一、原理:
scrollView自帶一個(gè)PanGesture滑動(dòng)手勢(shì),滑動(dòng)時(shí)修改scrollview的bounds.y,實(shí)現(xiàn)子視圖有滑動(dòng)效果。
參考:http://m.itdecent.cn/p/964313cfbdaa
二、觸摸事件打斷
根據(jù)《事件傳遞 響應(yīng)鏈》所知,自帶的滑動(dòng)手勢(shì)會(huì)打斷響應(yīng)鏈中視圖的touch方法,可以通過手勢(shì)屬性cancelsTouchesInView=NO ,讓這個(gè)手勢(shì)不打斷響應(yīng)者的touch方法。
參考:http://m.itdecent.cn/p/b0884faae603
三、scrollView的一個(gè)機(jī)制
scrollView的屬性
delaysContentTouches 和 canCancelContentTouches控制事件響應(yīng)交給scrollview子視圖還是scrollView的手勢(shì)。
從你的手指touch屏幕開始,scrollView開始一個(gè)timer,如果:
- 150ms內(nèi)如果你的手指沒有任何動(dòng)作,消息就會(huì)傳給subView。
- 150ms內(nèi)手指有明顯的滑動(dòng)(一個(gè)swipe動(dòng)作),scrollView就會(huì)滾動(dòng),消息不會(huì)傳給subView。
- 150ms內(nèi)手指沒有滑動(dòng),scrollView將消息傳給subView,但是之后手指開始滑動(dòng),scrollView傳送touchesCancelled消息給subView,然后開始滾動(dòng)。
delaysContentTouches:默認(rèn)值為YES。如果設(shè)置為NO,則會(huì)立即把事件傳遞給subView。canCancelContentTouches:默認(rèn)為YES,如果設(shè)置為NO,這消息一旦傳遞給subView,這scroll事件不會(huì)再發(fā)生。
參考:http://m.itdecent.cn/p/2b171f6153ad
四、scrollview和子視圖事件沖突
canCancelContentTouches用來控制scrollview的全局沖突設(shè)置,以下兩個(gè)scrollview方法用來分開控制scrollview與子視圖事件沖突
下面這個(gè)函數(shù)的功能是判斷是否可以把touch 事件傳遞給子視圖,即在他上面的視圖。當(dāng)返回是yes 的時(shí)候就表示可以,就當(dāng)點(diǎn)擊子視圖view 的時(shí)候停止響應(yīng)scroll事件,改而響應(yīng)子視圖的touch 事件,當(dāng)為no 時(shí)則拒絕子視圖響應(yīng),執(zhí)行父視圖的touch 事件
//scrollview的delaysContentTouches=NO時(shí),會(huì)立刻調(diào)用這個(gè)方法,看是否滾動(dòng)scrollview,用來控制子視圖是否響應(yīng)touch事件
- (BOOL)touchesShouldBegin:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view{
}
用來具體控制某個(gè)scrollview子視圖是否打斷touch,不打斷子視圖touch意味著觸摸在這個(gè)子視圖時(shí),scrollview不會(huì)滑動(dòng)
當(dāng)UIScrollView將touch事件交給子view后,當(dāng)手指發(fā)生滑動(dòng)時(shí),調(diào)用此方法,假如返回NO,則將touch事件交給view,如果返回YES,則交給UIScrollView處理,產(chǎn)生滑動(dòng)。(但是前提是UIScrollView的canCancelContentTouches屬性是YES才會(huì)調(diào)用這個(gè)方法,只要不是UIControll的子類,這個(gè)屬性默認(rèn)是YES。)
- (BOOL)touchesShouldCancelInContentView:(UIView *)view{
return NO;不打斷子視圖touch,scrollview不滑動(dòng)
return YES;打斷子視圖touch,scrollview滑動(dòng)}