iOS Auto layout issue when hiding tabBar in new ViewController - ios

I have a view hierarchy like this
TabBarController -> NavigationController -> TableViewController
When I tap the button want to push new VC without tabBar, as you can see on the GIF tabBar is hiding properly but the elements on screen aren't placed correctly when VC is pushed and it takes about half a second for it to adjust properly. Why is that?
In my TableViewController I have
#IBAction func presentPlayerPressed() {
performSegue(withIdentifier: "player", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? PlayerViewController {
destination.hidesBottomBarWhenPushed = true
}
}
But I also tried setting hides bottom bar on push in Storyboard and it gives the same effect
Also this doesn't change anything
#IBAction func presentPlayerPressed() {
let vc = storyboard!.instantiateViewController(withIdentifier: "playerVC")
vc.hidesBottomBarWhenPushed = true
navigationController?.pushViewController(vc, animated: true)
}

Related

Swift Navigation bar not appearing when storyboard is referenced after login

When I launch a build for the application the login and signup work just fine but when it transfers to the HomeVC storyboard it appears empty. To make sure that it is referenced correctly I put labels on it and those were appearing during builds what just really remains invisible is the navigation bar. Pls help :)
How the HomeVC storyboard is referenced in Login and Signup
Login:
else {
let homeViewController = self.storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
self.view.window?.rootViewController = homeViewController
self.view.window?.makeKeyAndVisible()
SignUp:
func transitionToHome(){
let homeViewController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
Here is the login storyboard
The navigation bar is clearly apparent in the storyboards
You could try to use a segue
// This is used to perform the segue with the approporiate identifier
self.performSegue(withIdentifier: "Your unique identifer of the seugue", sender: self)
// Prepare for segue is used if you want to modify some properities in the desintation viewcontroller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Your identifier of the segue" {
// This is used to fetch the destination and cast it to pass over the values
if let dc = segue.destination as? YourClassOfTheDestination {
// Here can you type into dc and pass over the values
//Example
dc.curentFruit = "Pear"
}
}
}
Here is an image on how to specify the custom identifier of the segue in the storyboard. Here is the image
If you don't want the navigation bar to be visible in certain screens you can simply use:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isHidden = false
}
Remember to make it visible again when the view disappears.
Great question, hope the answer helps!
I believe the issue is you are making the view controller the key window and you are not adding the navigation controller. Try making the home view controller's navigation controller the key window.

How to navigate from one controller to another View Controller programmatically in Swift?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "GMNewPostControllerSegueIdentifier"
{
let svc = segue.destination as? UINavigationController
let vc: GMNewPostController = svc?.topViewController as! GMNewPostController
}
}
#IBAction func newPostButtonAction(_ sender: UIButton) {
performSegue(withIdentifier: "GMNewPostController", sender: self)
}
I don't like to drag and drop from my storyboard because I have a table view in vc2.
You have many options to do this:
Using Push:
let viewController = storyboard?.instantiateViewController(withIdentifier: "viewStoryID")
self.navigationController?.pushViewController(viewController, animated: true)
You have to set ViewController ID in storyBoard like this:
Check below image , storyboard should like this
And take a reference Action for button and write like this
For button Action
Refer to the Image here
look at the picture, I want to navigate from green btn to the viewcontroller ..?

How to pass data from ViewController to a ViewController in a tab bar iOS?

