UIView子类没有收到touchesBegan,touchesEnded [英] UIView subclass not receiving touchesBegan, touchesEnded

查看:557
本文介绍了UIView子类没有收到touchesBegan,touchesEnded的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,所以我有一个应用程序的子类UIView,并依靠touchesBegan和touchesEnded。我指的是这些回调:

Ok- so I have an application which subclasses UIView, and relies on touchesBegan and touchesEnded. I refer of course to these callbacks:

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

我更新我的iOS从7到9只是在另一天(我知道,我很懒惰)发现触摸不工作。原来以上的功能没有得到调用在我的UIView子类。好奇,我开始一个空白的项目,这是足够短,我只是发布代码在这里。

I updated my iOS from 7 to 9 just the other day (I know, I'm lazy) to find that the touches aren't working. Turns out the above functions aren't getting called in my UIView subclass. Curious, I started a blank project, which is short enough that I'll just post the code here.

main.m:

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

这里是AppDelegate。动态创建窗口和视图。

Here's AppDelegate. Create a window and a view dynamically.

#import "AppDelegate.h"
#import "SubView.h"

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    //create a window and give it a frame. makeKeyAndVisible
    CGRect rect = [[UIScreen mainScreen] bounds];
    self.window = [[UIWindow alloc] initWithFrame:rect];
    self.window.frame = [[UIScreen mainScreen] bounds];
    [self.window makeKeyAndVisible];

    //Create a subview. Make it a red square. make sure it has a background.
    //set the userInteractionEnabled and multipleTouchEnabled and for
    //good meausure call becomeFirstResponder.
    SubView *view = [[SubView alloc] initWithFrame:CGRectMake(100,100,100,100)];
    view.backgroundColor = [UIColor redColor];
    [self.window addSubview:view];
    view.userInteractionEnabled = YES;
    view.multipleTouchEnabled = YES;
    [view becomeFirstResponder];


    //Create default UIViewControllers because Objective-C fails if the windows don't have
    //root view controllers. I don't like being muscled into MVC but what are you gonna do
    NSArray *windows = [[UIApplication sharedApplication] windows];
    for(UIWindow *window in windows) {
        if(window.rootViewController == nil){
            UIViewController* vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
            window.rootViewController = vc;
            window.userInteractionEnabled = YES;
            window.multipleTouchEnabled = YES;
        }
    }

return YES;
}

@end

这里是SubView类。只是有touchesBegan touchesEnded。

And here's the SubView class. Does just has the touchesBegan touchesEnded.

SubView.h

SubView.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface SubView : UIView {
}

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

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

@end

SubView.m

SubView.m

#import "SubView.h"

@implementation SubView

//delegate method for touches began
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    //[super touchesBegan:touches withEvent:event];
    NSLog(@"touchesBegan!");

}


//delegate method for touches ending.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    //[super touchesEnded:touches withEvent:event];
    NSLog(@"touchesEnded!");
}

//just for good measure.
- (BOOL) canBecomeFirstResponder {
    return YES;
}

@end

很简单。创建一个窗口,创建一个SubView,添加SubView到窗口,设置userInteractionEnabled。然而,它不工作。我看过下面的S.O.帖子:

Pretty simple. Create a window, create a SubView, add SubView to the window, set userInteractionEnabled. And yet, it doesn't work. I've looked at the following S.O. posts:

子视图未收到触摸

iPhone SDK - 将触摸从UIViewController转发到子视图

touchesBegan无反应

touchesBegan in UIView not being called

touchesBegan在UIView子类中未调用

touches没有在UIView子类中调用

他们都说userInteractionEnabled = YES应该修复它,或者可能有视图覆盖另一个视图,或者视图可能有一个透明的背景。这里没有适用。我设置了view.userInteractionEnabled = YES,我甚至试图给视图第一响应者状态。没有一个似乎做任何好处。

They all say userInteractionEnabled = YES should fix it, or there might be view covering another view, or the view might have a transparent background. None of that applies here. I've set view.userInteractionEnabled = YES, and I've even tried to give the view first-responder status. None of it seems to do any good.

精明观察者也会看到我在窗口本身设置这些值:

Astute observers will also see that I'm setting these values on the window itself:

window.userInteractionEnabled = YES;
window.multipleTouchEnabled = YES;

我试过了。没有骰子。我试过调用

I've tried it with and without. No dice. I've tried calling

[super touchesBegan:touches withEvent:event]

[super touchesEnded:touches withEvent:event]

。没有骰子。任何帮助,你可以给我将非常感谢。感谢!

in those callbacks on SubView. No dice. Any help you can give me would be greatly appreciated. Thanks!

推荐答案

在应用程序运行时查看您的视图层次结构,可以使用 recursiveDescription 或使用Xcode 7的Debug View Hierarchy按钮。

Look at your view hierarchy while the app is running, either using recursiveDescription or using Xcode 7's "Debug View Hierarchy" button.

(lldb) po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
<UIWindow: 0x7fc1f9d17b20; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x7fc1f9d18910>; layer = <UIWindowLayer: 0x7fc1f9d16560>>
   | <SubView: 0x7fc1f9c04350; frame = (100 100; 100 100); layer = <CALayer: 0x7fc1f9c04730>>
   | <UIView: 0x7fc1f9c07500; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x7fc1f9c07fc0>>

稍后在子视图列表中的视图更接近屏幕,因此首先接收触摸。由通用 UIViewController 创建的视图填充窗口,位于 SubView 前面。因此您的 SubView 无法接收触摸。

Views later in the list of subviews are "closer" to the screen and thus receives touches first. The view created by the generic UIViewController fills the window and is in front of your SubView. Thus your SubView can't receive touches.

Apple添加了 rootViewController 属性到 UIWindow 在iOS 4.0 - 五年前。通过战斗,你只是为自己做麻烦。只需让 rootViewController.view 成为窗口中的单个顶级视图,并在其下添加子视图。没有人强迫您向您的应用添加任何其他视图控制器。

Apple added the rootViewController property to UIWindow in iOS 4.0—over five years ago. By fighting it, you're only making trouble for yourself. Just let rootViewController.view be the single top-level view in your window, and add your subviews under that. Nobody's forcing you to add any other view controllers to your app.

这篇关于UIView子类没有收到touchesBegan,touchesEnded的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