Unbalanced calls in iOS 8 - ios7

I'm getting the following warning when I present a modal view controller on a navigation controller in iOS 8 at launch. It works fine on iOS 7.
Unbalanced calls to begin/end appearance transitions for UINavigationController.
Here's what I'm doing.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[self.window makeKeyAndVisible];
...
[self.navigationController presentViewController:self.modalViewController animated:NO completion:nil];
}
In iOS 8 I can see the navigation controller for a split second before the modal view is presented. In iOS 7 I see the modal view controller immediately without the warning.
How to I get the same behavior in iOS 8?

In order to get rid of the warning, you need to move the code to your first view controllers viewDidAppear. In order to make it look nicer, you might consider doing some tricks. I had the same problem, and I solved it by showing a full screen image of your modal view controller on your first view controller, and hide this image after the modal view controller is presented, e.g. using the method performSelector:withObject:afterDelay

Related

setStatusBarOrientation:animated: not working in iOS 6

I've used this code to force an orientation change back to portrait when the user is finished watching the video (it allows viewing in landscape mode), before popping the video view controller off the navigation controller:
//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
This worked perfectly until iOS 5.1.1. I've even tried to use the new present/dismiss methods after reading in another post that those should be used now:
[self presentViewController:mVC animated:NO completion:NULL];
[self dismissViewControllerAnimated:NO completion:NULL];
The problem is it doesn't work at all. After I rotated the video viewer to landscape and then pop it, my settings view (table view controller) comes back, but also in landscape mode.
I've even tried the tip from Here
"The setStatusBarOrientation:animated: method is not deprecated outright. However it now works only if the supportedInterfaceOrientations method of the topmost full screen view controller returns 0. This puts the responsibility of ensuring that the status bar orientation is consistent into the hands of the caller."
So I've experimented with setting a flag to force supportedInterfaceOrientations to return 0 (before calling the first code block above) but it doesn't work either.
Does anybody have a solution for this?
Thanks for your time and effort.
setStatusBarOrientation method has changed behaviour a bit. According to Apple documentation:
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
Your root view controller should answer false to the method shouldAutorotate in order that your app responds to setStatusBarOrientation:animated
From Apple Documentation: "if your application has rotatable window content, however, you should not arbitrarily set status-bar orientation using this method"
To understand that, put a breakpoint in the shouldAutorotate method and you will see that it is called juste after setting the status bar orientation.
Here is how I fixed.
https://stackoverflow.com/a/14530123/1901733
The current question is linked with the question from the url above.
The statusBarOrientation is a real problem in ios6.

Black screen on iPad storyboard using splitViewController

I have an app whose iPhone storyboard is working fine. My iPad storyboard (which uses a split view controller) just comes up with a black screen.
Logging tells me that both the master and detail view controllers' -viewDidLoad: methods are being called
Logging also tells me that my detail's view's -drawRect: is being called
I didn't post code because I think the problem lies in my storyboard setup (iPhone storyboard works fine).
Update: -viewDidAppear: isn't being called in either of my view controllers, either.
On an iPhone application, you can specify the root view of your application with the "Main nib file base name" key in the info.plist file. From the sound of it, the correct root view is not getting loaded for the iPad. Trying adding/or setting the correct view for "Main nib file base name (iPad)" in your info.plist file.
Also, make sure you are using the correct application lifecycle method to load your views.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
[self.window addSubview:yourSplitViewController.view];
} else {
[self.window addSubview:yourNavigationController.view];
}
[self.window makeKeyAndVisible];
return YES;
}

UITextField not working inside a UITabBarController with IOS5

