How to call another controller on long press of UITableViewCell in swift? - ios

I am using the below code to display MyEditViewController but all the field outlets in MyEditViewController are nil because of this line let editController = MyEditViewController(). Here I am creating new instance. So outlets are nil now. Is there any other way to call the edit controller without creating instance of it?
#IBAction func editMethod(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Began {
let cell = sender.view as! MyTableViewCell
let editController = MyEditViewController()
editController.sample= samples[cell.tag]
presentViewController(editController, animated: true, completion: nil)
}
}

To instantiate a new controller with your outlets you can use a xib
let editController = MyEditViewController(nibName: "MyEditViewController", bundle: nil)
Or you can attribute a StoryboardId to your controller and use with instantiateViewControllerWithIdentifier
let editController = storyboard?.instantiateViewControllerWithIdentifier("MyEditViewControllerStoryboardId") as! MyEditViewController
Or as a suggestion for your case, you can use a different approach using storyboard segues. Read more about it here
performSegueWithIdentifier("PresentMyEditController", sender: self)

You should initiate not a Class, you shoud initiate it as an ViewController from Storyboard. So in your case set an "Storyboard-ID" for your Controller.
And then use:
let editController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("StoryboardID") as! MyEditViewController
So all outlets should work fine.

Related

How can i pop back from storyboard of framework?

let storyboardBundle = Bundle(identifier: "SignUPFramework")
let vc = UIStoryboard.init(name: "SignIn", bundle: storyboardBundle).instantiateViewController(withIdentifier: "SignInViewcontroller") as! SignInViewcontroller
navigationController?.pushViewController(vc, animated: true)
I have navigated to storyboard of framework as above.
You own the navigationController. So you can use either popViewController(animated:) (if you are sure that there is only one view controller you wish to pop), or popToViewController(_:animated:), or popToRootViewController(animated:) (if you wish to return to the root).
It does not matter that the storyboard is in a framework. You still own the view hierarchy, the navigation stack and the view controller instance you get from the below line of code
let vc = UIStoryboard.init(name: "SignIn", bundle: storyboardBundle).instantiateViewController(withIdentifier: "SignInViewcontroller") as! SignInViewcontroller
So you can do whatever you want with it in terms of navigation (push it and pop it or present it and dismiss it).
You just need to identify at what point you want to trigger any of these actions.
I think you are using xib so it will not return action first you should do protocol for callback to view controller then you can use popViewController(animated:).
protocol CallBackDelegate: AnyObject {
func back()
}
//Delegate
weak var delegate:CallBackDelegate?
#IBAction func buttonAction(_ sender: Any) {
delegate?.back()
}
Now you can use protocol in view controller
class ViewController: UIViewController, CallBackDelegate {
func back() {
navigationController?.popViewController(animated: true)
}
}
Note :- Confirm delegate variable in cellForRowAtIndexPath i.e.
cell.delegate = self
I have solved it by
let bundle = Bundle(for: SignInViewcontroller.self)
let vc = UIStoryboard.init(name: "SignIn", bundle: bundle).instantiateViewController(withIdentifier: "SignInViewcontroller") as! SignInViewcontroller
in above snippet instead of passing bundle id i have passed viewcontroller itself.

Navigating One View Controller to Another using Swift 5 doesn't work

Okay guys, now that I have fixed this because of your help,
the error has gone.
but the page won't move to the 'requirementVC', so the button when i clicked, it just doesn't do anything.
#IBAction func buttonOK(_ sender: Any) {
let button = (self.storyboard?.instantiateViewController(withIdentifier: "RequirementsVC") as! requirementVC)
self.navigationController?.show(button, sender: nil)
}
Thankyou again, appriciate it!
You can do the following...
#IBAction func buttonOK(_ sender: Any) {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RequirementsVC") as! requirementsVC
self.navigationController?.pushViewController(vc, animated: true)
}
Here Main is the name of the storyboard.
RequirementsVC should be storyboard id set in storyboard.
And requirementsVC should be the subclass of the UIViewController.
//Class name should always start with capital letter. So rename requirementsVC to "RequirementsVC"
class RequirementsVC: UIViewController {
//class body
}
just set your identifier and class of viewController you want to go on in this code :=
let addReminderVc = self.storyboard?.instantiateViewController(withIdentifier: "AddReminderVC") as! AddReminderVC
self.navigationController?.pushViewController(addReminderVc, animated: true)

Loading a ViewController from nib file owner

