使用 UIScrollView 用两根手指滚动

2022-01-12 00:00:00 iphone objective-c uiscrollview

我有一个应用程序,我的主视图同时接受 touchesBegantouchesMoved,因此接受单指触摸和拖动.我想实现一个 UIScrollView,我让它工作,但它覆盖了拖动,因此我的 contentView 永远不会收到它们.我想实现一个 UIScrollview,其中两指拖动表示滚动,而单指拖动事件会传递给我的内容视图,因此它可以正常执行.我需要创建自己的 UIScrollView 子类吗?

I have an app where my main view accepts both touchesBegan and touchesMoved, and therefore takes in single finger touches, and drags. I want to implement a UIScrollView, and I have it working, but it overrides the drags, and therefore my contentView never receives them. I'd like to implement a UIScrollview, where a two finger drag indicates a scroll, and a one finger drag event gets passed to my content view, so it performs normally. Do I need create my own subclass of UIScrollView?

这是我实现 UIScrollViewappDelegate 中的代码.

Here's my code from my appDelegate where I implement the UIScrollView.

@implementation MusicGridAppDelegate

@synthesize window;
@synthesize viewController;
@synthesize scrollView;


- (void)applicationDidFinishLaunching:(UIApplication *)application {    

    // Override point for customization after app launch    
    //[application setStatusBarHidden:YES animated:NO];
    //[window addSubview:viewController.view];

    scrollView.contentSize = CGSizeMake(720, 480);
    scrollView.showsHorizontalScrollIndicator = YES;
    scrollView.showsVerticalScrollIndicator = YES;
    scrollView.delegate = self;
    [scrollView addSubview:viewController.view];
    [window makeKeyAndVisible];
}


- (void)dealloc {
    [viewController release];
    [scrollView release];
    [window release];
    [super dealloc];
}

推荐答案

你需要继承 UIScrollView(当然!).然后你需要:

You need to subclass UIScrollView (of course!). Then you need to:

  • 制作单指事件以转到您的内容视图(简单),并且

  • make single-finger events to go to your content view (easy), and

让两指事件滚动滚动视图(可能容易,可能很难,可能不可能).

make two-finger events scroll the scroll view (may be easy, may be hard, may be impossible).

Patrick 的建议通常很好:让您的 UIScrollView 子类了解您的内容视图,然后在触摸事件处理程序中检查手指的数量并相应地转发事件.只需确保 (1) 您发送到内容视图的事件不会通过响应者链返回到 UIScrollView(即确保处理所有事件),(2) 尊重通常的触摸事件流(即 touchesBegan,而不是一些 {touchesBegan, touchesMoved, touchesEnded},以 touchesEnded 或 touchesCancelled 结束),尤其是在处理 UIScrollView 时.#2 可能很棘手.

Patrick's suggestion is generally fine: let your UIScrollView subclass know about your content view, then in touch event handlers check the number of fingers and forward the event accordingly. Just be sure that (1) the events you send to content view don't bubble back to UIScrollView through the responder chain (i.e. make sure to handle them all), (2) respect the usual flow of touch events (i.e. touchesBegan, than some number of {touchesBegan, touchesMoved, touchesEnded}, finished with touchesEnded or touchesCancelled), especially when dealing with UIScrollView. #2 can be tricky.

如果您决定事件是针对 UIScrollView,另一个技巧是让 UIScrollView 相信您的两指手势实际上是单指手势(因为 UIScrollView 不能用两根手指滚动).尝试只将一根手指的数据传递给 super(通过过滤 (NSSet *)touches 参数——注意它只包含更改的触摸——并完全忽略错误手指的事件).

If you decide the event is for UIScrollView, another trick is to make UIScrollView believe your two-finger gesture is actually a one-finger gesture (because UIScrollView cannot be scrolled with two fingers). Try passing only the data for one finger to super (by filtering the (NSSet *)touches argument — note that it only contains the changed touches — and ignoring events for the wrong finger altogether).

如果这不起作用,你就有麻烦了.从理论上讲,您可以尝试通过创建一个看起来类似于 UITouch 的类来创建人工触摸以提供给 UIScrollView.底层 C 代码不检查类型,因此将 (YourTouch *) 转换为 (UITouch *) 可能会起作用,并且您将能够欺骗 UIScrollView 处理实际上并没有发生的触摸.

If that does not work, you are in trouble. Theoretically you can try to create artificial touches to feed to UIScrollView by creating a class that looks similar to UITouch. Underlying C code does not check types, so maybe casting (YourTouch *) into (UITouch *) will work, and you will be able to trick UIScrollView into handling the touches that did not really happen.

您可能想阅读 我关于高级 UIScrollView 技巧的文章(并完全看一些不相关的 UIScrollView 示例代码在那里).

You probably want to read my article on advanced UIScrollView tricks (and see some totally unrelated UIScrollView sample code there).

当然,如果你不能让它工作,总是可以选择手动控制 UIScrollView 的移动,或者使用完全自定义编写的滚动视图.Three20 库中有 TTScrollView 类;用户感觉不好,但程序员感觉不错.

Of course, if you can't get it to work, there's always an option of either controlling UIScrollView's movement manually, or use an entirely custom-written scroll view. There's TTScrollView class in Three20 library; it does not feel good to the user, but does feel good to programmer.

相关文章