Rotating iPhone 6 Plus results in gray detail view controller? - rotation

I am experiencing an odd issue with split view controllers, and I've been able to recreate the issue very easily in a brand new app. If you rotate the iPhone 6 Plus to landscape the master and detail view controller become visible on screen, but if you then rotate back to portrait and switch tabs then rotate to landscape, the detail view controller will be completely gray as if nothing is there. This is logged to console: <Error>: CGImageCreate: invalid image size: 0x0 I would like to know if you know the cause or what can be done to fix this bug.
The setup is a UITabBarController with three tabs, each tab is the default UISplitViewController dragged out via Interface Builder. Subclass UISplitViewController and change the 3 split views to that class. Set the split view controller's delegate to self in viewDidLoad. Then return YES from splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:. This sets it up so that the master remains visible after rotating back to portrait instead of the default details view controller.
To reproduce the bug: Launch app in portrait on iPhone 6 Plus, rotate to landscape, rotate back to portrait, tap the second or third tab, rotate to landscape
Bug: The detail view controller is completely gray
Expected: The detail view controller should appear like it normally does if you launch the app, tap a different tab, then rotate to landscape
Additional info: Once this occurs, if you rotate back to portrait and then go back to a different tab it will also show a gray detail controller upon rotation to landscape. The app must be force quit and relaunched to see those split views in landscape.
Now I noticed if you open the app and the first tab is displayed, if you rotate the iPhone 6 Plus to landscape, it actually initializes every single master and detail view controller in the tab bar controller (5 additional view controllers) - it stops at breakpoints set in viewDidLoad if you subclass those controllers. I expected it to only initialize the detail view controller for the split view controller that's displayed on screen. I'm wondering if this is expected behavior? I believe it could be linked to this bug.
My question is, is this gray screen a bug in iOS, or is there a problem with this setup, or is there something that can be done to prevent this from occurring?
How it should appear:
How it appears when following the above steps:

I encountered some thing strange myself, while working on my Multiple Detail Views sample. I was actually getting 2 Table Views displayed instead of 1 Table View and 1 Detail view in 6+ simulator. I could fix it by returning my detail view controller from separateSecondaryViewControllerFromPrimaryViewController method of SplitViewController delegate.
My code is like this:
func splitViewController(splitViewController: UISplitViewController, separateSecondaryViewControllerFromPrimaryViewController primaryViewController: UIViewController!) -> UIViewController? {
if let primaryAsNavController = primaryViewController as? UINavigationController {
if let topAsTableViewController = primaryAsNavController.topViewController as? TableViewController2 {
//Return Navigation controller containing DetailView1 to be used as secondary view for Split View
return (UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("detail1Nav") as UIViewController)
}
}
return nil
}
For me it was happening only when TableView2 was TopViewController, so I am checking for it and if true I am initialising my intended DetailViewController and returning it.
Hope this approach works for you as well.

Related

UIPresentationController changes size when another view controller is displayed on top of it

I am presenting a modal view controller using UIPresentationController. I am setting the frame of presentedView less than the containView's bounds using following method:
override func frameOfPresentedViewInContainerView() -> CGRect {
let myDX = (self.containerView!.bounds.width - 600)/2
let myDY = (self.containerView!.bounds.height - 600)/2
return self.containerView!.bounds.insetBy(dx: myDX, dy: myDY)
}
Everything works great unto this point.
Now, I present another view controller modally (default not custom) on top of the currently displayed modal view controller which takes up the entire screen. So, I have a custom modal view controller underneath the default modal view controller that covers the entire screen.
The problem is when I dismiss the top view controller thats covering the entire screen, my custom view controller shows up covering the entire screen as well. I want my custom view controller's size to remain the same (smaller than containerView). Is there any way that I can achieve this.
Any help would be appreciated
I encountered the same issue. I couldn't solve it by adding constraints, and -[UIPresentationController containerViewWillLayoutSubviews] is called too late (after the dismiss animation is completed).
After some time I figured out that the problem seems to be that the presenting controller view is being removed from the view hierarchy when you present with the default UIModalPresentationFullScreen presentationStyle and added again with a full screen size when it has to be shown again.
In iOS 8, you can use UIModalPresentationOverFullScreen as the presentationStyle when presenting from the smaller controller. The system will not automatically remove the presenting controller's view then. (-[UIViewController viewWillDisappear:] and such, doesn't get called on the presenting controller when you do this though)
You can also use UIModalPresentationCustom which is available in iOS 7, but then you'll have to provide your own transition animation.

