iOS 8.3 modalPresentationStyle OverCurrentContext does not inherit status bar appearance and visibility - statusbar

Consider the following setup:
You have a simple application with a single UINavigationController subclass and a single UIViewController subclass in it.
The UINavigationController overrides preferredStatusBarStyle() method and returns UIStatusBarStyle.LightContent
The UIViewController overrides prefersStatusBarHidden() method and returns true
In iOS 8.0 - 8.2 when another UINavigationController (with another UIViewController that does not override anything) is presented with the modalPresentationStyle set to UIModalPresentationStyle.OverCurrentContext, the newly presented controller inherits the status bar appearance and visibility.
But in iOS 8.3 in the exact same situation - the newly presented controller does not inherits the status bar appearance and visibility
Another example would be to present an instance of UIImagePickerController - the exact same thing happens regarding the status bar appearance.
The questions are:
Why in iOS 8.3 the newly presented controller does not inherit the status bar appearance?
What has been changed (I was unable to find any meaningful reference in the iOS 8.2 to 8.3 API diff regarding this)?
Is there any elegant solution to this, instead of overriding everywhere the appearance and visibility methods?

Try that:
(viewControllerToBePresented).modalPresentationCapturesStatusBarAppearance = true

Related

NSSplitViewController in OSX 10.10 using Xcode 6

