我在UIScrollView中有一个UIControl。在我的UIControl init
中,我安装了一些触摸事件处理程序,例如
[self addTarget:_delegate
action:@selector(touchedDown) forControlEvents:UIControlEventTouchDown];
当我执行以下操作时,iOS6 和 iOS7 的行为不同:
- 滑动 UIScrollView 以开始滚动
- 点击 UIScrollView 以停止滚动
在 iOS6 中,我的应用程序继续按预期运行:步骤 #2 中的点击不会调用touchedDown
- UIScrollView 会立即停止滚动时吞下触摸事件。
但在 iOS7 中,UIScrollView 会按预期停止滚动,而 touchedDown
仍被调用。
是否有记录在案的 API 更改?我希望我的应用程序的行为与 iOS6 中的 iOS7 相同。
iOS 7 的解决方法
@interface UIScrollViewFixed : UIScrollView
@end
@implementation UIScrollViewFixed
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if (self.isDragging || self.isDecelerating) {
return self;
}
return [super hitTest:point withEvent:event];
}
@end
只需替换事件类型
UIControlEventTouchDown
必须UIControlEventTouchUpInside
不是很优雅,但在没有任何更好的想法的情况下,这就是现在对我有用的东西:
- 在 UIScrollView 上,将
canCancelContentTouches
设置为YES
,delaysContentTouches
设置为NO
。 - 在 UIScrollViewDelegate 中,在 UIScrollView 滚动时切换 UIScrollView 的子视图的
userInteractionEnabled
属性:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[_contentView setUserInteractionEnabled:NO];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[_contentView setUserInteractionEnabled:YES];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[_contentView setUserInteractionEnabled:YES];
}
- 子类化 UIScrollView 并实现:
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
return YES;
}
- 子类化 UIControl 并实现
touchesCancelled:withEvent
以反转UIControlEventTouchDown
处理程序执行的任何操作:
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
//custom logic
}
UIScrollView 上的 UIButtons 也是如此。这是我现在的解决方案。
而不是使用内容 UIControlEventTouchDown 事件:
[button addTarget:_delegate
action:@selector(touchedDown) forControlEvents:UIControlEventTouchDown];
我在我的内容UIViewController中实现了UIResponder touchesEnd方法:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
// my scroll content touch logic
}
如果用户触摸内容并开始拖动触摸,则不会调用已结束处理程序。UIResponder touchesCanceled 方法将。
如果用户不拖动 UIscrollview,则会触发 touchesEnd 处理程序,该处理程序可用于触摸逻辑。