Why does my Done button disappear in a simple FlipsideViewController app?
I have a simple two-screen app that I built a year ago using the "utility" project template in Xcode 3. This creates an app delegate, a main view and a flipside view. The flipside view has a UINavigationBar at the top with a Done button in the left position.
I just finally upgraded to Xcode 4 with SDK 4.3, and when I build the app now, the Done button doesn't appear, either in the simulator or on my device. But if I create a new project using the Xcode 4 "utility" template, the Done button displays and works correctly. Unfortunately the upgrade removed my SDK 4.2 files, so I can't rebuild for SDK 4.2 and test whether that's what made the difference.
I noticed that the new template sets up the main view differently, using the rootViewController property of the window rather than adding the main view as a subview of the window (more info here). I tried copying this code into my app delegate instead of the addSubview code, but the view didn't display at all, so I must have missed something ... but I would just as soon maintain iOS 3.0 compatibility anyway. I can't find any other difference between the newer "utility" template and my own project based on the old template.
I also tried moving the Done button from the leftButtonItem to the rightButtonItem in Interface Builder, but it still doesn't appear.
MORE INFO:
I tried this on all the versions of the iPhone simulator that are available in my Xcode installation. When building with SDK 4.3, the Done button does not appear with the iOS 4.0-4.3 simulators ... but it does ap开发者_Python百科pear with the iOS 5 (beta) simulator.
Next, I wired up IBOutlets to the navigation bar, navigation item and done button in Interface Builder so I could probe them from my code. When I checked them immediately after presenting the flipside view with presentModalViewController, I found that the done button (a UIBarButtonItem) exists, but the navigation item's leftBarButtonItem is null. If I assign the done button to that property, it appears. So somehow that button is getting disconnected from the leftBarButtonItem property when the flipside view is initialized or displayed.
WORKAROUND:
In Interface Builder, if I view the outlets for the Navigation Item, I see that the Done button is linked to its leftBarButtonItem property, but if I view the outlets for the Done button, it has no links. If I link it to the Navigation Item then the button appears! With this setup, the Done button shows the Navigation Item as an outlet, and the Navigation Item shows the Done button as an outlet twice. This is not needed in the new Utility Application template, so I don't know why it's needed here. It seems to be working, but if anyone has an explanation or a better solution I'll reserve my answer points for that.
Had a similar problem with custom BarButtonItem's, although I'm not exactly sure that it's the same problem they're pretty close. So, I'm posting an answer in case someone stumbles upon your question like I did :)
Problem: Add a custom UIBarButtonItem with the following code to a navigation bar with a custom background. When you push another view controller and come back, the custom UIBarButtonItem doesn't appear but you can continue to touch where it used to be and invoke its target action. The problem only occurs on iOS4.3 simulator and everything works fine without the solution on iOS5 simulator. (Everything works normally also on iOS5 devices, couldn't try the code on an iOS4.3 device)
UIButton* doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
[doneButton setBackgroundImage:[UIImage imageNamed:@"barbutton.png"] forState:UIControlStateNormal];
[doneButton setTitle:@"Done" forState:UIControlStateNormal];
doneButton.titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:12.0];
[doneButton.layer setCornerRadius:5.0];
[doneButton.layer setMasksToBounds:YES];
[doneButton.layer setBorderWidth:0.2];
[doneButton.layer setBorderColor:[[UIColor blackColor] CGColor]];
doneButton.frame = CGRectMake(0.0, 0.0, 70.0, 30.0);
[doneButton addTarget:self action:@selector(doneButtonPressed) forControlEvents:UIControlEventTouchUpInside];
doneBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:myLocationButton];
self.navigationItem.leftBarButtonItem = doneBarButtonItem;
Solution: Adding the following line of code related to setting the UIButton layer's z-index solved the problem for me.
[doneButton.layer setZPosition:2];
Note
You need to include <QuartzCore/QuartzCore.h>
in order to use layer related properties/methods
精彩评论