I have a UIPageViewController subclass that displays 1 view controller at a time. The displayed view controller has a scrollview. This allows the user to scroll left/right to go to a new page, or up down to view content larger than the screen's height. The UIPageViewController subclass is embedded within a UINavigationController, and the navBar's toolbar is visible.
This UIPageViewController subclass can be accessed from two different parts of my app.
In my first viewController, the toolbar is hidden. Tapping on an element in this view controller loads the UIPageViewController, and everything looks fine.
In my second viewController, the toolbar is visible. Tapping on an element in this view controller loads the UIPageViewController, but my content (the pageViewController's viewController) is pushed down a bit from the navigation bar. As soon as I interact with the scrollView though, the view automatically adjusts to correctly sit right below the nav bar.
I am running this on iOS7, but I'm not sure if that has any relation.
Why is my view controller loading differently when coming from two different parts of the app, one with the toolbar showing, one with it hidden?
If your app works well on iOS6, but not on iOS7, try to set NO to UIPageViewController(UIPVC)'s automaticallyAdjustsScrollViewInsets property.
UIPVC seems to have a scrollview inside. On iOS7, UIViewController's automaticallyAdjustsScrollViewInsets property is set to YES in default. I think it doesn't work well if it is embedded in UINavigationController.
In my case, I created custom UIPVC and place the following code in [viewDidLoad] method.
self.automaticallyAdjustsScrollViewInsets = NO;
I was finally able to properly align an embedded UIPageViewController in a NavController, which itself is inside a TabBarcontroller. I did so by programmatically creating the pageViewController inside a dummy "rootviewcontroller", following the example given in the default Xcode "New Project" called "Page-based Application".
In my case, the following storyboard layout produce the error: TabBarController -> NavController -> UIPageViewController (scroll-horizontal) -> ContentViewController
I changed my storyboard layout to: TabBarController -> NavController -> CustomRootViewController
The CustomRootViewController instantiates a UIPageViewController and saves it as a member property. CustomRootViewController becomes the DataSource and Delegate for its PageViewController. Follow the default Xcode "New Project" called "Page-based Application" for an example of how to setup the RootViewController.
Unfortunately, this whole issue appears to be caused by a bug in Storyboard when you are using the drag-and-drop "UIPageViewController", with scroll-horizontal transition-type, embedded in a navController (and/or tabbarcontroller). FYI - In the pageViewController's viewWillAppear, I tried resetting the frame of the pageViewController and the contentViewControllers each to (0,0) with size matching the device, and yet the view of the pageViewController's initial viewController would always be shifted-down by what appeared to be the height of the tabbarcontroller in which it was embedded. Here are a few observations for those who wish to pursue this issue further:
In viewDidLoad, you can set the Frame of the pageViewController's initial view to offset the layout-error. But then you might have to deal with different layout-corrections for different devices in different orientations, and that could be a headache down the road.
In Storyboard, setting the pageViewController's transition style to "page curl" resolves the layout issue. So therefore I am certain that the layout issue resides in page-scroll, which is set upon instantiation. Instantiation by Storyboard will produce the layout error, but instantiation programmatically in my CustomRootViewController is error-free.
Related
I have an iOS app that was created using storyboards with auto-layout. The View Controllers are in a navigation controller. Several steps down the navigation controller chain I have a button in VC1 that is connected to VC2 via a popover segue. When I tap the button, a popover view appears but is blank. I changed the background color of VC2 to see if the view was actually appearing. It was. No subviews were visible. I have created and recreated VC2. I have changed the sizes of the view, the subviews and the view controller. I have manually and automatically created restraints. I also created a test view controller outside of the navigation view controller. It behaved the same as the view controllers in the navigation controller.
Just to check if I was completely incompetent, I created a new project with a storyboard that had one VC. I placed a button in this VC with a popover segue to a second VC. It worked as desired. When the button was pressed a popover would appear and all subviews of the second VC would be visible. I tried placing the first VC in a navigation controller with no change. It continued to show the popover as it should. I have compared the two projects and I can't find what the problem is.
My question is this: Does anyone out there know of some hidden setting that would cause this behavior? or Any suggestions on what I'm missing here?
Well, after a whole lot of time (and even rewriting my project from scratch) I finally found the solution. Apparently, using size classes messes with popovers. To solve this solution, I turned size classes off completely. My app is iPad only so that worked for me. According to this thread: iOS8 Size-Classes and Popover Views you can also use the Any/Any size class. I was using Regular/Regular size class. I hope this helps someone.
My application has a UIViewController which is embedded in a UINavigationController. The UIViewController has a container view inside it. I connect this container view to a UITableViewController thereby embedding it in the container view. It's fine until now.
Now when I connect this UITableViewController to a new UIViewController using the push segue (we are still in the navigation view) in the storyboard, the size of the new UIViewController scene becomes same as that of the container view. I guess this is expected but is there some way not to make this happen. I want the remaining scenes to be in the normal size. Also, its working pretty fine and as expected when running in the simulator. The problem with the size is only pertained to the storyboard.
Just explaining my controller - view hierarchy here:
UINavigationController
-> UIViewController ( Initial View Controller )
-> Container View
-> UITableViewController ( Embed Segue )
-> UIViewController ( Push Segue )
Is there any way so that the last UIViewController and the remaining connected controller scenes are of normal sizes in the storyboard?
Here is one solution: Create a manual segue from your Initial View Controller to the desired destination. This will prevent the storyboard from getting confused and giving the destination the wrong size (and other inferred metrics). Unfortunately, because it is a manual view controller, you will have to perform the segue in code from your embedded view controller by doing something like this:
[self.parentViewController.parentViewController performSegueWithIdentifier:#"MySegue" sender:self];
As of Xcode 7 (I'm not sure if this applies to previous versions):
Select the view controller that is embedded inside your container view.
In the Attributes Selector, there are five drop downs at the top under Simulated Metrics.
Set Size to Master
Set Status Bar to Default
Set Top Bar to Translucent Navigation Bar
Now drag a UINavigationItem onto your view controller.
This will give you the correctly sized view controller and a navigation bar to edit.
So I have a custom bottom tab bar that works if I add it as a subView to any of my views, but I would love for it to be part of the UINavigationController so I don't need to keep track of it in every view initialization. Is there a way to do this?
I can't add it as a subView of navigationBar because I think it is out of the frame and the touches don't register on the tab bar.
I can't subclass the navigationController because apple doesn't let you. So how do I get this working?
It's not true that Apple won't let you subclass a UINavigationController. As of iOS 6, it is allowed, however, I don't think that would help you anyway. I think the best way to do this is with a custom container controller. If you start with a UIViewController in IB, you can put your custom tab bar at the bottom (or just leave space for it and add it in code), and add a container view that fills the rest of the space. You can delete the default controller you get with that container view, and replace it with a navigation controller. As you navigate through your content controllers, your tab bar will remain in place.
I am completely new to ios development and I am only interested in developing for ios5.
I have an app with some scenes, they are mostly tableviews. I also use a navigation controller
I however need to add some status text and buttons that are always visible in all scenes and thought that a toolbar added to the navigation controller should do the trick.
so i thought that i should only have to drag out a toolbar in storyboard to the navigation controller, but it does not stick there. I can add it to the bar underneath with first responder and navigation controller but that does not help me (small icons).
I can also not add it to my table view (but if i drag out a plain view I can add it there)
do I have to make my own custom navigation class that the navigate view uses and then programatically add my toolbar?
Had the same question recently. Check Attributes Inspector in your ViewController's properties in storyboard. There you can define a Bottom Bar.
Well, inside the UINavigationController, you should have something... A UIViewController for instance. You can easily add a UIToolBar by dragging the object inside the UIView of the UIViewController. What might being happening is that as the root view you have the UITableView, in that case I think you can't do that. But to better understand, just take a small print screen of your StoryBoard.
If you zoom up to 100% on the storyboard it should drag.
In an iPad app, I have a tableView as a subview of a top level viewController - let's call it topVC. The tableView is controlled by a dedicated viewController, tblVC, which is a property of topVC. I need the tableView to support iPhone-style detailView navigation.
Setting up a UINavigationController property in the topVC.xib in IB, with tblVC wired as the rootViewController, didn't work, so I set it up the UINavigationController programmatically in topVC viewWillAppear: initializing it with tblVC as the rootViewController, and setting its view as a subview of topVC. This functioned as desired but upon rotation to landscape orientation, the navigationController's navigationBar would pop to the top of thetopVC view.
Is it possible to manually achieve detailView navigation with basic iPhone-style slide-in animation without UINavigationController, using UINavigationBar and UINavigationItem? I thought of setting the detailView out of the frame of the tableView and sliding it in manually, but that only made it appear over another subview and slide into the tableView. How to do this?
You could consider using a popover view controller, and host inside it a standard UINavigationController, with your UITableViewController inside that.
Otherwise you're gonna have to roll your own nav-controller. I've found that it's a real PITA to change/affect some of the innate behaviors you're seeing, like repositioning on rotation.