Swift 3 Pass variable to PopupViewController - ios

I am presenting my viewController like so using accessoryButtonTappedForRowWith:
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let popoverContent = storyboard.instantiateViewController(withIdentifier: "Test")
popoverContent.modalPresentationStyle = .popover
if let popover = popoverContent.popoverPresentationController {
let viewForSource = self.createCharacterView as UIView
popover.sourceView = viewForSource
// the position of the popover where it's showed
popover.sourceRect = viewForSource.bounds
// the size you want to display
popoverContent.preferredContentSize = CGSize(width: 200,height: 200)
popover.delegate = self
}
self.present(popoverContent, animated: true, completion: nil)
The pop up works and looks fine it's just that the viewController that I am presenting needs to the label of the tableViewCell. I am able to get the variable, but I'm unsure how to pass the variable to the popover since a segue isn't called I don't think I am able to use prepare(for segue: UIStoryboardSegue, sender: Any?).

It was too simple:
popoverContent.variableName = passingVariable

You might need to cast you popOvercontent to you specific viewController
(popoverContent as? MyViewController).myVar = value

Related

Could not cast value of type UINavigationController not navigating in the Main Storyboard

I know there are lots of similar posts but none answered my situation. All of the posts I’ve seen only deal with the Main storyboard. I’m navigating to a different storyboard called Date_Popup which has a VC embedded in a NC. The thing is that this code works on iPhone so I know the segue.identifier, Storyboard ID and the VC ID are correct. Also, I’m using this same code in 7 of my older apps and it works fine there. I’m frustrated that it works there and not in this new app. I’m not sure if this is an Xcode problem or what. I left the commented out code so readers know I’ve tried it both ways. If I comment out the line that throws the error the code execute but then the preferredContentSize doesn't get set.
Thanks for any help.
This is where I get the error.
popupVC = segue.destination as! Date_Popover_VC
Her's my code.
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == K.Segue.to_Date_Popover
{
var popupVC = UIStoryboard(name: K.StoryboardID.date_Popup_SB, bundle: nil).instantiateViewController(identifier: K.StoryboardID.date_Popover_VC) as! Date_Popover_VC
let navigationController = UINavigationController(rootViewController: popupVC)
// let storyboard : UIStoryboard = UIStoryboard(name: K.StoryboardID.date_Popup_SB, bundle: nil)
// var popupVC: Date_Popover_VC = storyboard.instantiateViewController(withIdentifier: K.StoryboardID.date_Popover_VC) as! Date_Popover_VC
// let navigationController = UINavigationController(rootViewController: popupVC)
let deviceName = UIDevice().type
let deviceString: String = ("\(deviceName)")
if deviceString.contains(K.theDevice.iPad)
{
popupVC = segue.destination as! Date_Popover_VC
if ModelData.isInline()
{
popupVC.preferredContentSize = CGSize(width: 320, height: 300)
} else {
popupVC.preferredContentSize = CGSize(width: 350, height: 410)
}
navigationController.isNavigationBarHidden = true
} else if deviceString.contains(K.theDevice.iPhone) {
present(navigationController, animated: true, completion: nil)
navigationController.isNavigationBarHidden = false
}
popupVC.theDate = dateFld_Outlet.text!
popupVC.dateDelegate = self
}
}
I finally figured out where I want wrong. On the main storyboard where the storyboard reference to the date popover is linked to the segue. The storyboard needs to be the name of the storyboard and the Referenced ID needs to be the name of the VC on that storyboard. The storyboard is chosen from a drop-down menu. The Referenced ID needs to be entered. It actually has nothing to do with a UINavigationController so the error verbiage is a bit misleading.

PopoverPresentationController coming as nil

Created a SingleViewApplication in that I have placed a button.
Now clicking on button I need to display a tableView as popover.
The TableViewController is created in xib.
The issue is tableViewController.popoverPresentationController always comes as nil see below code
let filterVC = TableViewController(nibName: "TableViewController", bundle: nil)
var filterDistanceViewController = UINavigationController(rootViewController: filterVC)
filterDistanceViewController.preferredContentSize = CGSize(width: 300, height: 200)
let popoverPresentationViewController = filterDistanceViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .any
if let pop = filterDistanceViewController.popoverPresentationController {
pop.delegate = self
}
in above code
filterDistanceViewController.popoverPresentationController is always coming as nil
Any hint in right direction will be highly appreciated.
Until you've set a modalPresentationStyle on your VC, the popoverPresentationController property will be nil. Ensure that you set the modalPresentationStyle before accessing.
You are not presenting anything, so you need to present the popoverPresentationViewController on the current viewcontroller, for example:
#IBAction func importantButtonPressed(_ sender: UIButton) {
let tableViewController = UITableViewController()
tableViewController.modalPresentationStyle = .popover
present(tableViewController, animated: true, completion: nil)
if let pop = tableViewController.popoverPresentationController {
pop.delegate = self
}
}
You may do like below.
#IBAction func popoverBtnPressed(_ sender: Any) {
let vc2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController2")
vc2.modalPresentationStyle = .popover
vc2.popoverPresentationController?.delegate = self
vc2.popoverPresentationController?.barButtonItem = popoverBtn
vc2.popoverPresentationController?.sourceRect = .zero
present(vc2, animated: true, completion: nil)
}

My show segue not using NavigationController

