I have an action tied to pop up the MPC view controller however once this action is complected and the browser is dismissed I simply am lead back to my old view controller
func browserViewControllerDidFinish(
browserViewController: MCBrowserViewController!) {
// Called when the browser view controller is dismissed (ie the Done
// button was tapped)
func seguetoJoin(segue: UIStoryboardSegue, sender: AnyObject?) {
var joinView: playMusicViewController = segue.destinationViewController as! playMusicViewController
weak var delegate: MCBrowserViewControllerDelegate!
}
self.dismissViewControllerAnimated(true, completion: nil)
}
You seem to be calling dismissViewController on the VC that is receiving the didFinish callback.
You should move the segue code to the ViewController that needs to perform the segue, rather than performing it on a ViewController that is being dismissed.
Also, these are unused
var joinView: playMusicViewController = segue.destinationViewController as! playMusicViewController
weak var delegate: MCBrowserViewControllerDelegate!
Update -
Following the comments below.
in mpcSubClass.m
var viewControllerToPeformSegue: UIViewController!
func browserViewControllerDidFinish(browserViewController: MCBrowserViewController!) {
// animation:false as your segue will have an animation
self.dismissViewControllerAnimated(false, completion: nil)
self.viewControllerToPerformSegue.handleBrowserDidFinish()
}
in viewControllerToPerformSegue.m
// when you initialise the MPC VC subclass
mpcVCSubclass.viewControllerToPerformSegue = self
func handleBrowserDidFinish()
{
self.performSegueWithIdentifier("mainViewSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!)
{
if segue.identifier == "mainViewSegue"
{
let mainVC = segue.destination as! MainVC
// now pass any data to your main VC that it can load in viewWillAppear
}
}
in storyboard
link viewControllerToPerformSegue to the MainVC and name the segue mainViewSegue
Hope this helps.
Related
I have a parent UIViewController(MainVC). From there I have 2 segue to 2 UIViewControllers: FirstVC (identifier: goFirstVC) and SecondVC (identifier: goSecondVC)
In FirstVC I have a button Save and when I click it I want to dismiss the FirstVC and to go on SecondVC.
Here is my code:
#IBAction func saveBtnTapped(_ sender: UIButton) {
//navigationController?.popViewController(animated: true)
let destinationController = self.storyboard?.instantiateViewController(withIdentifier: "goSecondVC") as! SecondVC
let presentingVC = self.presentingViewController
self.dismiss(animated: false, completion: { () -> Void in
presentingVC!.present(destinationController, animated: true, completion: nil)
})
}
Here is the design for my issue:
You can use setViewControllers to keep the parent only and the SecondVC
let destinationController = self.storyboard?.instantiateViewController(withIdentifier: "goSecondVC") as! SecondVC
self.navigationController?.setViewControllers([self.navigationController!.viewControllers.first!,destinationController], animated: true)
There are many methods but one of the generic one is to use delegates and protocols. Use the following code in your classes.
Add Following code in the first VC
protocol SecondVCDelegate : AnyObject {
func goToSecondVC()
}
class FirstVC: UIViewController {
var Delegate : SecondVCDelegate!
#objc func save() {
Delegate.goToSecondVC()
}
}
//In second view
Add following code in MinVC
class MainVC: UIViewController {
override func viewDidAppear() {
self.performSegue(withIdentifier: <yourSegueIdentifierToFirstVC>, sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == <yourSegueIdentifierToFirstVC> {
let cont = segue.destination as! FirstVC
cont.Delegate = self
}
}
}
extension MainVC : SecondVCDelegate {
func goToSecondVC() {
self.performSegue(withIdentifier: <yourSegueIdentifierToSecondVC>, sender: nil)
}
}
//This is MainVC
I think you should present second from first rather than dismissing first then presenting second.
when you will present second from first then if you wanto go back to main you can simply dismiss 2 veiwcontrollers at once without any hack.
try it:
We can control our presented controllers with navigation controller calling pushViewController and popViewController methods.
FirstVC.navigationController?.popViewController(animated: animated) // pops the top view controller
self.navigationController?.pushViewController(SecondVC, animated: true) // Pushes a view controller onto navigation's stack of controllers
In your case:
let destinationController = self.storyboard?.instantiateViewController(withIdentifier: "goSecondVC") as? SecondVC
self.navigationController?.popViewController(animated: animated)
self.navigationController?.pushViewController(destinationController, animated: true)
I used this code here to pass data from first view controller to the second view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? secondViewController {
vc.showPageType = self.checkEdit
}
But the problem is that in the second view controller I have text field that when user fill that text field and push the button submit the secondViewController will be dismiss with this method
dismiss(animated: false, completion: nil)
and now I can't use perform segue method to pass textfield text to the first view controller how can I do that in swift4?
Add to your secondViewController source code file:
protocol SecondViewControllerDelegate {
func submitButtonPushedWithText(_ text: String)
}
Add to class secondViewController property:
var delegate: SecondViewControllerDelegate?
Then conform your first controller to SecondViewControllerDelegate and implement method submitButtonPushedWithText(:):
class FirstViewController: UIViewController, SecondViewControllerDelegate {
func submitButtonPushedWithText(_ text: String) {
// use text from textField of second controller
}
}
Also setup delegate property of second controller before presenting:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? secondViewController {
vc.showPageType = self.checkEdit
// setup delegate
vc.delegate = self
}
Now you can call method submitButtonPushedWithText(_ text: String) in your Second controller just before calling dismiss(animated: false, completion: nil):
func submitButtonPushed() {
delegate?.submitButtonPushedWithText(textField.text!)
dismiss(animated: false, completion: nil)
}
I tried many methods to send data from my popup view controller to main view controller. but failed. can anybody help me with this.
i am using a "present as popover" segue. i want to the text entered in textfield of popover view as the label text of main view.
From Popup View, Data send to Main ViewController using protocol in Swift 3.
enter image description here
Complete Details are given below...
1. View Controller Implementing with Protocol named sendDataToViewProtocol.
import UIKit
class ViewController: UIViewController,sendDataToViewProtocol {
#IBOutlet weak var lshowDataLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnShowPopUpDialog(_ sender: Any) {
let popUpVc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PopupVIewController") as! PopupVIewController
//Don't forget initialize protocal deletage
popUpVc.delegate = self
self.addChildViewController(popUpVc)
popUpVc.view.frame = self.view.frame
self.view.addSubview(popUpVc.view)
popUpVc.didMove(toParentViewController: self)
}
func inputData(data: String) {
lshowDataLabel.text = data
}
}
Popup View Controller With Protocol named sendDataToViewProtocol below.
3.protocol declare outside the PopupVIewController.
Don't forget to assign ViewController to PopupVIewController .
In viewController withIdentifier: "PopupVIewController" , "PopupVIewController" is PopupVIewController storyborad Id.
Please see the attached image.
import UIKit
protocol sendDataToViewProtocol {
func inputData(data:String)
}
class PopupVIewController: UIViewController {
//Protocol object
var delegate:sendDataToViewProtocol? = nil
#IBOutlet weak var txtInputFieldText: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor
.black.withAlphaComponent(0.8)
}
#IBAction func btnSendDataToViewController(_ sender: Any) {
//"Check Delegate nil"
if(delegate != nil){
//Check textField is empty
if(txtInputFieldText.text != ""){
//set textField Data to protocol Function
delegate?.inputData(data: txtInputFieldText.text!)
self.view.removeFromSuperview()
}
}
}
#IBAction func btnClose(_ sender: Any) {
self.view.removeFromSuperview()
}
}
First of all, keep a temporary variable in your Main ViewController. Let's call it:
var somethingCool: String?
Then, in your popup ViewController code, assuming you have your segue trigger there, you will need to add in a new method.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "your_segue_identifier" {
if let vc = segue.destination as? MainViewController {
vc.somethingCool = "whatever_you_want"
}
}
}
How can I pass data back from a PopoverViewController to the main view controller on an iPhone?
I know I'm doing something terribly wrong but I cannot figure it out.
Here is the code:
PopoverViewController.swift
protocol PopoverViewControllerDelegate {
func messageData(data: AnyObject)
}
class PopoverViewController: UIViewController {
#IBOutlet weak var inputMessage: UITextField!
var delegate: PopoverViewControllerDelegate?
#IBAction func sendData(sender: AnyObject) {
if inputMessage.text != ""{
self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
self.delegate?.messageData(inputMessage.text!)
}
}
}
Main ViewController.swift:
class ViewController: UIViewController, UIPopoverPresentationControllerDelegate, PopoverViewControllerDelegate {
#IBOutlet weak var showData: UILabel!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// popover segue
if segue.identifier == "popoverSegue" {
let popoverViewController = segue.destinationViewController
popoverViewController.popoverPresentationController!.delegate = self
}
// code to comunicate with data in popoverViewController
let pvc = storyboard?.instantiateViewControllerWithIdentifier("popoverViewController") as! PopoverViewController
pvc.delegate = self
self.presentViewController(pvc, animated:false, completion:nil)
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.None
}
func messageData(data: AnyObject) {
self.showData.text = "\(data)"
}
}
With the code above I can pass data back to the main view controller without a problem, the issue is that the popover doesn't work, it just acts like a regular ViewController occupying the whole screen.
The funny thing is that if I comment the following line of code the popover works but I can no longer pass data back, I can see the popover but the passing data stops working.
// if I comment this line
self.presentViewController(pvc, animated:false, completion:nil)
I don't get any errors, one just stops working.
Any suggestions?
Thanks a lot
In prepareForSegue, the destinationViewController is your PopoverViewController. You need to cast it to that and set the delegate on that so that you can pass back data, and you need to set the popoverPesentationController?.delegate as well. You don't need the rest of the code in prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// popover segue
if segue.identifier == "popoverSegue" {
let popoverViewController = segue.destinationViewController as! PopoverViewController
popoverViewController.delegate = self
popoverViewController.popoverPresentationController?.delegate = self
}
}
I want to pass data (e.g. set var) from modal segue to parent, how can I do that?
I’m using that code to exit from modal segue:
#IBAction func doneClicked(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
I can’t use segue.destinationViewController here to pass data as i’m used to do on push segues.
Create protocol on Modal ViewController
protocol ModalViewControllerDelegate
{
func sendValue(var value : NSString)
}
Also declare in you Modal ViewController class
var delegate:ModalViewControllerDelegate!
Include this protocol ModalViewControllerDelegate in ParentViewController
When you are Moving form one viewController to another
modalVC.delegate=self;
self.presentViewController(modalVC, animated: true, completion: nil)
Here you get your value in ParentViewcontroller
func sendValue(value: NSString) {
}
Finally on ModalViewController
#IBAction func doneClicked(sender: AnyObject) {
delegate?.sendValue("value")
self.dismissViewControllerAnimated(true, completion: nil)
}
In the second viewController (the one showed by the segue) declare a variable like
var parentVC : UIViewController?
then when you call segue from parent
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "yourSegue" {
let secondController= segue.destinationViewController as UIViewController
secondController.parentVC = self
}
}
so you can use
#IBAction func doneClicked(sender: AnyObject) {
self.parentVC.yourVariable = 0
self.dismissViewControllerAnimated(true, completion: nil)
}