Subclass UINavigationBar and override- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
such that it returns NO
for the rect where the view you want to receive touches is and YES
otherwise.
For example:
UINavigationBar subclass .h:
@property (nonatomic, strong) NSMutableArray *viewsToIgnoreTouchesFor;
UINavigationBar subclass .m:
- (NSMutableArray *)viewsToIgnoreTouchesFor
{
if (!_viewsToIgnoreTouchesFor) {
_viewsToIgnoreTouchesFor = [@[] mutableCopy];
}
return _viewsToIgnoreTouchesFor;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL pointInSide = [super pointInside:point withEvent:event];
for (UIView *view in self.viewsToIgnoreTouchesFor) {
CGPoint convertedPoint = [view convertPoint:point fromView:self];
if ([view pointInside:convertedPoint withEvent:event]) {
pointInSide = NO;
break;
}
}
return pointInSide;
}
In your fullscreen viewController where you have the view behind the navBar add these lines to viewDidLoad
UINavigationBarSubclass *navBar =
(UINavigationBarSubclass*)self.navigationController.navigationBar;
[navBar.viewsToIgnoreTouchesFor addObject:self.buttonBehindBar];
Please note: This will not send touches to the navigationBar, meaning if you add a view which is behind buttons on the navBar the buttons on the navBar will not receive touches.
Swift:
var viewsToIgnore = [UIView]()
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let ignore = viewsToIgnore.first {
let converted = $0.convert(point, from: self)
return $0.point(inside: converted, with: event)
}
return ignore == nil && super.point(inside: point, with: event)
}
See the documentation for more info on pointInside:withEvent:
Also if pointInside:withEvent:
does not work how you want, it might be worth trying the code above in hitTest:withEvent:
instead.