I have a design made in nib and in round about all ViewControllers I am loading that nib design.
Now as that was common footer so I managed to used it in the footer of all other view controllers.
Now what I want : I want that whenever User click on a footer it must start a new View Controller that will show what you can say "About us " view controller.
What I am doing:
// ON CLICK OF FOOTER I AM DOING
let mAboutUs = self.storyboard?.instantiateViewController(withIdentifier: "idAboutUs") as! AboutUs
mAboutUs.modalPresentationStyle = .fullScreen
self.present(mAboutUs, animated: true) {
}
but I am getting following error
Value of type 'FooterView' has no member 'storyboard'
My Understanding: I think from nib file we can not start a new ViewController, But I really do not want to do this thing in all other View controllers in which I added this nib (FooterView) as my footer view at bottom of each view controller.
Please help me!!!!
A UIView subclass doesn't contain a storyboard property it's for a vc subclass , You need
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "idAboutUs") as! AboutUs
if you want to present a vc from inisde the view FooterView then add a delegate like
weak var delegate:VCName?
When you create an instance
let ins = FooterView() // or from storyboard
ins.delegate = self
Then use
delegate?.present(mAboutUs, animated: true)
inside the view's class
You can use a delegate that all vcs conforms to but the easiest is to add this extension
extension UIViewController {
func topMostViewController() -> UIViewController {
if let presented = self.presentedViewController {
return presented.topMostViewController()
}
if let navigation = self as? UINavigationController {
return navigation.visibleViewController?.topMostViewController() ?? navigation
}
if let tab = self as? UITabBarController {
return tab.selectedViewController?.topMostViewController() ?? tab
}
return self
}
}
Then
guard let currentVC = (UIApplication.shared.delegate as! AppDelegate).window?.rootViewController.topMostViewController() else { return }
currentVC.present(mAboutUs, animated: true)
Your code should look similar to this:
let vc = UIStoryboard(name: "<Name of the storyboard that contains the About Us VC>", bundle: nil).instantiateViewController(withIdentifier: "idAboutUs") as! AboutUs
self.present(vc, animated: true) {
}

How do i pass a json response from one view controller to another view controller in a different storyboard

How do I pass the json response I received from api to another viewcontroller in a different storyboard ?
I tried using segues but doesn't seem to work
let propass = UIStoryboard(name: "ProfileStoryboard", bundle: Bundle.main).instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
propass.proDict2 = parseJSON2
Try to add:
self.present(propass, animated: true, completion: nil)
after:
propass.proDict2 = parseJSON2
If you set up segues through the storyboard, then it makes sense that it didn't work through the segue when you tried the code above. The issue is that when when you set up a storyboard segue, the App deals with creating a new VC and presenting/showing it from your original VC.
What you are doing in your code, is that you are instantiating a new version of the same view controller, which is not the one being shown/presented.
You have 2 ways to implement this, firstly it is by overriding prepareForSegue in the ViewController that shows/presents your propass View Controller:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "YOUR SEGUE IDENTIFIER FROM THE STORYBOARD" {
let propassVC = segue.destination as! ProfileViewController
propassVC.proDict = parseJSON2
}
}
Another way to implement this, is to remove the segue you set up in the storyboard. Then you do as you are doing to initialize the Propass VC and to pass data to it.
let propassStoryboard = UIStoryboard(name: "Main", bundle: nil)
let propassVC = propassStoryboard.instantiateViewController(withIdentifier: "PROPASS IDENTIFIER SET IN STORYBOARD") as ProfileViewController
propassVC.jsonDict = JSONParse2
show(propassVC, sender: nil)

Push another Viewcontroller from action button in xib file

I have a viewcontroller that presents from a .xib.
Inside the .xib there is a button; I want the button to pushviewcontroller to an other viewcontroller (ViewControllerPeopleNew).
I use an action button:
#IBAction func _hitPeople(sender: AnyObject) {
let mapViewControllerObejct = self.storyboard?.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
But got an error:
Signal SIGABRT
unrecognized selector sent to instance
I already checked all about name identifier viewcontroller and all is right.
From view controller present with XIB you can not get storyboad use below code
#IBAction func _hitPeople(sender: AnyObject) {
let storyboard = UIStoryboard(name: "storyboadname", bundle: nil)
let mapViewControllerObejct = storyboard.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
Always remember that you can only use self.storyBoard to instantiate a view controller when both the view controllers (To and From view controllers) belong to the same storyboard. If not then you need to first get a reference to the storyboard your To view controller belongs to. So you need to do this:
#IBAction func _hitPeople(sender: AnyObject) {
let stotyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let mapViewControllerObejct = storyboard?.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
PS: Just be sure that your From view controller is in the navigation stack i.e. self.navigationController is not nil.

Resources