This is an infuriating problem... Xcode 6 and iOS 8 introduced adaptive segues, but they do not degrade gracefully in iOS 7.
Here is the (very common) scenario: I have an iPhone storyboard with a navigation controller with several other view controllers that should be pushed (i.e, slide from the right to the left) when the segue is called. The segues were created with a previous version of Xcode in IB, but upon inspecting them with the attributes inspector I see that the segue type selected is "Show (e.g. Push)".
This produces the push style segue I'm after in iOS 8. However, in iOS 7, the views are presented modally (from the bottom up), and what's worse, they lose their navigation bar. Since it was created in a previous version of Xcode, I tried re-creating the segue in IB to no avail.
I cannot find ANY documentation on this from Apple. How can I force the push style segue for iOS 7 without using the now deprecated Push segue?
Related
I've been developing an app for the past few months, and I was always testing on my iOS 11 device and simulators. Since we are close to public release, I decided to test the app on iOS 9 and 10 simulators to make sure everything is ok.
To my disapointment, the core element of the app is broken: Its an app that displays a list of articles in tableviews, using a TabBarController. More article categories can be accessed through the side menu. However, when I display a VC form the side menu, for which I create the VC, embed it in a NavigationController and then add it in the TabBarController and make it the selected tab, the NavBar is under the status bar and the tableview's content insets extend under the tabBar, which also breaks my TabBar and creates a whole lot of other problems.
The weird thing is that after navigating to the next VC, the whole statusbar situation is fixed, so I'm guessing something is initially off with the NavBar that gets fixed once a second VC is pushed.
Does anyone have any idea on how to fix this bug? On iOS 11 everything works perfectly, while on iOS 9 and 10 only when a new VC is pushed, the error is fixed. Please note that I'm not using a UITableViewController but a ViewCOntroller with an embeded TableView, since I also need to add othr views at the bottom of my view controller.
After updating from Xcode 8 to Xcode 9 I've noticed this very strange behaviour in the navigation bar only on devices running iOS 11.
This bug appears after navigating from my left side menu that show the menu controller you choose modally with a default presentation (That is Full Screen)
I've posted a video here: https://youtu.be/mgjlbkMi-N8
It seems a bug of the compilation on Xcode 9.
Tryed also on real device iPad Pro with iOS 11.
The same code compiled with Xcode 8.3.3 works as expected, while compiled with Xcode 9 exposes the issue.
I've put a playground code here: https://github.com/shadowsheep1/xcode9navigationissue
With already a workaround: set the presentation to Over Full Screen.
But that has no meaning this is not the exptected operation.
Once the navigation bar is broken, is broken for every navigation controller in the App.
Any idea?
EDIT:
Apple Developer Relations January 23 2018, 11:13 PM
There are no plans
to address this based on the following:
You are creating a detached presentation, which is causing multiple
navigation bars to be placed in the view hierarchy. The navigation bar
that is seen is not the one where pushes are happening, thus the error
in display. I don’t know why this didn’t happen on iOS 10, but it was
an invalid configuration there as well.
We would recommend that you use a proper view controller container to
implement this menu, rather than what seems to be done (the
IS_SlideMenu_View being placed directly in the window).
I have the same problem with regular UIModalTransitionStyleCoverVertical.
I've solved it by setting UIModalPresentationOverFullScreen or UIModalPresentationOverCurrentContext.
Possibly it also helps you.
Example for navigation that is presented modally:
if (#available(iOS 11.0, *)) {
navController.modalPresentationStyle = UIModalPresentationOverFullScreen;
}
I have an app with a navigation view controller and once a cell is tapped on, a screen is pushed on top of it. However, when testing this app on a simulator and on multiple devices, the push segue somehow turns into a modal segue. These pictures will show a gist of what is happening:
Table View:
What is supposed to happen (Show segue):
What happens instead (Modal segue):
I am running this on an iOS simulator but for my app the result is the same. I have seen people post about this issue taking place on iOS 7, but is this supposed to happen with iOS 9?? Please help.
Thanks!
I have found a solution. It appears, that now, in Xcode 7, you should make a segue not to navigation controller, but to your viewController directly, in order to achieve desired push segue.
I'm in the process of moving from hard-coded layouts to the new universal storyboard system available in Xcode 6. It's great to be able to create one storyboard that, through the magic of auto-layout, will work on both the iPhone and the iPad. And my understanding is that universal storyboards are backwards-compatible with iOS 7.
However, I'm running into a problem using popover segues. On iOS 8, the new 'Present as Popover' segue will display as a popover on an iPad interface and as a modal view controller on an iPhone interface. This is exactly the behavior I want, but when I run my universal storyboard on iOS 7, the app crashes whenever I attempt a popover segue. Here's the error message I get:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[UIPopoverController initWithContentViewController:] called when not
running under UIUserInterfaceIdiomPad.'
This is a bit annoying, as I don't want to have to resort to separate storyboards for each UI idiom.
It looks like these are my choices:
Create a subclass of UIStoryboardSegue that will show a popover on iPad and a modal view on iPhone. This requires manually changing the class of all popover segues in my app.
Create two segues out of every bar button item, table cell, etc. - one that's a pure 'Popover' segue and one that's a pure 'Modal' segue. In this case, I'll be unable to just control-drag to the next screen and will have to create custom action methods that will invoke the right segue based on the current UI idiom.
Abandon universal storyboards and create device-specific storyboards until I can require iOS 8 from my users.
None of these are great alternatives, so I was wondering: do I have any other options? Am I missing any problems with my proposed solutions?
Xcode 6 supports unified storyboards. A storyboard can add or remove views and layout constraints based on the size class that the view controller is displayed in. Rather than maintaining two separate (but similar) storyboards, you can make a single storyboard for multiple size classes.
But Size classes are based on UITraitCollection which is supported on iOS8. That's why it's crashing on iOS7.
I ended up making a modal segue and checking in code to see if it was on a iPhone with iOS 7. I then use performWithSegue to pick which segue should be taken. iOS 8 can handle the popover code but iOS 7 has issues.
Seems Like You are trying to present your view modally if device is iPhone and as Popover if the device is iPad..
To produce that the easiest way would be to check the InterfaceIdiom when the event occurs(like button click) and conditionally using appropriate approach.
-(IBAction)btnClicked:(id)sender{
if([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad){
//your popover code..
}else{
//your present modaly code...
}
}
Last night I updated XCode and the iOS SDK.
It looks like it messed up the UINavbar on the storyboard, here is a pic:
It shows two titles overlapping, if I delete the title , then there is still another one in the background, Im not able to remove that second one.
The strange part is it magically disapear, if I run the app.
XCODE version --> Version 5.1 (5B130a)
iOS SDK---------> Version 7.1
Yes, there's a new property for the uiviewcontrollers named "exteded edges" you must uncheck this in the interface builder inside the uiviewcontroller preferences. Or by inserting this code in your view did load. This will tell the controller not to draw the view under the navigation bar.
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]){
self.edgesForExtendedLayout = UIRectEdgeNone;
}
I checked again and there was an extra navigation bar, its weird that It shows only after I upgraded, I think something happen with that view because I embedded it into a navigation controller.