NSSplitViewController based application almost never launches with the correct size

I have this app that uses a NSSplitViewController as the root and has a NSTabViewController connected as its detailViewController.
This app is set to launch at 1024x768. The left pane should launch at 320x768 and the right pane (where the tabViewController is), should launch at 704x768.
From 10 times I run this app, 9 times it will launch with the incorrect size (about 500x500). Other strange thing is that this app should not be scalable, but if you hover the mouse near the window border you see cursor indication to scale.
I want this to launch at the correct size and have no scalable option.
Both of these settings are on interface builder but are being ignored.
You can download a sample project that demonstrates the problem, here. Stop and run the project several times to see the problem.
How do I solve this?
I couldn't say for sure what's causing the problem, but one way you may be able to solve it is to add some constraints. Interface Builder doesn't allow you to constrain the default NSView instances that it inserts into the left and right panels of the split view, so you'll need to add your own. The screen-shot below
is taken from your demo, but after I've done the following:
Added a subview to the left split (My Content View), and pinned it's edges to the edges of its superview (the view Xcode automatically adds to the splitview)
Added an explicit width constraint of 320 pixels to My Content View
When I load the app both splits are visible, the divider doesn't budge, and the window can't be resized.
Update - a better solution
Although constraints are one way to solve this problem, I think the root of the problem lies in a bit of unexpected behaviour in Interface Builder. When you drag an NSSplitViewController object onto the canvas, and make it the target of the window controller's content window relationship, the split-view controller's view outlet is not actually set. One consequence of this appears to be that, when you load the app, the divider will appear to be right over to one side. To resolve this, set the aforementioned view outlet to point at the split view:
I've created a demo project with a setup similar to that in the questioner's demo app.
For reference, the same problem occurs if the window content segue points to an NSTabViewController scene. New windows open with a size of 500x500.
I solved it by placing a plain view controller with a container view between my window and my main tab view controller. The window will then use the size of the container view as initial size.
Here is what I did in detail:
Added a new view controller scene to the storyboard
Made that view the size I want my window to use initially
Added a container view to the new view controller scene & added 4 constraints to have the container cover the view completely
Connected the window's content segue to the new view controller
Finally connect the container view to my actual tab view controller scene
Before:
[Window Controller Scene] → [Tab View Controller]
After:
[Window Controller Scene] → [View Controller Scene] → [Tab View Controller]
(with Container View)

Text views and image view disappearing from view controller in Xcode 6.1 storyboard

I updated to Xcode 6.1 to fix an error I was having with the Interface Builder Cocoa Touch Tool spiking to 99% CPU usage when I used the storyboard, which would freeze Xcode. Now that that error is fixed, I have a possibly even more frustrating error.
When I use the storyboard, while I'm working on a UIViewController, my UITextView, my custom UITextViews (which are subclasses of UITextView, but for all intents and purposes in the storyboard, they're UITextViews), and my UIImageView suddenly disappear!
Here's how the default main view inside my view controller looks right now:
Main View
View
Activity indicator
Scroll view
Label
Text view (x=0, y=-65, width=0, height=0) ERROR!
Label
Custom text view (x=0, y=-65, width=0, height=0) ERROR!
Label
Custom text view (x=0, y=-65, width=0, height=0) ERROR!
Label
Custom text view (x=0, y=-65, width=0, height=0) ERROR!
Label
Label
Custom text view
View
View
Label
Button
Image view (x=0, y=0, width=0, height=0) ERROR!
ViewX
Label
Custom text view (x=0, y=-526, width=0, height=0) ERROR!
Width and height Constraints for this view.
Button
Width and height constraints for the scroll view
Center x and y constraints for ViewX within the scroll view.
Center x and y constraints for the scroll view within the main view.
It all started when I adjusted the size of the view controller using "freeform" in order to see views that were off the view controller screen. Once I used cmd-Z to change the view controller back to "fixed" (to the normal size), the missing elements appeared again and everything seemed fine. However, later on, I was editing the view controller and suddenly...bam! They're gone. And when I reset all of them to where they were supposed to be, it just happened again (resulting in the above described x, y, width, height values).
:-(
Does anyone know what could be wrong? I never had this error in Xcode 5.
EDIT:
I was able to use cmd-Z to get the view controller back to normal. Then I restarted my mac and reopened Xcode. Now, I've noticed that the error occurs whenever I resize anything in the storyboard by dragging with the cursor (it doesn't happen if I resize something using the width and height properties on the right panel in Xcode). It happens on other view controllers as well. Even in a view controller that has only a UILabel and a UIImageView in the default main view, when I click and drag the edge of the label to resize it, the image view disappears with values of x=0, y=-64, height=0, width=0.
CONCISE SUMMARY:
In the Xcode 6.1 storyboard, every time I resize any elements in a UIViewController, all UITextViews and UIImageViews collapse and get shoved -64 pixels above the upper left corner of the view controller.
UPDATE
It appears that Xcode 6.1.1 has fixed the bug.
Another workaround is to add constraints to the layout Before resizing of any views. (add missing constraints e.g.). The bug only seems to occur when there are no constraints available. I have reported the bug to Apple with Bugreporter.
Edit: So, at least it seems that Apple Bugreporter is working. The problem is fixed in XCode v 6.1.1.
Seems it's a bug in Xcode 6.1 !!
The current solution is you should resize your elements from the Size Inspector.
Never do the resizing by mouse...
If you uncheck "Use Autolayout" then it won't occur either. Though, you're back to using the old "springs and struts" method. Still, this can be set on a view controller by view controller basis so it's not too bad.
I was having the same problem. I just went to the Apple Developer website and downloaded the beta version of the new Xcode and they fixed this bug!
I just installed XCode 6.2 Beta and the issue seems to be fixed there.
There are 2 types of 1 is main storyboard and 2 is launchscreen storyboard
Your are placing all your views on launchscreen this appears when you app first time then it will not appear
Place all your views on main storyboard instead of launchscreen

