【问题标题】:Prevent UIScrollView to scroll unless it was touched near edges防止 UIScrollView 滚动,除非它在边缘附近被触摸
【发布时间】:2011-04-07 18:36:03
【问题描述】:
我有以下情况:一个 UIScrollView 包含一个 UIWebView。我希望 web 视图中的内容是可触摸的,但滚动视图不应滚动,除非它在左边缘或右边缘附近被触摸。我已经继承了 UIScrollView 和 UIWebView 来尝试覆盖 hitTest 和 pointInside 这样的方法,但到目前为止还没有。
我唯一的部分成功是在我的 UIScrollView 中覆盖 pointInside,如果该点不在边缘附近,则返回 NO。然后 UIScrollView 停止滚动,但没有触摸发送到 UIWebView。
【问题讨论】:
标签:
iphone
objective-c
cocoa-touch
ipad
uiscrollview
【解决方案1】:
首先,您不应该继承UIWebView,因为documentation 特别不鼓励这种做法。您可以通过继承其他类来拦截触摸事件,例如UIWindow,或者在您的情况下为UIScrollView。
查看this article,它演示了如何检测UIWebView 上的触摸事件。我采用了类似但略有不同的方法:我将包含UIWebView(和其他控件)的UIView 子类化,并覆盖hitTest:withEvent: 方法。
【解决方案2】:
您可以照常做,并覆盖 pointInside。获取点和事件,然后手动调用 webView touchesEnded 事件,并将您创建的 NSSet touches 对象与事件一起传递。
然后您的 webview 可以对此采取行动。
【解决方案3】:
可能你可以通过使用 UIScrollView 然后在其中添加一个 UIView 然后在 UIView 中添加 UIWebView 来完成。
【解决方案4】:
查看来自苹果的 scrollviewsuite 示例代码。 (点击检测视图)
在滚动视图上接收任何触摸事件的想法是在其上添加一个自定义 uiview 并在那里获得点击。至于滚动,您应该可以使用滚动视图委托功能,如果(在您的示例中)触摸不对应于开始滚动的所需位置,您可以取消滚动。至于顶部的webview..你可以处理它..
PS。你的这个想法与滚动视图和顶部的 web 视图和触摸......它不是那么用户友好.. 也许你应该重新考虑。
干杯。
【解决方案5】:
我不在我的mac前,所以这必须用伪代码来完成。
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
{
NSRect noScroll = NSMakeRect(10,10,300,460); // No-Touch Zone
NSSet *allTouches = [event allTouches];
UITouch *touch = [[allTouches allObjects] objectAtIndex:0];
CGPoint point = [touch locationInView:[self view];
if (! NSPointInRect( NSPoint aPoint, NSRect aRect ))
{
// Point is NOT within the "No-Touch Zone" Proceed with Execution.
}
}
这部分是我从 iphonesdkarticles.com 偷来的。那么这个方法去哪里了......我认为在 ViewController 中?您不必使用此方法对任何内容进行子类化。
【解决方案6】:
这就是我所做的:
static const float kEdgeScrollViewMargin = 8;
@implementation EdgeScrollView
- (BOOL)touchesShouldBegin:(NSSet *)aTouches
withEvent:(UIEvent *)aEvent
inContentView:(UIView *)aView
{
if([aTouches count] == 1) {
CGPoint const touchLoc = [[aTouches anyObject] locationInView:self];
float const edgeDistance = MIN(touchLoc.x - self.contentOffset.x,
self.bounds.size.width - (touchLoc.x - self.contentOffset.x));
if(edgeDistance <= kEdgeScrollViewMargin)
return NO;
}
return YES;
}
@end