In one of my view controllers I have a carousel that the user can swiper through.
But if the user swipes up in the top left hand corner of the screen they can drag back the previous view controller.
How can I stop this? It could be something to do with this?
- (void) viewWillDisappear:(BOOL)animated
{
[self.carousel setHidden:YES];
}
- (void) viewWillAppear:(BOOL)animated
{
[self.carousel setHidden:NO];
}
https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html#//apple_ref/occ/instp/UINavigationController/interactivePopGestureRecognizer
Set the interactivePopGestureRecognizer's enabled property to NO on your UINavigationController
Related
Scenario
I have an app with a navigation controller. When the navigation controller pushes another controller onto the stack, in the upper left corner of the screen it shows the back button "<(title of the last view controller)".
What I need
I need something like (pseudo code)...
-(void)detectedBackButtonWasPushed {
NSLog(#"Back Button Pressed");
//Do what I need done
}
Question
Because this button is created by the navigation controller and I did not create this button in storyboards, how do I get the back button 'hooked up' to a method like this?
examples of what Ive tried for Oleg
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"notification"];
if (viewController == vc) {
NSLog(#"BACK BUTTON PRESSED");
}
}
Is this how I'm supposed to do it? Cause this doesn't work.
Use viewWillDisappear to detect this.
-(void) viewWillDisappear:(BOOL)animated
{
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
{
[self backButtonPressed];
[self.navigationController popViewControllerAnimated:NO];
}
[super viewWillDisappear:animated];
}
-(void)backButtonPressed
{
NSLog(#"YEA");
}
Previously, I have solved this by setting the navigationBar leftItem to be a back button with a custom selector that dismisses the view along with whatever else it needed to do.
I might also suggest looking at the back button item and adding a target:self that is called on touch.
I have a UINavigationBar that intercepts the back button tap that alerts the user if there are unsave changes. This is based on the solution presented in UINavigationController and UINavigationBarDelegate.ShouldPopItem() with MonoTouch using the UINavigationBarDelegate protocol and implementing - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;
Now, iOS7 has introduced the swipe-to-go-back gesture, and I'd like to intercept that as well, but can't get it to work with the solutions I've found so far, namely using [self.interactivePopGestureRecognizer addTarget:self action:#selector(handlePopGesture:)]; and
- (void)handlePopGesture:(UIGestureRecognizer *)gesture {
if (gesture.state == UIGestureRecognizerStateEnded) {
[self popViewControllerAnimated:NO];
}
}
While this does pop the views, it leaves the navigation bar buttons in place, so I'm ending up with a back button that leads nowhere, as well as all other navigation button I've added to the nav bar. Any tips?
To intercept the back swipe gesture you can set self as the delegate of the gesture (<UIGestureRecognizerDelegate>) and then return YES or NO from gestureRecognizerShouldBegin based on unsaved changes:
// in viewDidLoad
self.navigationController.interactivePopGestureRecognizer.delegate = self;
// ...
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
if (self.dirty) {
// ... alert
return NO;
} else
return YES;
} else
return YES;
}
In the alert you can ask to the user if she want to go back anyway and, in that case, pop the controller in alertView clickedButtonAtIndex:
Hope this is of some help.
I have a view with a custom bar at the bottom of the screen. When a collection view cell is pressed, it loads a detail view, and I can go back.
This all works great; however, I have a plus button displayed on the custom bar, and I would like for the plus button to disappear only when the detail view shows up, and then come back when you hit the back button.
So far I have used the delegate method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// Your code to update the parent view
}
The problem is this fires when the detail view is loaded and popped as well. Any idea on how to accomplish this? Thanks!
I assume mainView and detailView are viewControllers. In mainView's viewWillAppear method
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//get reference of plus button here
btnPlus.hidden = NO;
}
In detailView's viewWillAppear method
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
//get reference of plus button here
btnPlus.hidden = YES;
}
My keyboard appears with a textView, I want to hide it when the user push on a back button on a navigation bar.
I have tried this:
-(void)viewWillDisappear:(BOOL)animated{
[myTextView resignFirstResponder];
}
and this:
-(void)viewDidDisappear:(BOOL)animated{
[myTextView resignFirstResponder];
}
But it doesn't work, how can I do this?
edit:
I found the solution here:
iPad keyboard will not dismiss if modal ViewController presentation style is UIModalPresentationFormSheet
Put this into the buttonPress method -
[self.view.window endEditing:YES];
Edit - this also lets you get the contents of the text being edited when the "back" button is pressed
Combining the above answers and checking for back button will be done by this
- (void)viewWillDisappear:(BOOL)animated{
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
[self.view.window endEditing:YES];
}
[super viewWillDisappear:animated];
}
Hi there, Now I'm trying to create a Pop-OverView using an Xcode
storyboard. Firstly, I have
rootViewController, UIViewController, and UITableViewController
I want the UIView to act as a page flip and the UITableView will show popOver under the navigationBar item controller.
For the UITableView, I want to make a Pop-Over under NavigationBar controller. The problem is, when I touch the Navigation item to show the UITableViewController, it shows correctly, but when I try to close the Pop-Over View, it won't close. And then, the navigation item doesn't work well. It shows multiple instances of popOverView when I touch it multiple times.
This doesn't seem to make sense to me. Can anyone help me out or tell me where to find documentation / tutorials on this?
UPDATE:
For the UIPopOverController, it seems to work well now, but it is still bugging me when I touch a Navigation Item multiple times. It will show multiple instances of PopOver. How can I handle it, so it will show only one instance?
I had the same problem and mostly found the solution here. Basically you change the action of the button each time it's pressed to either display or dismiss the popover. Here's the code I ended up with:
#interface FilterTableViewController : UITableViewController {
UIPopoverController *editPopover;
id saveEditSender;
id saveEditTarget;
SEL saveEditAction;
}
-(void)prepareForSegue:(UIStoryboardPopoverSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"EditFilterSegue"]){
// Save the edit button's info so we can restore it
saveEditAction = [sender action];
saveEditTarget = [sender target];
saveEditSender = sender;
// Change the edit button's target to us, and its action to dismiss the popover
[sender setAction:#selector(dismissPopover:)];
[sender setTarget:self];
// Save the popover controller and set ourselves as the its delegate so we can
// restore the button action when this popover is dismissed (this happens when the popover
// is dismissed by tapping outside the view, not by tapping the edit button again)
editPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
editPopover.delegate = (id <UIPopoverControllerDelegate>)self;
}
}
-(void)dismissPopover:(id)sender
{
// Restore the buttons actions before we dismiss the popover
[saveEditSender setAction:saveEditAction];
[saveEditSender setTarget:saveEditTarget];
[editPopover dismissPopoverAnimated:YES];
}
-(BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
// A tap occurred outside of the popover.
// Restore the button actions before its dismissed.
[saveEditSender setAction:saveEditAction];
[saveEditSender setTarget:saveEditTarget];
return YES;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// Before we navigate away from this view (the back button was pressed)
// remove the edit popover (if it exists).
[self dismissPopover:saveEditSender];
}