Why does ScrollView/Webview object in xcode include some kind of margin?

I'm really getting extremely mad with Xcode, trying to get a ScrollView correctly working. I'm having in fact 2 problems, but I'll separate it in two questions.
First of all, check out this screenshot.
Whether I drag the ScrollView to the top of view or just to the bottom border of the navigation bar, the web view (white square) stays about 60px from the nav bar, as you can see in the simulator.
The only way for me to have the web view aligned just below the nav bar is by dragging the Scrollview to the top of the view, at the top of the nav bar, and dragging the web view all the way to the top too.. Which places (in Storyboard) the web view behind the nav bar. Seems a bit odd, isn't it? The web view object has no attributes assigned to it which could have created that strange space.
What am I doing wrong?
Note: I have less than 40 hours of Xcode experience resulting in knowing nothing of Objective-C lines, but the Xcode interface itself. Learning by tutorials and practice
In the view controller add this method...
- (BOOL) automaticallyAdjustsScrollViewInsets
{
return NO;
}
This will fix it for you.

Resizing view controller acording to tabbar controller

In my application, I have developed one wizard in which I am providing a way for the user to setup his details one-by-one. After finishing all steps, the user will be redirected to the screen where TabBar will come into the picture.
The problem here is that the user can access the same view controllers with the wizard (without TabBar controllers) and normal flow (which is with tabbar controller). In the wizard, I am using a view controller of size 320x480 and the same in normal flow. But whenever I load any view controller using TabBar the 44 pixel view from bottom side gets hidden behind TabBar.
I know the I can manually set the view size, by detecting whether TabBar is present or not, but here in this case number of view controllers are more and its already designed of size 320x480.
I had tried with all methods given in Apple's documentation but none of it seems to work for me.
Following are the methods I have tried, along with some xib settings.
[self setWantsFullScreenLayout:YES];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[self.view setAutoresizesSubviews:YES];
[self.navigationController.view setNeedsLayout];
Is there any way to set the height of a view controller according to whether that TabBar is present or not?
In my case, (Status bar/Nav bar/Hidden tabbar) this worked
//Add this in your ViewController
self.edgesForExtendedLayout = UIRectEdgeBottom;
self.extendedLayoutIncludesOpaqueBars = YES;
However Barry's answer is better if you use Storyboard but I could not for this VC.
Tried for iOs7 and iOs 8.
If you're using storyboards, select each tab VC and clear the box for View Controller > Extend Edges > Under Bottom Bars.
I wasn't able to find a good answer for this, so I ended up adding a BOOL, hasTabBar. I set it true or false based on where I create my view, and use that to calculate my layouts.
frame.size.height -= (hasTabBar*50); // works nicely.

Resources