Are there any restrictions on a UITextField when placed inside a tabview which not the main interface. In other words
Working fine scenario
1. A tab based application, with one of the view having a UITextField.
2. The tabview is the main interface for the application.
This works fine without any glitches
Not-working so fine scenario.
1. A tab based application, but the tab view is not the mainview.
2. There is another view MainWindow.xib with some intro animation, which then calls and shows the tabview.
3. UITextfield in such tabviews does'nt seem to work - especially in IOS5. Both methods work fine till IOS 4.3
4. The textfield is visible, but tapping it does not show any keyboard, if i call becomeFirstResponder via code, the keyboard is shown but is not responsive.
Any suggestions
The code is pretty standard
in the AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
tabViewController = [[tabView alloc] initWithNibName:#"tabView" bundle:nil];
[self.window addSubview:tabViewController.view];
//self.window.rootViewController=tabViewController
[self.window makeKeyAndVisible];
return YES;
}
tabViewController has a ProfileViewController with a simple textfield.
The textfield works fine if i do this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
tabViewController = [[tabView alloc] initWithNibName:#"tabView" bundle:nil];
profileView=[[Profile alloc] initWithNibName:#"Profile" bundle:nil];
//calling the view directly without using a tab view
[self.window addSubview:profileView.view];
[self.window makeKeyAndVisible];
return YES;
}
Is there something else that needs to be done for IOS5 when the tab view is not the main interface? I have been cracking my head at this for a few days, all my apps with a UITextfield inside a tabview are not usable in ios5. Any help is highly appreciated
Edit: Uploaded the project file http://www.mediafire.com/?xjuc4udlph78saj - XCode 4.2 on Lion
It is a simple project with two options, Creating a tabbarcontroller from the delegate itself, and i also have a view(tabView) with a tabbarcontroller. There are 2 views for the tabbar FirstViewController & SecondViewController.
In the AppDelegate.m if using method 1(create UITabBarController inside AppDelegate, all is well). If i choose to add a subview of tabView, the uitextfield does not work.
I have not really handled the releasing of objects, since this is test project and it is only for proof of concept.
Thanks
After hours of searching, fiddling and experimenting. I have found out the solution.
This seems to happen when there are more than one UIWindow in the application.
In my case, i was diong this
AppDelegate starts off with its own UIWindow Once i have played some
startup animations, i try to display another view with a
tabbarcontroller, and ofcoures a window to hold the UITabBarController
The second window (even after setting it to makeKeyAndVisible) seems
to be blocking keyboard events fore UITextField inside the
UITabBarController.
The following has worked for me:
Rather than having the second view with its own window, i had it with a UITabBarController, and a UIView/UIWindow(this is for the sake of having a default view for the nib file). And when i needed to show the tabbarview i have used this
[[[UIApplication sharedApplication] keyWindow] setRootViewController:TabBar]
I am not sure of a better way, but that have worked for me. In short, i have found that having another UIWindow inside the app causes issues with becomeFirstResponder.

Passcode ViewController Presentation from Modal View

I'm implementing a Passcode feature in my iPhone app which has a UITabBarController as a root view controller. I have everything working great in most situations, by displaying a modal Passcode ViewController from the tabBarController when the app goes into the background, like so:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
if ([[NSUserDefaults standardUserDefaults] valueForKey:kPasscodeStringKey]) {
PasscodeEntryVC *passcodeView = [[PasscodeEntryVC alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:passcodeView];
[tabBarController presentModalViewController:nav animated:NO];
}
}
My problem comes when the app is already displaying a modal view controller when it enters the background. Then, no passcode view appears. What would be the correct way to do this? Instead of just sending the message to the tabBarController to present the view, should I be checking first to see what the current view is, then have that present the passcode? If so, how is this done? Thanks.
First - you are leaking memory because you do not release your passcodeView and navigation controller nav.
Second - you could keep a simple BOOL variable that is updated whenever a modal view is presented or dismissed. If there is a modal view, just call dismissModalViewController:animated: in your applicationDidEnterBackground: method.
You could also check the frontmost view controller with [self.navigationController.topViewController class], but I have found this to be unreliable.
What I usually do is to ensure that any views I have that may present a modal view controller to dismiss the modal view controller whenever it is sent the UIApplicationWillResignActiveNotification notification, while over in my app delegate, I set it up exactly like yours.
One caveat though, is that whenever you dismiss the said modal view controllers, you need to ensure that you dismiss them with animated: set to NO before presenting your passcode view controller.

NSNotificationCenter for presenting multiple modals?

I have an app delegate, whose default view should be preceeded by a modal view controller, and sometimes by two modal view controllers. So in the app delegate's didFinishLaunchingWithOptions, I'm checking if there is need for, and in that case displays, the first modal view controller.
Upon dismissing the first modal view controller (using [self dismissModalViewControllerAnimated:YES];), I may want to display the second modal view controller. This is known by the app delegate as well.
So my solution was to use NSNotificationCenter to tell the app delegate that the first modal view controller now have been dismissed. When that happens, the second modal view controller can be displayed by the app delegate, if it is needed.
It works fine, but is there a cleaner solution? I think NSNotificationCenter is really ugly stuff.
Note on displaying multiple modal view controllers at once
I did try to display the first AND the second modal view controller inside of didFinishLaunchingWithOptions, but I never got it working. Here's what I tried:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window setRootViewController:tabBarController];
[self.window makeKeyAndVisible];
[tabBarController presentModalViewController:pinViewController animated:NO];
if([self needsActivation]) {
[tabBarController presentModalViewController:activationViewController
animated:YES];
}
}
UPDATE: The above code works with the following correction:
if([self needsActivation]) {
[pinViewController presentModalViewController:activationViewController
animated:YES];
}
In this particular case, there was no need for NSNotificationCenter, as I thought. I had tried to display multiple modal view controllers, but I'd made an error.
When displaying the modal view controller B from the modal view controller A, it works fine. I had tried presenting modal view controller A and B from a parent view controller.
So when presenting modal view controllers in a hierarchy instead, there is no need for NSNotificationCenter. The view controllers are dismissing themselves, animations works and I'm a step further towards bending the UIKit to my will.
I've edited the code in my question, which now works fine.