今天博主做了這樣一個demo,上圖,圖中cell有點類似oc自帶刪除功能的cell,但是嫌棄他長得難看~~!博主自定義了一個cell

Cell中有scrollView,這就出現問題了,因為這個cell是需要跳轉的,但是這個點擊事件被scrollView截取了,這就連帶出了很多問題,其中主要的就是響應者鏈條。
這里也看了很多博文,感覺這個比較好:
響應者鏈條概念: iOS系統檢測到手指觸摸(Touch)操作時會將其打包成一個UIEvent對象,並放入當前活動Application的事件隊列,單例的UIApplication會從事件隊列中取出觸摸事件並傳遞給單例的UIWindow來處理,UIWindow對象首先會使用hitTest:withEvent:方法尋找此次Touch操作初始點所在的視圖(View),即需要將觸摸事件傳遞給其處理的視圖,這個過程稱之為hit-test view。
響應者對象(Responder Object) 指的是 有響應和處理事件能力的對象。 響應者鏈就是由一系列的響應者對象 構成的一個層次結構。
UIResponder 是所有響應對象的基類,在UIResponder類中定義了處理上述各種事件的接口。我們熟悉的 UIApplication、 UIViewController、 UIWindow 和所有繼承自UIView的UIKit類都直接或間接的繼承自UIResponder,所以它們的實例都是可以構成響應者鏈的響應者對象。
UIWindow實例對象會首先在它的內容視圖上調用hitTest:withEvent:,此方法會在其視圖層級結構中的每個視圖上調用pointInside:withEvent:(該方法用來判斷點擊事件發生的位置是否處於當前視圖范圍內,以確定用戶是不是點擊了當前視圖),如果pointInside:withEvent:返回YES,則繼續逐級調用,直到找到touch操作發生的位置,這個視圖也就是要找的hit-test view。
hitTest:withEvent:方法的處理流程如下:
首先調用當前視圖的pointInside:withEvent:方法判斷觸摸點是否在當前視圖內;
若返回NO,則hitTest:withEvent:返回nil;
若返回YES,則向當前視圖的所有子視圖(subviews)發送hitTest:withEvent:消息,所有子視圖的遍歷順序是從最頂層視圖一直到到最底層視圖,即從subviews數組的末尾向前遍歷,直到有子視圖返回非空對象或者全部子視圖遍歷完畢;
若第一次有子視圖返回非空對象,則hitTest:withEvent:方法返回此對象,處理結束;
如所有子視圖都返回非,則hitTest:withEvent:方法返回自身(self)。
響應者鏈條是從點擊的當前控件中自上而下的,如果當前控件不能處理點擊事件的話再向下傳遞,如果處理點擊事件的話會執行三個方法(還有一個就先不說了):
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
}
但是經過測試發現scrollView中只有點擊事件才會執行此三種方法,而滑動事件則不會。而我們正是要的這種效果,如果滑動的話界面是不跳轉的,點擊才跳轉,在這里我們在scrollView中這樣操作
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
albumTableViewCell * cell = self.superview;
[cell touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
albumTableViewCell * cell = self.superview;
[cell touchesEnded:touches withEvent:event];
}
其實只寫touchesend那個方法就可以,將點擊事件傳遞下去,在執行了touchEnd之后tableView的代理方法didSelect才會執行
,這樣實現了點擊事件的手動傳遞,效果還是不錯的~~!
順便說一下關閉控件響應事件的三種方法,一個是屬性userInteractionEnabled設成No、hidden屬性設成yes、alpha在0~0.01之間,其實還有一種,就是重寫控件將hitTest:withEvent:方法,將返回置為空(因為響應者鏈條是這個方法傳遞的)。
