UINavigationBar Touch

前端 未结 9 1274
北恋
北恋 2020-12-23 17:53

I would like to fire an event on touch when a user taps the title of the navigation bar of one of my views.

I\'m at a bit of a loss on whether I can access the view

9条回答
  •  北海茫月
    2020-12-23 18:08

    I didn't want to specify a button as a custom titleView because that would mean I can't use the standard title anymore. On the other hand, when adding a tap gesture recognizer to the navigation bar, we have to make sure that it doesn't fire when tapping a bar button.

    This solution accomplishes both (to be added to a UINavigationBar subclass):

    - (void)awakeFromNib {
        // put in -initWithFrame: if initialized manually
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(ft_titleTapped:)];
        [self addGestureRecognizer:tap];
    }
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
        UIView *titleView = [self valueForKey:@"titleView"];
        CGRect titleFrame = titleView.frame;
        titleFrame.origin.y = 0; // expand to full height of navBar
        titleFrame.size.height = self.frame.size.height;
        return CGRectContainsPoint(titleFrame, [gestureRecognizer locationInView:self]);
    }
    
    - (void)ft_titleTapped:(UITapGestureRecognizer*)sender {
        if (sender.state == UIGestureRecognizerStateEnded) {
            // could add some checks here that the delegate is indeed a navigation controller
            UIViewController *viewController = (id)[((UINavigationController*)self.delegate) topViewController];
            if ([viewController respondsToSelector:@selector(titleViewTapped:)]) {
                [viewController titleViewTapped:self];
            }
        }
    }
    

    It automatically sends a -titleViewTapped: message to the view controller (if implemented). In a UITableViewController subclass you could implement the method like this for a scroll to top feature:

    - (void)titleViewTapped:(id)sender {
        [self.tableView setContentOffset:CGPointMake(0, -self.tableView.contentInset.top) animated:YES];
    }
    

    Caution: we're retrieving the title view using the undocumented -valueForKey:@"titleView". It's technically not using a private API but might still fail in a future iOS version!

提交回复
热议问题