UINavigationBar 中的点击事件被手势识别器覆盖
首先的问题是:
当你有一个 tableView 时,如何实现用户可以点击导航栏一直滚动到顶部。
解决方案:
- (void)viewDidLoad {
UITapGestureRecognizer* tapRecon = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(navigationBarDoubleTap:)];
tapRecon.numberOfTapsRequired = 2;
[navController.navigationBar addGestureRecognizer:tapRecon];
[tapRecon release];
}
- (void)navigationBarDoubleTap:(UIGestureRecognizer*)recognizer {
[tableView setContentOffset:CGPointMake(0,0) animated:YES];
}
这就像一个魅力!
但 Drarok 指出了一个问题:
只有当您没有后退按钮或 rightBarButtonItem 时,这种方法才可行。他们的点击事件被手势识别器覆盖
我的问题:
我怎样才能拥有我的导航栏可点击的好功能,但仍然能够使用我的应用程序中的后退按钮?
因此,要么找到一个不覆盖后退按钮的不同解决方案,要么找到一个让后退按钮重新恢复工作的解决方案:)
The question in the first place was:
When you have a tableView how to implement that the user can tap the NavigationBar to scroll all the way to the top.
Solution:
- (void)viewDidLoad {
UITapGestureRecognizer* tapRecon = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(navigationBarDoubleTap:)];
tapRecon.numberOfTapsRequired = 2;
[navController.navigationBar addGestureRecognizer:tapRecon];
[tapRecon release];
}
- (void)navigationBarDoubleTap:(UIGestureRecognizer*)recognizer {
[tableView setContentOffset:CGPointMake(0,0) animated:YES];
}
Which works like a charm!
But Drarok pointed out an issue:
This approach is only viable if you don't have a back button, or rightBarButtonItem. Their click events are overridden by the gesture recognizer
My question:
How can I have the nice feature that my NavigationBar is clickable but still be able to use the back buttons in my app?
So either find a different solution that doesn't override the back button or find a solution to get the back button back to working again :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
iOS7 版本:
编辑:
后退按钮手势一角的某些内容仍然被覆盖,因此您可以将此代码插入
pointInside:withEvent
:iOS7 version:
EDIT:
Someting on the corner of back button gesture is still overwritten, so you this code insted of
pointInside:withEvent
:Xamarin.iOS 不会在私有 API 中公开 Objective-C 类的 C# 包装器,因此上面 @ben-flynn 建议的简洁子类检查在这里不起作用。
一个有点黑客的解决方法是检查视图的
Description
字段:尽管在视图层次结构中查找某些类型时,Linq 集合过滤器
.OfType
很方便。Xamarin.iOS does not expose C# wrappers for Objective-C classes in the private API, so the neat subclass checking suggested by @ben-flynn above won't work here.
A somewhat hackish workaround is to check the
Description
field of the views:The Linq collection filter
.OfType<T>
is convenient though when fishing for certain types in the view hierarchy.这对我有用,它基于 Stavash 的答案。我使用手势识别器的视图属性在委托方法中返回“是”/“否”。
这是一个旧的应用程序,所以显然这不是 ARC,不使用新的布局内容或 NSAttributed 字符串。我把这个留给你:p
然后你像往常一样使用手势识别器
This worked for me, It is based on Stavash answer. I use the view property of the gesture recognizer to return YES/NO in the delegate method.
It is an old app so obviously this is not ARC, does not use new layout stuff nor NSAttributed strings. I leave that to you :p
Then you use the gesture recogniser as usual
我没有使用位置视图,而是通过检查 UITouch 的类来解决这个问题。
请注意,导航按钮的类型为
UINavigationButton
,该类型未公开,因此需要进行子类检查。此方法位于您指定为手势识别器的委托的类中。如果您刚刚开始使用手势识别器,请注意委托与目标是分开设置的。
Rather than using location view, I solved this by checking the class of the UITouch.
Note that the nav buttons are of type
UINavigationButton
which is not exposed, hence the subclass checking.This method goes in the class you designate as the delegate of the gesture recognizer. If you're just getting started with gesture recognizers, note that the delegate is set separately from the target.
UIGestureRecognizerDelegate 有一个名为“gestureRecognizer:shouldReceiveTouch”的方法。如果您能够指出触摸的视图是否是按钮,则只需使其返回“NO”,否则返回“YES”即可。
UIGestureRecognizerDelegate has a method called "gestureRecognizer:shouldReceiveTouch". If you are able to point out if the touch's view is the button, just make it return "NO", otherwise return "YES" and you're good to go.
UIGestureRecognizer
还有一个属性@property(nonatomic) BOOL cancelsTouchesInView
。来自文档:一个布尔值,影响识别手势时是否将触摸传递到视图。
因此,如果您只是这样做,
这可能是一个更简单的解决方案,具体取决于您的用例。这就是我在我的应用程序中执行此操作的方式。
当按下导航栏中的按钮时,它的操作会被执行(根据需要),但
UIGestureRecognizer
的操作也会被执行。如果这不打扰您,那么这将是我能想到的最简单的解决方案。UIGestureRecognizer
also has an attribute@property(nonatomic) BOOL cancelsTouchesInView
. From the documentation:A Boolean value affecting whether touches are delivered to a view when a gesture is recognized.
So if you simply do
this might be an even simpler solution, depending on your use case. This is how I do it in my app.
When pressing a button in the navigation bar though, its action is executed (as desired), but the
UIGestureRecognizer
's action is executed as well. If that doesn't bother you, then that would be the simplest solution I could think of.