今天寫了這麼一小段測試代碼,如下: [cpp] CGRect imageRect = (CGRect){100, 100, 100, 100}; UIImageView *imageView = [[[UIImageView alloc] initWithFrame:imageRect] autorelease]; imageView.backgroundColor = [UIColor yellowColor]; [self.view addSubview:imageView]; UIButton *maskBtn = [UIButton buttonWithType:UIButtonTypeCustom]; maskBtn.frame = imageView.bounds; maskBtn.backgroundColor = [UIColor redColor]; [maskBtn addTarget:self action:@selector(maskBtnDidClick:) forControlEvents:UIControlEventTouchUpInside]; [imageView addSubview:maskBtn]; 結果點擊按鈕不響應事件,小糾結了一下,在SO上得到信息: UIImageView has userInteractionEnabled set to NO by default. You are adding the button as a subview to the image view. You should set it to YES. 所以,添加了一行代碼,設置imageView響應用戶交互即可: [cpp] CGRect imageRect = (CGRect){100, 100, 100, 100}; UIImageView *imageView = [[[UIImageView alloc] initWithFrame:imageRect] autorelease]; imageView.backgroundColor = [UIColor yellowColor]; [self.view addSubview:imageView]; imageView.userInteractionEnabled = YES; UIButton *maskBtn = [UIButton buttonWithType:UIButtonTypeCustom]; maskBtn.frame = imageView.bounds; maskBtn.backgroundColor = [UIColor redColor]; [maskBtn addTarget:self action:@selector(maskBtnDidClick:) forControlEvents:UIControlEventTouchUpInside]; [imageView addSubview:maskBtn]; 這純粹就是一個知識點引發的坑,因為以前在UIImageView上都是使用TapGesture來響應用戶交互的,所以對這個坑沒有太大印象 —— 我遇到過沒? 上面代碼所構建的視圖層級大致如下: 其中紅色方框代表的是UIImageView上的UIButton按鈕。 參考View Programming Guide for iOS文檔,當用戶在紅色按鈕上點擊了一下後: 1. 硬件設施會通知UIKit有觸摸事件; 2. UIKit將觸摸事件信息封裝成UIEvent對象,分發給合適的視圖; 1) UIKit將事件對象放到當前App的事件隊列中; 2) 參考Event Handling Guide for iOS文檔,當前App會從事件隊列取出一個事件對象,然後發送給key window對象; 3) key window對象通過Hit-Testing獲取觸摸事件發生時所在的視圖對象; 4) 通過Hit-Testing獲得的視圖成為第一個可以響應事件的對象,first responder,如果它不響應,則事件對象會沿著響應者鏈傳遞。響應者鏈,即Responder Chain,是由first responder到當前App對象所構成的一串對象,它們都繼承於UIResponder類; P.S. 具體描述可以見此文檔。 3. 找到合適的處理事件的對象,比如上面代碼是self(ViewController),響應事件做些事情;如果找不到就丟棄掉。