I'm trying to pass data from my main ViewController to another ViewController in a Tab Bar.
I have tried using the following code , and got an error Could not cast value of type 'Test.FirstViewController' to 'Test.ViewController'
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
let tab1Controller = self.tabBarController?.viewControllers?.first as! ViewController
print(tab1Controller.test)
}
I just used the following code which just worked fine for me on Xcode 9 with swift 4.0. The following method is declared in the View Controller class which just presents the First View Controller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "sendingToTabBar" {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabVC = storyboard.instantiateViewController(withIdentifier: "tabVC") as! UITabBarController
self.present(tabVC, animated: true, completion: {
let vc = tabVC.selectedViewController as! FirstViewController
vc.dataLBL.text = self.dataTF.text!
})
}
}
You can access the tab bar controllers in your ViewController prepare method and set your values.
Prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let barViewControllers = segue.destination as! UITabBarController
let destinationViewController = barViewControllers.viewControllers?[0] as! FirstViewController
destinationViewController.test = "Hello TabBar 1"
// access the second tab bar
let secondDes = barViewControllers.viewControllers?[1] as! SecondViewController
secondDes.test = "Hello TabBar 2"
}
Then in your tab bar ViewControllers declare variables, you want to set the values to.
#IBOutlet weak var label: UILabel!
var test: String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
label.text = test
}
FirstViewController
SecondViewController
You could do a number of things, what I would do is to just make a global variable so that both view controllers can access it. Another option is to give each view controller a separate global variable, and when the view is loaded, the variable is set to self, then make a variable that can be set by the other view controller.
example:
var data:Any?
viewDidLoad() {
viewControllerA = self
}

Trouble with back button

I have strange trouble with my back button. I have 2 VC. Every VC has its own back button (they're not default, they are added as Left Bar Button Items. When I coming from VC1 (linked with Home View Controller, not shown) to VC2 I see VC2 but when I'm coming back to VC1 I see Navigation bar of VC1 and view of VC2. What Do I need to do to?
I also tried to add func but it hadn't helped.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "comeBack" {
let backVC = self.storyboard?.instantiateViewController(withIdentifier: "CollectionVC") as! RecipeCollectionViewController
self.navigationController?.pushViewController(backVC, animated: true)
}
}
use this for push VC1 TO VC2
let vc = self.storyboard?.instantiateViewControllerWithIdentifier("VC2") as! VC2
self.navigationController?.pushViewController(vc, animated: true)
and use this for back from VC2 TO VC1
self.navigationController?.popViewControllerAnimated(true)
For pop specific view controller
let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for vc in viewControllers {
if VC is YourViewController {
self.navigationController!.popToViewController(vc, animated: true)
}
}
If Pop previous controller than use
self.navigationController?.popViewControllerAnimated(true)

why is my view all black after initiating a simple "performSegueWithIdentifier"?

I'm just attempting to initiate a simple segue programmatically, but for some reason, when I do so, the destination view is just all black, and when I go back via the navigation controller, it turns the rest of my views black as well. Here is the segue in my IB:
And this the code for the segue, through a button in the master controller:
#IBAction func buttonPressed(sender: AnyObject) {
self.performSegueWithIdentifier("showLoading", sender: self)
}
however when I run the app and press the button, the segue works but the view is just black:
and every view previous is black as well.. but i have notices every time i switch back and forth between the tabs, the views are regular and not this black screen. Why is this unusual behavior occurring?
Once I disable the sizeclass of my storyboard.
Change one of popover segue to push segue.
Then I enable the sizeclass,this segue is the same as yours in storyboard ,so is the problem .
After I change this segue back to popover segue, everything works fine again.
This is how I fix this problem ,but I don't know why.
And the following is my code in presentedviewcontroller:
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == Constants.EditWaypointSegue {
if let waypoint = (sender as? MKAnnotationView)?.annotation as? EditableWaypoint {
if let ewvc = segue.destinationViewController.contentViewController as? EditWaypointViewController {
if let ppc = ewvc.popoverPresentationController {
let coordinatePoint = mapView.convertCoordinate(waypoint.coordinate, toPointToView: mapView)
ppc.sourceRect = (sender as! MKAnnotationView).popoverSourceRectForCoordinatePoint(coordinatePoint)
let minimumSize = ewvc.view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
ewvc.preferredContentSize = CGSize(width: Constants.EditWaypointPopoverWidth, height: minimumSize.height)
ppc.delegate = self
}
ewvc.waypointToEdit = waypoint
}
}
}
}
// MARK: - UIAdaptivePresentationControllerDelegate
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
println("full")
return UIModalPresentationStyle.FullScreen // full screen, but we can see what's underneath
}
func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController?
{
let navcon = UINavigationController(rootViewController: controller.presentedViewController)
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .ExtraLight))
visualEffectView.frame = navcon.view.bounds
navcon.view.insertSubview(visualEffectView, atIndex: 0) // "back-most" subview
return navcon
}

Resources