来自UIScrollview的视图的前瞻性和手势

时间:2013-11-01 08:57:43

标签: ios objective-c uiscrollview

我在转发手势和触摸方面遇到了一些麻烦。我玩了很多,但我不能按照我想要的方式工作。

基本上我想用2个手指控制双屏幕上的滚动视图,然后将其他所有内容转发到覆盖滚动视图后面的ipad视图。

为了能够控制双屏幕上的滚动视图,我将其子类化为UIScrollView,并将其添加为具有清晰背景的覆盖视图到ipad屏幕。

然后我与一位代表联系起来,将其拖动和内容转发到双屏幕上的滚动视图。这很完美。

正如我写的那样,我希望scrollview只响应2个手指滚动,所以我把它设置为

ScrollView.panGestureRecognizer.minimumNumberOfTouches = 2;

但是,滚动视图会消除所有触摸,我不能正确地将所有其他内容转发到后面的视图中。 我认为压倒

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

必须要做的伎俩,但我没有正确地检测到屏幕上的手指数量。

4 个答案:

答案 0 :(得分:4)

我想分享/解释问题的解决方案。这就是说我也想指出,孵化输入使我朝着正确的方向发展。非常感谢你的配偶!

尝试将视图/滚动视图作为覆盖到玩家时的问题是该玩家不知道其“下一个响应者”。将视图/滚动视图作为底层视图将解决此问题。 您可能需要微调该底层滚动视图中任何滚动视图的触摸行为以获得正确的行为(如设置最大触摸次数)

解决方案是子类化UIScrollview,覆盖此方法 override the touchesBegan: and other touch methods as follows(请参阅user1085093 answer),并将其作为底层视图添加到ipad屏幕。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
if (!self.dragging){
    [self.nextResponder touchesBegan: touches withEvent:event];
}
else{
    [super touchesBegan: touches withEvent: event];
}}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
if (!self.dragging){
    [self.nextResponder touchesMoved: touches withEvent:event];
}
else{
    [super touchesMoved: touches withEvent: event];
}}


-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
if (!self.dragging){
    [self.nextResponder touchesEnded: touches withEvent:event];
}
else{
    [super touchesEnded: touches withEvent: event];
}}

我像这样设置了scrollview:

 TopLayerScrollView *newScrollView = [[TopLayerScrollView alloc] init];
[newScrollView setBackgroundColor:[UIColor clearColor]];
[newScrollView setFrame:self.tabBarController.view.frame];
[newScrollView setContentSize:dualScreenViewController.scrollContent.contentSize];
newScrollView.showsHorizontalScrollIndicator = NO;
newScrollView.showsVerticalScrollIndicator = NO;
newScrollView.delegate = self;
newScrollView.bounces = NO;
[newScrollView scrollsToTop];
newScrollView.panGestureRecognizer.minimumNumberOfTouches = 2;

self.topLayerScrollView = newScrollView;
[newScrollView release];

[self.tabBarController.view removeFromSuperview];
[topLayerScrollView addSubview:self.tabBarController.view];
[window addSubview:topLayerScrollView];
[topLayerScrollView bringSubviewToFront:self.tabBarController.view];

底层滚动视图的委托方法:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView.dragging || scrollView.tracking)
{
    [dualScreenViewControlleremphasized text.scrollContent setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y) animated:NO];
    self.tabBarController.view.frame = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, self.tabBarController.view.frame.size.width, self.tabBarController.view.frame.size.height);
}}

此解决方案效果很好。 另一种解决方案是将滚动视图作为我最初想要的重叠视图。如上所述问题是让toplayer视图知道视图(nextResponder)benath它。要实现此目的,您必须对UIScrollview进行子类化并创建一个UIResponder属性,您必须在接口构建器文件中或在运行时进行连接。这样,覆盖的scrollview将知道谁是下一个响应者。 please see morningstar's answer

答案 1 :(得分:2)

不幸的是,你不能在-pointInside:withEvent:做任何事情,因为在确定触摸是否满足手势识别器的要求之前,系统会决定触摸所在的视图(或触摸所在的视图)。

我认为你最好的选择是让当前在scrollview后面的视图实际上是scrollview的内容视图,并且每次滚动视图的内容偏移改变以保持它在同一视图中时移动该视图在屏幕上的位置。 (这听起来很昂贵,但事实并非如此。)因此,滚动视图更像是一个叠加层,而不是叠加层。

您可能还希望使用UIScrollView.delaysContentTouches-[UIScrollView touchesShouldBegin:withEvent:inContentView:]等来改善行为。

答案 2 :(得分:1)

更新Xcode 6.4,Swift 1.2:

我还将UIScrollView

分包了
import UIKit

class WBMScrollView: UIScrollView
{
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
    {
        self.nextResponder()?.touchesBegan(touches, withEvent: event)
        super.touchesBegan(touches, withEvent: event)
    }
}

在app main vc ViewController.swift中,我测试了它:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        println(" touches began")
    }

它有效。滚动视图已通过IB添加并连接到ViewController.swift

答案 3 :(得分:1)

使用我的应用程序,我需要将单指触摸事件转发到滚动视图的父视图控制器,同时仍允许滚动视图放大/缩小。

使用下一个响应者不起作用,因为我还添加了另一个重叠视图,最终成为下一个响应者并窃取触摸事件。我最后通过简单地传递父视图控制器并直接向其发送触摸事件来完成基于Tom的回答。这是在Swift:

class CustomScrollView: UIScrollView {

    var parentViewController: UIViewController?

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        parentViewController?.touchesBegan(touches, with: event)
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        parentViewController?.touchesMoved(touches, with: event)
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        parentViewController?.touchesEnded(touches, with: event)
    }
}