I have two UITableViewControllers that are connected via a Show segue. The prompt property of UINavigationItem is set on both view controllers in Interface Builder. When the first view controller is shown, the prompt and navigation bar are both displayed properly, however, when performing a segue to the second view controller, the title and the back button animate undesirably. I have tried setting the prompts programmatically in the viewWillLayoutSubviews, viewDidLayoutSubviews, viewDidLoad, viewWillAppear:, and the viewDidAppear: methods of both view controllers, but I get the same effect.
Any ideas on how to resolve this issue? I don't want to resort to a custom view for the titleView because I prefer the stock functionality, but I am not able to figure out how to fix the undesirable animation.
Here is a video if the animation in question.
Well, it looks like this is an issue with the way that the UINavigationItem is laid out when showing the next view controller.
According to Catalina T. in an answer to a similar question, making two calls to set the hidden property of the navigation bar to true and then again to false in viewWillAppear: seems to get by this issue.
Related
I am wondering the following:
What is the best way to set up a searchbar that is available in all child view controllers of the navigation controller on the ipad (Hence in the entire application in my case).
A perfect example in which this is done is the IMDB application on the iPad, where each view controller with its presented views shows a search bar in the navigation bar that uses the same datasource.
I found the following post on this topic: Same UISearchBar for entire app?
However,I am not completely satisfied with the answer yet. I would like to know whether it is possible to show it in the navigation bar everywhere using either the function:
[self.navigationItem setTitleView:mySearchBar];
or:
[self.navigationItem setTitleView:mySearchBar];
searchDisplayController.displaysSearchBarInNavigationBar = YES;
at a specific location, hence not in each view controller. I thought of adding the search bar in the prepareforsegue function every time, but there must be a more convenient and nicer way.
Also, if you would suggest to work with container view controllers, how would this work with other navigation items? Can one adjust the size of the view UIsearchbar when more navigation bar items (buttons) are presented for a certain view controller?
This question came closest to describing my problem, but I'm missing something in the general process and the answer eventually goes into "Never mind, I figured out a different solution that isn't described".
In my case, I've got an XIB with a navigation bar and its controller. For the class fields, I've filled in my custom class names. Here's a screenshot showing the XIB, because I think this should be a relatively simple and straightforward setup...
What I want (like in link at the beginning) is for the touchesEnded event to fire so that I can do something. This works for the "view"; I can programmatically write in the event, set a breakpoint, and see that breakpoint get hit. However, my higher-level goal is to push a new view onto the app at that point -- something that I shouldn't do in the view's functionality, and which I can't do anyway because my view doesn't have access to the navigation controller (unless I do some trickery to retrieve the controller, but I want to do this cleanly).
Even though it works programmatically for the view, the touchesEnded event does not get hit for the navigation view's controller. I set it to the delegate, as shown in the image below, which I'm suspecting is perhaps only a part of what I need to do.
So now that I've set the delegate, and have seen that the touchesEnded event is being hit by the view, why isn't my navigation bar view controller picking up on the touchesEnded event? Am I mistaken and should instead be figuring out how to push a new view from the navigation bar's view, since I've seen that THAT touchesEnded event is being hit? It just seems like something I should be handling in the navigation bar view's controller, but I can't get that controller's touchesEnded event hit.
Thanks!
It's not clear from your post, but it looks like you're adding a navigation bar to your app explicitly, is that true? If your controller is embedded in a navigation controller, then there's no need to do that. You can add a view to the navigation bar, and add a UIImage view as a subview. If you set user interaction to be on, and add a tap gesture recognizer to the image view, you should be able to get the effect you want.
Then you have to override UINavigationBar, and override becomeFirstResponder, returning YES.
Is there a way to use custom segues to individually animate several different subviews.
For example, I want my modal view to appear by the UINavigationBar fading in (as the source destination's UINavigationBar fades out) and then a UITableView to slide down the screen 'over' the source destination's view controller.
When I try to implement this in the - (void)perform method. My properties don't animate using [UIView animateWithDuration: animations: completion:].
Can anyone provide me with a solution?
Thanks in advance!
You can certainly use custom segues to achieve this - however, I don't think you'll get much help without more details about the setup of your view controllers.
Everything you describe is correct: to create a custom segue you animate the views inside your sourceViewController and destinationViewController inside the segue's perform: method. If they're not animating you might want to check that your segue is actually getting called (you can use breakpoints in the debugger to check this), or that the views you're trying to access inside your view controllers actually exist at that point in time (again, something you can check using the debugger).
For a solution specific to your app you're almost certainly going to have to provide more details about the two view controllers you're trying to transition between. Perhaps you could post your perform: method.
Hi there and thank you in advice for your help. I have a really strange problem while working with ViewControllers in Xcode4. First of all I have to say that I'm not using storyboards and I prefer to create any UI element programmatically. So I've set a UIButton and I want that, when pressed, it brings me to a new view controller. This is the code I'm using for a button:
-(void)settingsAndExportHandle:(UIButton *)buttonSender {
SettingsViewController* settingView = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
settingView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:settingView animated:YES];
}
This buttons is initialized and allocated in the viewDidLoad method of the RootViewController. I want to switch to the other view controller (in this case SettingsViewController) when I press the button.
The strange thing is that when I press the button, the animation that flips the controllers goes well, but when it finishes I obtain the EXACT same things that I had on the RootViewControllers (same custom views, same buttons, same all!). The question is: what I'm missing?? I have to say that I use ARC (automatic reference counting) so I can't release or dealloc the views and buttons I've created on my RootViewController.
Any help will be appreciated. Thank you all!
Pushing and and modally presenting view controllers does not deallocate the view controller that presented them. It simply adds the additional view controller to the stack. You'll need to implement a callback method so that when the user hits the button to flip back to root view controller, your settings view controller lets the root view controller know what's about to happen so you can call a method you've written to reset the interface back to whatever state you need it at. You may also be able to use viewWillAppear: but that's a little messy.
However, according to the Apple Human Interface Guidelines, the user expects that when they push a view controller or modally present it, the view controller they were on will save state and be exactly the way they left it when they came back. It's disconcerting and annoying when state is not preserved while in a navigation controller context. It is especially annoying when it's modally presented.
Think about this - A user is in a hypothetical Mail app. They start typing out an email and set a font size and a color. They tap on the add attachment button, which brings up a modal view controller that allows them to select a picture. They select the picture and the modal view is dismissed, and in your implementation, the mail composing interface would have reset and the email content would be gone or at the very least the selected font size and color would be back to the default. That's not a good experience.
I was looking to implement something like the image below, and really have no idea how it's done and was wondering if someone had a quick design idea (no code is necessary or anything). Is it a footer view for the table view? is it some unknown footer view for a popover controller? Is it some way to integrate a toolbar from the UINavigationController 'into' the popover? I guess I could always create a custom view and display it 'like' a popover. Thanks for any help.
UIPopoverController will actually do a lot of that for you. If you set its content view controller to a UINavigationController, the contents of that navigation controller’s current view controller’s navigation item will display embedded in the top of the popover. I believe setting the view controller’s (not the navigation controller’s) toolbarItems will have the same effect at the bottom.
In this case, it looks like they wrote a custom popover controller; it doesn’t have an arrow attached, and the top of it is shaded a little differently from the standard UIPopoverController. But I’m pretty sure you can use the methods I just described to achieve a similar effect without having to roll your own popover.