In my application, I have a UINavigationController with a UINavigationBar that I created programmatically. The UINavigationBar has custom positioning within the view, but whenever will/didChangeStatusBarFrame is called (when you enable the in-call status bar), or the app suspends and resumes, the navBar automagically moves back to the top of the screen.
I was able to override this behavior somewhat by keeping my navBar in place at the bottom, but now it creates a SECOND navBar which it moves to the top.
Why is this happening, and how do I prevent it from happening? This is a new issue with iOS 4 - the app ran fine in both 2.x and 3.x.
Also, before a discussion about Human Interface Guidelines is started, please note that I'm aware Apple doesn't want UINavigationBars at the bottom. However, this is a custom app that will be used by me and me alone, and I require that the bar be at the bottom. Additionally, this issue is driving me nuts and I want to know the answer no matter where my navBar lies...
Whelp, this is a bit of a hack, but it works.
To keep the navBar at the bottom when the in-call status is displayed:
- (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame {
[navigationController setNavigationBarHidden:YES];
}
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame {
[navigationController setNavigationBarHidden:NO];
CGSize s2 = navBar.bounds.size;
[navBar setFrame:CGRectMake(0, [navigationController.view bounds].size.height-s2.height, s2.width, s2.height)];
}
And since multitasking with this app is not only unnecessary but also unwanted, I disabled it by adding the following to the plist:
Application does not run in background
This still doesn't really answer my question about why the navBar was jumping to the top, and it's a hackish fix, but it will have to work for now.
Related
I have a nice little app on the app store that does pretty well for itself. Life was great until iOS 5 came to town. Now, I have a number of issues with my app that I have no way of fixing because I have no clue what is going on, because I feel that they are iOS 5 issues, not mine.
Was there an iOS 5 conversion manual I missed? Or did they just change everything for fun, and want us to figure out where all the easter eggs were?
Here is another issue I am experiencing (that I have wasted so much time trying to fix), that DON'T EXIST AT ALL when I simply say that I want to run the app in good ol' 4.2:
Modal view
My app is a simple reader app. I have a book reading view that displays text with a UIWebView. One of the features I have been working on involves the ability to take notes as you read. This is achieved by hitting a button, and presenting a modal view. Yes, a modal view. The most simple pre- iOS 5 thing you could possibly do. Now, when I dismiss my modal view, just by hitting cancel, and simply dismiss the view, when I get back to my reader view, the navigation bar at the top is pushed up half way off the screen! This doesn't happen in 4.2, but there it is in iOS 5!
What can I do to get this issue resolved?
Thanks for your help.
Ok, I was just able to figure out what in the blazes was going on. I had the shouldAutorotateToInterfaceOrientation value set to a BOOL variable, so that when the modalView was coming back, it didn't know the state/size of the status bar. Fixed that, and the problem disappeared.
I have the feeling it has something to do with the way you present and dismissing the modalview. Apple introduced a new method to present views. May you try using theses instead of the old ones and see if it fixes your problem.
So here is what you do:
change this method:
presentModalViewController:animated:
into the new preferred method introduced with iOS 5:
presentViewController:animated:completion:
Depending if you are using dismissModalViewControllerAnimated:to dismiss your view, change it into dismissViewControllerAnimated:completion.
This methods also have completion handler which is very useful to do some extra work after the view has been presented/dismissed. Maybe that also helps with your other issue. Let me know if that might helped.
A major change in iOS 5 is that the navigationController property of UIViewController is no longer set for modal views. Instead, there is a new (not present in iOS 4) parentViewController property. So where you're using navigationController in a modal view you need to change the logic to something like:
UIViewController* parent;
if ([self respondsToSelector:#selector(parentViewController)]) {
parent = self.parentViewController;
}
else {
parent = self.navigationController;
}
(That's from memory, so I can't guarantee that every t is dotted and every i crossed.)
I was seeing this same clipping problem.
I found out that the reason for my issue was that I set the content size within the modal dialog (something I did for my iPad layout), so removing these two lines seemed to fix the issue:
CGSize size = CGSizeMake(320, 480);
self.contentSizeForViewInPopover = size;
I thought the problem was fixed but it wasn't. After reviewing the code some more, cleaning the build, and retesting it turned out to be a shouldAutorotateToInterfaceOrientation which would return NO for all orientations, for a brief amount of time (flag == NO) while the app is loading (root controller). You want to at least return YES to one orientation like so:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return !self.flag ? UIInterfaceOrientationPortrait == toInterfaceOrientation : YES;
}
Developing an iPhone app.
I've got a really strange problem where, every once in a while, the status bar at the top of my app screen will turn solid black. Not like the black version of the status bar, but like a solid black rectangle with NO text/icons. It's very rare, but usually seems to occur after returning to the app via multi-tasking or from a locked device (the app has been running in the background). I've seen it occur on both 3GS and iPhone4. Here's a screenshot:
I can never reproduce it when trying, it just seems to eventually happen at some point (sometimes it will go for days without happening).
Once it does occur, the app seems to continue functioning fine, even with the status bar gone, except for when I do one specific action in the app which will cause everything to freeze up all the sudden (the app doesn't crash, but everything on screen is frozen and non-interactive). Without explaining the design in detail, the specific action that causes it to freeze up (after the bug appears) is performing a simple upload in the background to a SQL database. Resetting the app is the only way to fix the problem once the black status bar appears.
Anyone else ever experienced this? I can't find a single thread anywhere explaining similar behavior, and it's driving me nuts.
It happened once in my app when I called a drawing method in my custom subclass of UIView instance right before I added it as a subview to parent view.
The solution was apparently easy: add it as a subview first before sending/calling any custom drawing methods.
Examples:
CustomView *aView = [[CustomView alloc] init];
[aView drawSomething];
[self.view addSubview:aView]; //wrong approach
[aView release];
Should be:
CustomView *aView = [[CustomView alloc] init];
[self.view addSubview:aView];
[aView release];
[aView drawSomething];
The screenshot is missing, but what you describe sounds as though you've incorrectly implemented the use of Apple's built-in view controllers.
Both UINavigationController and UITabBarController will automagically shift all the content inside them down by 20-pixels, if they detect there is "supposed" to be a statusbar on screen at the moment.
My guess is that you have some code that is removing the statusbar, but which is kicking-in after the Apple code has already detected it and shifted everything down to accomodate.
The "fix" is to re-read the docs on Apple's classes very carefully and use them as Apple dictates (usually, people use them in ways that seem sensible - e.g. embedding them inside other views - but which Apple has expressly declared are unsupported. Sadly those classes from Apple are very fragile)
Are you holding a reference to a QLPreviewController instance? I was able to solve this problem in my app by creating a new autoreleased QLPreviewController whenever I need to display a file modally, as opposed to reusing the same instance over and over again.
I had a similar problem, which I described in this question here
If you have any, try removing any CGRect frame created by reference to:
[UIScreen mainScreen].applicationFrame]
and instead create the frame using a more manual definition. If that works, you can decide how to proceed from that point.
Fairly new to iPhone app development, so this might be really obvious (if so, apologies in advance!)
I'm building an app which has a tab bar. However, when the app first runs and 'launch screen' is shown with 3 UIButtons - each of these buttons points at a view of one of the tabs. What I need to do is:
Close the existing view
Open the selected view
Set the highlighted tab accordingly
This sounds like it should be quite easy, but a few hours of Googling has found nothing!
Thanks for your help,
Kev
Additional:
Sorry - I am using a tabBarController... But instead of immediately launching the tab bar views I'm using the code below to launch the home menu instead.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
homeViewController *splashView = [[homeViewController alloc] initWithNibName:#"homeView" bundle:nil];
[window addSubview:splashView.view];
// [window addSubview:tabBarController.view];
[window makeKeyAndVisible];
return YES;
}
On the home menu there are UIButtons which need to link to individual tabs... Hope this clarifies...
Cheers!
Oh. Then it gets a bit more complex. What you want to do is basically this:
Add a method to your AppDelegate - (void)showTabBarWithSelectedTab:(NSUInteger)tabIndex. In this method, use tabBarController.selectedIndex to select the correct index, then remove homeViewController's view from the window and add tabBarController's view instead.
In homeViewController, have actions for the buttons that calls the newly created AppDelegate method with the correct tab index.
Generally I would say that this adds a bit too much logic to the AppDelegate. Ideally you'd implement this in a new view controller, surrounding and managing both homeViewController and tabBarController. However, having a UITabbarController inside of another view controller isn't officially supported - although you can get it to work anyway.
it's a bit hard to fully understand your question, but it sounds like you should be using UITabBarController instead of the stand-alone view UITabbar. This is essential reading! Good luck
I've finally gotten a working "alpha" version of my first app installed and (mostly) working on my iPhone 3G. So excited I came into the house and danced a little jig while my wife rolled her eyes at me. Don't care - totally stoked that I figured it out on my own (with lots of help here - thanks again, guys).
I've never really dabbled with or cared about animation; I'm more into utility-type apps. However, I've decided that I'd like to animate my app's opening image / default.png / splash screen similar to the flipside view controller animation - where the image spins from a view on the front to a different view on the back. I've found code for animating between views using the flipside animation, but how would I go about animating from a static *.png image to my navigation-based table view? I'm just not even sure where to start with this one - literally the first time I've ever even searched for anything graphics-related in the documentation.
Any help will be appreciated. As usual, thanks in advance!
You can't do anything with your Default.png, and just for form I'll point out that that HIG guidelines say that you shouldn't use it as a splash screen :-).
I would suggest that you use your initial view controller to duplicate the Default.png, and copy the flip animation code from a basic Utility app template - you probably want to use [NSObject performSelector:#selector(...) afterDelay:0] to get it to flip, called from your initial viewDidLoad:.
You can just present a modal view controller when you first launch using the flip transition instead of the default slide. Have your initial view controller loaded from your xib just display the same image you are using for your Default.png. Once you get the -viewDidLoad call in your initial view controller, push the modal view specifying the transition you want. Something like this:
- (void)showMainView;
{
MainViewController *controller = [[MainViewController alloc] init];
[controller setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:controller animated:YES];
[controller release], controller = nil;
}
As Paul suggested, you should call this using performSelector:withObject:afterDelay:
[self performSelector:#selector(showMainView) withObject:nil afterDelay:0.15];
Hope that helps.
I have a window within an iPhone application, which is displayed modally to allow the user to enter their settings for a web service upon 'first run'.
The text fields have helper text set, and when you tap them the keyboard shows and allows you to enter text.
Unfortunately the text fields do not clear the helper text, show the edit caret or show the text being entered (as in the screenshot below).
Any suggestions?
The window is being displayed with [self presentModalViewController:<controller_name> animated:YES];, which may or may not be the cause of this issue - when I run the UI via the Interface Builder 'test' application the text boxes respond like normal.
Clear when editing begins has been set for both fields.
Thanks in advance!
Edited: More information
After the info Bart Gottschalk provided I thought I should add some more information. First, the application is a Navigation Based Application.
Secondly, the test app Bart recommended worked fine, so that takes the modal window and the view out of the equation.
Third, I was presenting the modal view when the -(void)viewWillAppear... delegate method was being called - which may very well be the wrong place... however I'm not 100% sure if I should be presenting the modal view from within the didFinishLaunchingWithOptions of the App Delegate...
(this is happening on Simulator and iPhone 3.1.3)
In Interface Builder did you check the box for "Clear When Editing Begins"? With that checked the text field should clear any value once the use taps to edit which is the behavior I think you're looking for.
You can also set the same property programatically using clearsOnBeginEditing if that is convenient in your code.
My guess is that you've done this and it's not behaving as you expect. Just checking on this as a first step in helping you debug.
Also, does this happen in both the Simulator and on a testing device?
Bart
Edited Below...
This seems strange. Let's strip away everything but the basics of presenting a modal view when the application starts and see what happens.
I've recreated the most basic app (that I know of) to test presenting a modal view controller at launch and verify that field editing works fine. What happens for you when you do the same/similar in a new project?
Here is what I'm doing:
1) Create a new view-based app in Xcode called "ModalViewTest"
2) Create a new UIViewController with xib called ModalViewController
3) In ModalViewController.h add a method
-(IBAction)closeModalView;
4) In ModalViewController.m add the method implementation as
-(IBAction)closeModalView {
[self dismissModalViewControllerAnimated:YES];
}
5) In the ModalViewController.xib create two text fields and set the placeholder text for each to abcd1234 and confirm that "Clear When Editing Begins" is checked.
6) In the ModalViewController.xib add a button "Close" and set Touch Up Inside to fire "closeModalView"
7) In the application delegate (ModalViewTestAppDelegate) add the following import
#import "ModalViewController.h"
8) In the application delegate (ModalViewTestAppDelegate) applicationDidFinishLaunching add the following after the line containing [window makeKeyAndVisible];
ModalViewController *modalViewController = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
[viewController presentModalViewController:modalViewController animated:YES];
9) Save everything
10) Build and Run this new app
Does editing of the text fields work as expected? If yes, what is different about how you are building and presenting your modalView? If no, then we'll need to dig further to determine what is going on in your environment.
Second Edit Below...
When creating a navigation-based application I did the following to present the modal view at application start. Does this work for you in both your test app as well as your real app?
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
ModalViewController *modalViewController = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
[navigationController presentModalViewController:modalViewController animated:YES];
}
Well, I just figured it out, but honestly without the persistence and awesome help from Bart it would have taken much longer and been much more frustrating.
It turns out the problem was that I was using a Window instead of a View in the XIB file. This was why when showing the modal view within the Navigation controller it wouldn't display properly (i.e. only a white screen) and why the UITextField would not work properly when showing the view from the RootViewController.
So, to recap - modal views should have UIView, not UIWindow in the XIB/NIB File.
Thanks for your help Bart!
I have the same problem but in iOS7 only. I solved it by changing the tint color of textField to blue in the Storyboard