I am having problems segueing to my detail view, using Navigation Controller.
I was using a tableview, to display some exercises, and when you clicked the exercise you would seque into the detail view, embedded in nav controller
I have removed the Tableview, and added 3 buttons, each with its' own "show" segue to the detail view. It almost works, but it is now not using my Navigation controller, meaning that the view is just presented kind of like a modal presentation.
I have tried removing the segue on one button and replace with this action:
#IBAction func strengthButton(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destination = storyboard.instantiateViewController(withIdentifier: "ExerciseViewController") as! ExerciseViewController
destination.componentaccessid = -1;
destination.openedFromUrl = false;
destination.exercise = self.strengthexercise
destination.exercisetype = .strength
self.navigationController?.present(destination, animated: true, completion: nil)
}
But that does exactly the same.
I have a prepare function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier,
let destination = segue.destination as? ExerciseViewController{
destination.componentaccessid = -1;
destination.openedFromUrl = false;
switch identifier{
case "strengthsegue":
destination.exercise = self.strengthexercise
destination.exercisetype = .strength
case "rangesegue":
destination.exercise = self.rangeexercise
destination.exercisetype = .range
case "combinedsegue":
destination.exercise = self.combinedexercise
destination.exercisetype = .combined
default:
print("Nothing")
}
}
}
Try this
self.navigationController?.pushViewController(destination, animated: true)
In your code you are using,
self.navigationController?.present(destination, animated: true, completion: nil)
This will only present the UIViewController.
Instead use,
self.navigationController?.pushViewController(destination, animated: true)
to push the viewController in which the NavigationController is inherited.

Present small viewController

Problem State: I've two viewController
parentViewController (375 * 667)
childViewController (300 * 667)
and i want to present childViewController at Axis (75 * 0) as shown below
childViewController is show on this IBAction
#IBAction func btnShowVC(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let newVC = storyboard.instantiateViewController(withIdentifier: "cvc") as? childViewController
self.present(newVC!, animated: true, completion: nil)
}
But it stretches itself like
can anyOne help me to tackle it?
Thanks
You can try in this way.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let newVC = storyboard.instantiateViewController(withIdentifier: "ChildViewController") as? ChildViewController
view.addSubview((newVC?.view)!)
newVC?.view.frame = CGRect(x:75,y:0,width:view.frame.size.width-75,height:view.frame.size.height)
newVC?.view.autoresizingMask = \[.flexibleWidth, .flexibleHeight\]
newVC?.didMove(toParentViewController: self)
Where are you setting the frame of your ViewController? If you are using autolayout you will need to set constraints to make the ViewController look how you want it to. If you want to do it programatically you can set the frame somewhere for example in the code that you posted above you could do this:
#IBAction func btnShowVC(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let newVC = storyboard.instantiateViewController(withIdentifier: "cvc") as? childViewController
newVc.view.frame = CGRect(x: 75, y: 0, width: 300, height: 667)
self.present(newVC!, animated: true, completion: nil)
}
By setting preferredContentSize property will solve your problem, Please try out below code snippet
newVC?.preferredContentSize = CGSize(width: 300, height: 667)

Can't push because self.navigationController is nil

I'm presenting a Navigation Controller as a popover. First time a do it I can push to another View Controller with any issue. But, second time a present another controller the same way I can't perform a push because the self.navigationController of the presented Controller is nil. This is the piece of code I'm using to present the Controller
func instantiateEditController(view : UIView) -> UINavigationController
{
let popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("Edit Controller") as MCMEditController
popoverContent.preferredContentSize = CGSizeMake(320, 480)
let navController = MCMBaseNavigationController(rootViewController: popoverContent)
navController.modalPresentationStyle = UIModalPresentationStyle.Popover
navController.navigationBar.tintColor = UIColor.whiteColor()
let popover = navController.popoverPresentationController
popover?.sourceView = view
popover?.sourceRect = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)
return navController
}
Note: The Navigation Controller is always presented, but just the first time I perform pushes. And this code is for be used in iPad.
Because of the nature of Storyboards and not being able to show that here, I'm not sure where your issue is exactly.
However I successfully setup a project that works using segues. I changed your code to the following:
func instantiateEditController(view : UIView) -> UINavigationController
{
if let popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("Edit Controller") as? MCMEditController {
popoverContent.preferredContentSize = CGSizeMake(320, 480)
let navController = UINavigationController(rootViewController: popoverContent)
navController.modalPresentationStyle = UIModalPresentationStyle.Popover
navController.navigationBar.tintColor = UIColor.whiteColor()
let popover = navController.popoverPresentationController
popover?.sourceView = view
popover?.sourceRect = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height)
return navController
} else {
return UINavigationController(rootViewController: self) // not recommend to keep this, I'm on Swift 1.2 and this was an easy fix to resolve the errors
}
}
To present this popover I set up this IBAction in my ViewController (sender in my case was a UIButton)
#IBAction func presentPopover(sender: AnyObject) {
if let view = sender as? UIView {
let controller = instantiateEditController(view)
let popover = UIPopoverController(contentViewController: controller)
popover.presentPopoverFromRect(view.frame, inView: self.view, permittedArrowDirections:UIPopoverArrowDirection.Any, animated: true)
}
}
The last thing that could be the issue is make sure your segues are using the segue type "show" for all the segues to make sure the transition between them use the navigation controller push:
Hope this helps!

Resources