According to documentation on NSSplitViewControllers, the associated NSSplitView uses the NSSplitViewController as its delegate. Specifically in the documentation, "The split view controller serves as the delegate of its split view object (the object that manages the dividers). If you override a split view delegate method, your override must call super."
I have implemented an NSSplitViewController in interface builder and gave it a class. However, none of the splitView delegates are ever invoked. Additionally, if I just do something like spit who the splitView delegate [ NSLog (#"%#", self.splitView.delegate); ], the result is "null". If, however, I assign the delegate either in IB itself (by dragging the delegate outlet to the NSSplitViewController) or inside code ([self.splitView setDelegate:self];), I get the following error:
An uncaught exception was raised
SplitViewController's splitView is unable to use autolayout because the SplitViewController overrides an incompatible delegate method.
I'm completely flummoxed.
If the delegate of a split view implements one of the following methods, it becomes incompatible with auto layout.
splitView:constrainMinCoordinate:ofSubviewAt:
splitView:constrainMaxCoordinate:ofSubviewAt:
splitView:resizeSubviewsWithOldSize:
splitView:shouldAdjustSizeOfSubview:
https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/#10_8AutoLayout
And because NSSplitViewController requires the use of auto layout (mentioned in the documentation), these methods are incompatible with NSSplitViewController and shouldn't be implemented in a subclass.
Extending on Taylor's answer.
In macOS 10.8 Apple made improvements to NSSplitview, which includes respecting constraints of the subviews. Apple also introduced holding priority for subviews of NSSplitview. Holding Priority is the priority of holding the size of the subview, so while resizing the splitview, subview with the lowest priority will resize first.
So to control the resizing behavior you will have to tune the holding priority of SplitView Items. This can also be done in storyboard directly

iOS7 : how to set navigationItem property of UISearchDisplayController?

I have a UISearchDisplayController that works perfectly in one of my iOS6 app. Now, I want to migrate this app to iOS7.
I had read the Apple docs, and it says the following :
Starting in iOS 7.0, you can use a search display
controller with a navigation bar (an instance of
the UINavigationBar class) by configuring the
search display controller’s displaysSearchBarInNavigationBar
and navigationItem properties.
displaysSearchBarInNavigationBar is pretty easy to set up. But the only clue I have for navigationItem is the following :
Important: The system raises an exception if you
attempt to set the titleView property for a search
display controller’s navigation item.
I can't seem to find example of how to set the navigationItem. How to I say to my navigationBar to embed my searchBar? Somebody can show me an example?
Thank you in advance!
UISearchDisplayController creates and manages the navigation item needed to display the search bar in the navigation bar. You don't need to create your own, although you can access it via searchDisplayController.navigationItem after displaysSearchBarInNavigationBar has been set to YES (the navigationItem is created lazily)
When the view controller with the search display controller is asked for its navigationItem, the search display controller will return its item (which contains the search bar) instead of the view controller's.

Where to define the -shouldAutorotate method in iOS 6?

I am trying to define the shouldAutorrotate method, but I don't know where to define it as it's never being called. I have a UITabBarController, with three tabs (each one, with a root navigation controller) in my project. My aim is to disable autorotation in some specfic cases.
Thank you!
OK, solved. What I did: In my topmost navigation controller I defined
-(BOOL)shouldAutorotate {return [self.visibleViewController shouldAutorotate];}
and then, in my next viewController
-(BOOL)shouldAutorotate {return NO;}
Thanks guys!!!
you can write that method in viewcontroller.m file, for which you want to disable autorotation
Here is the code for iOS 6:
#ifdef IOS_NEWER_OR_EQUAL_TO_6
-(BOOL)shouldAutorotate
{
return NO;
}
#endif
Read the iOS 6.0 Release Notes:
Autorotation is changing in iOS 6. In iOS 6, the
shouldAutorotateToInterfaceOrientation: method of UIViewController is
deprecated. In its place, you should use the
supportedInterfaceOrientationsForWindow: and shouldAutorotate methods.
More responsibility is moving to the app and the app delegate. Now,
iOS containers (such as UINavigationController) do not consult their
children to determine whether they should autorotate. By default, an
app and a view controller’s supported interface orientations are set
to UIInterfaceOrientationMaskAll for the iPad idiom and
UIInterfaceOrientationMaskAllButUpsideDown for the iPhone idiom.
A
view controller’s supported interface orientations can change over
time—even an app’s supported interface orientations can change over
time. The system asks the top-most full-screen view controller
(typically the root view controller) for its supported interface
orientations whenever the device rotates or whenever a view controller
is presented with the full-screen modal presentation style. Moreover,
the supported orientations are retrieved only if this view controller
returns YES from its shouldAutorotate method. The system intersects
the view controller’s supported orientations with the app’s supported
orientations (as determined by the Info.plist file or the app
delegate’s application:supportedInterfaceOrientationsForWindow:
method) to determine whether to rotate.
The system determines whether
an orientation is supported by intersecting the value returned by the
app’s supportedInterfaceOrientationsForWindow: method with the value
returned by the supportedInterfaceOrientations method of the top-most
full-screen controller.
The setStatusBarOrientation:animated: method
is not deprecated outright. It now works only if the
supportedInterfaceOrientations method of the top-most full-screen view
controller returns 0. This makes the caller responsible for ensuring
that the status bar orientation is consistent.
So I would first try to implement the behaviour in the app delegate. If that’s too coarse for your use case, I would try to implement the -shouldAutorotate (note the single r!) method for the individual content view controllers. If that does not work (see the quote above), implement this method in your container controller, ie. the tab bar controller or the navigation controller.
See also the WWDC 2012 Session #236, The Evolution of View Controllers on iOS.

viewWillAppear and viewWillDisappear callbacks when a ViewController's view is hidden by another view & UIViewController Containment in iOS5

The UIViewController docs mentions about -viewWillDisappear:
"This method is called in response to a view being removed from its
window or covered by another view. This method is called before
the view is actually removed or covered and before any animations are
configured."
In iOS 4.3 and lower we are supposed to present a viewController and not add a viewController's view to the view hierarchy explicitly, so the calls -viewWillDisappear or -viewDidDisappear would be triggered when a new view controller is being presented over the existing view, in which case 'covered by another view' is true! But what if a viewController's view is hidden since another view obstructs the viewController's view? Do we get these callbacks?
Well, in iOS 5 there is a UIViewController containment concept where views can be directly added as subviews in view hierarchy by setting the parent-child relationship between viewControllers. So, unlike <= 4.3 OS, -viewWillDisappear and -viewDidDisappear calls should ideally be triggered when a viewController's view is obstructed or covered by some other view, which I have verified by a sample project that it is not happening in SDK 5.0.
Has anyone found this problem related to these callbacks?
Or, is my understanding correct?
Thanks,
Raj
Someone has the same kind of problem here :
iOS 5 : -viewWillAppear is not called after dismissing the modal in iPad
You should read the answers, I found them very interesting.

Putting an ADBannerView on top of a UINavigationController

I'm trying to put an iAd banner in an app that is based on a UINavigationController (it's not the standard nav-base app proposed by xcode, cause I don't need the table view).
I'd like to place an ADBanner on its bottom, to be always visible, no matter how the user pops and pushes views.
I studied the iAdSuite example in the apple sample code, but, though it's reported among the "best practices", I don't think it's the best practice for what I need. It basically declares an ADBannerView in the app delegate class and then implements the ADBannerViewDelegate methods for every single view the app needs. That means implementing the ADBannerViewDelegate methods over and over again on every view controller class you need! It doesn't seem too smart... :(
I'd rather prefer to have an approach more similar to what Apple itself does in the tab bar based app, where you have a part of the window always occupied by the tab controller and all the views switching above without affecting the tab bar view below.
You can't directly put an ADBannerView along with the nav controller in the app delegate, because ADBanner needs to be placed in a view controller (you get a runtime error otherwise).
I tried to subclass from UIViewController, implementing the ADBannerViewDelegate in this class, and place it in the rootViewController along with a UINavigationController but I'm not having good luck with this approach...
Has anybody found a good, simple way to to this? Any hint?
Thank you for any help...
You can have just one class for ADBannerViewDelegate, and just one instance of ADBanner itself. When the currently active view changes, remove ADBanner from the old view, add it as a subview to the new view.
EDIT:
to clarify, you don't need each view implement the ADBannerViewDelegate. You only should have one class implement it (that class doesn't have to be a view controller for that matter).
You would also need to maintain a somewhere a property that would point to the currently active view (e.g. you can update that property in your Navigation Controller's navigationController:didShowViewController:animated:, or come up with your own protocol for that if your views appear in a more complex way).
Then in your ADBannerViewDelegate you'd just resize the view currently pointed to by that current view property. The actual view doesn't even have to know it has an ad in it ;)