I need to resignFirstResponder() on a text field when the user taps the back button in the navigation bar of the navigation controller, otherwise I get some error. The back button works as it should (the previous view gets shown) but I don't know where to do resign first responder. It's too late if I do it in viewWillDisappear() (I tried), and prepareForSegue() doesn't get called, so I need to somehow do it as soon as the back button gets tapped or at least before viewWillDisappear(). How do I detect that event?
Note: See first comment on question for simpler answer
You could combine NotificationCenterand this post: Execute action when back bar button of UINavigationController is pressed to make a custom back button (that looks the same). Just post a Notification in the action for the back button, and add an observer for the Notification on the textfield whose action calls resignFirstResponder. You would also need to make an image or draw an image in CoreGraphics for the arrow.
Related
On the iPhone in Landscape orientation, there is a button in the lower right corner that causes the keyboard to dismiss. I really don't want this button to be there, since I have a Done button already and users should only be able to stop editing the textfield by pressing this Done button (which has to be there to address portrait orientation anyway).
I'm wondering if there's a way to remove that keyboard dismissal button, or if not, I'd appreciate any suggestions for UITextField delegate behavior that differentiates between proper dismissal (Done button pressed) and improper (first responder might resign even though Done button not pressed, e.g. because of aforementioned problem button or view controller dismissal).
One thing you can do is declare a variable, something like, isDismissedProperly and initiate it to false. Then subscribe to keyboard show and hide notifications. UIKeyboardDidShowNotification and UIKeyboardDidHideNotification. In the target method for done button(as mentioned in the question), change the isDismissedProperly to true. And in the keyboardDidHide method, you can check if isDismissedProperly is true or false.
If it's true, then user dismissed the keyboard by pressing done button.
Hope it helps!
I have an app that has a toolbar, but I don't want the bar at the top, in order to free more viewing space. Therefore I have decided not to use a navigation controller. I'd like to add a back button to the toolbar. How would I go about this?
Adding the button is easy enough, and setting the action to performSegueWithIdentifier is all fine, but what happens is that the previous view just gets loaded again, rather than show it as it was, like a true back button. So if I tap on the 10th row on a tableView and go to a new page, when I press the back button it loads the view from the top again, instead of showing it as where I scrolled down to last.
Even though you don't want a UINavigationBar, you do want a UINavigationController in this case, because it manages the 'back stack' exactly the way you want it. Just hide its navigation bar by setting its navigationBarHidden property to true (in the Storyboard or in the viewDidLoad function of the root view controller).
You can then use navigationController.popViewController(true) as normal, in response to the user clicking your custom back button.
I know that a push segue automatically adds a back button so that the presentee can return to the presenter on click. What I want is for the back button to be available on the first UIViewController of the NavigationController (basically the only view controller in the chain that does not have a back button). How do I force add the back button?
I cannot simply add a custom image because I want the exact same chevron that comes with the iOS back button.
The easiest (yet hackish) way to achieve this is probably adding a dummy view controller in the stack before the actual first one, so you will get a proper back button. Use dummy's backBarButtonItem to customize the button title if you need, and -viewWillAppear: to respond to the button being tapped.
What I want is for the back button to be available on the first UIViewController .... How do I force add the back button
This whole thinking and logic is wrong. This is not how iOS UINavigationControllers work. You have a starting page (mainViewController) in a UINavigationControllers and from there you "move on" to something else. But you always come back to the main view controller. Just think about it, if you put a back button on the main view controller, where will the user go back to?
If you have a situation like this.
SomeViewController --> UINavigationController --> MainViewController
Once user is on SomeViewController and you take him to MainViewController which is part of UINavigationController then back button makes sense.
Just a FYI - you can easily drag and drop a UIBarButtonItem to any UINavigationController in Xcode and call it "Back". You will have to then connect that back button to another view controller.
Maybe it doesn't make sense but why can't you add a custom image? If all you want is "Back" chevron, can't you take a screenshot of this button and then put this image on your custom UIBarButtonItem?
I wanna change the back button text after the child view is already pushed in not before pushing it in.
More specifically, I'm developing an chatting app that shows unread messages count in the back button like this "<- Chats (3)". So I need to update the button text whenever the new message arrives.
After some digging it, I found that changing the title of the parent view eventually changes
the back button text. But there is a redraw delay problem. It takes about 5 seconds until the back button is redrew after I changed the title.
In short, I'd like to know
How to redraw the back button immediately after I changed the parent's title.
or, better way to change the back button text after the button shows.
Any idea?
I don't know how you're doing this now, but putting this in a button method changed the back button title immediately:
-(IBAction)changeTitle:(id)sender {
[self.navigationController.viewControllers[self.navigationController.viewControllers.count -2] setTitle:#"New"];
}
I have a UITableView within an UINavigationController. On the right of the UINavigationBar I have an "Edit" button. When I tap this button, all the textfields in the table cells become activated so I can edit them. The right button changes to "Save".
I'd now like the left "back" button of the UINavigationController to be replaced by a "Cancel" button which when I tap doesn't bring me back to the previous UIViewController, but just cancels editing mode.
When I tap "Save" the "Cancel" button should be changed back to the usual UINavigationController back button. Is there any easy way to do this? I tried accessing [[self navigationItem] leftBarButtonItem]. This works for the right button, but not the left one.
Set the leftBarButtonItem to your Cancel button. At the appropriate time, set the leftBarButtonItem to nil to remove your Cancel button. This will automatically restore the original back button that was in place before you added the Cancel button.
It sounds like the leftBarButtonItem is a "BackButton", which is set on the UIView(Controller) you used to navigate to the current View.
You can hide the BackButton following the answer in this question. This should be done, since you cannot change it's behavior.
I believe you are then able to use the leftBarButtonItem.
See this other SO question.
Then make sure you declare the cancel method similar to this.
(void)cancel:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}