[Swift] Button이 ScrollView의 드래그를 막는다면

When UIButton blocks scroll

naljin
6 min readOct 16, 2020

뭐가 문젠디!

아니 제 ScrollView 안에 UIButton이 있단말이져? 근데 얘를 잡고 스크롤하려면 스크롤이 안되는거예요????

이럴 때는 모다? 구글링이다~

열심히 사과도 그려봄. 짤 쓰려고 글 쓴다는게 정계의 학설~

그 결과!! 문제 해결의 핵심은 ScrollView의 instance method인 touchesShouldCancel(in:)에 있었습니당

touchesShouldCancel(in:)

공식문서를 볼까여?

Declaration

이렇게 생겼군여. 계속 살펴 봅시다.

parameter

view터치 이벤트를 받고 있는 object라고 하네요 ㅇㅋㅇㅋ

return value

viewUIControl object가 아니라면 기본으로 true를 리턴한다고해요. 그 말은 UIControl 객체는 false를 리턴한다는 말이겠져?

Discussion

ScrollView는 content view로 tracking message들을 보내기 시작하자마자 해당 메소드를 호출한다.

엥 트래킹 메시지? 터치 이벤트 받는걸 전달한다는거여? 뭔말이지 일단 넘어가고~

이 메소드로부터 만약 false를 수신하면, 드래깅을 중지하고 content view의 하위 view로 전달한다.

오호 대박. 그러니까 이거란 말이지..

  • false: 하위 view 가 touch 받음. 드래깅 중지.
  • true: view에 touch 동작 전달 취소. (따라서 쭉쭉 드래깅 가넝)

근데 방금 우리 return value 부분 설명 기억나세요?

기본으로 true를 리턴. 하지만 view가 UIControl 이면 false 리턴

근데 여러분 UIButton이 모다?!

UIControl 객체이다!

그래서 얘가 터치 이벤트를 받는 view일 때는 false를 리턴하게 되고… 얘한테 계속 터치 이벤트가 가게 되고… 우리는 드래그 불가넝하게 되고…

오키오키 그럼

해당 함수에서 파라미터로 받는 view 가 UIButton일때도 true를 리턴해주면 되겠군!

코드를 보자

앗 여러분 Discussion 부분에서 빼놓은 설명이 있어요 ㅎㅎ

만약 scroll view의 canCancelContent 값이 false면 이 메서드를 호출하지 않는다.

ㅇㅋ 그럼 얘부터 true로 세팅해야겠죠?

아님 코드로 하시등가요!

collectionView.canCancelContentTouches = true

맞아여 ㅋ 제 scrollview는 사실 collectionView였음여. 님덜은 tableView로 바꾸등가 scrollView로 바꾸등가 알아서 하셈여

후비적

그리고 위에서 내내 설명했던 touchesShouldCancel(in:) 를 사용해야겠져?

님덜이 사용할 ScrollView 종류를 상속받고 저 함수 override 하셈여

class MyCollectionView: UICollectionView {
override func touchesShouldCancel(in view: UIView) -> Bool {
if view is UIButton {
return true
}
return super.touchesShouldCancel(in: view)
}
}

자자 저기 보이죠? viewUIButton이면 true를 리턴하는 부분!

if view is UIButton {
return true
}

아무 처리도 안했으면 UIButtonview로 들어왔을때는 false로 return 되고 있었겠죠? 그래서 자기가 다 터치 가져가고 있었을거예요.. 이 부분을 강제로 true로 리턴시켜주면?! ! 드래그 하게 내 터치 내놔 ㅡㅡ 상황이 되는거죵

마무리

잘 되나 테스트 해보고 올게여! 오키 전 잘되네요!

저는 쌓인 에러들을 처리하러 다시 20000…

참고

--

--

No responses yet