자식 뷰 컨트롤러에 이벤트가 전파되지 않음
삽질 iOS ReactorKit Troubleshooting
배경
- ReactorKit 사용
상황
- C 는 A 와 B 라는 자식 뷰 컨트롤러를 가지고 있다.
- 처음에는 A 만 표시한다. B 는 숨겨져 있다.
- 어떤 버튼을 누르면 A 가 숨겨지고, B 가 표시된다.
- 다시 어떤 버튼을 누르면 B 가 숨겨지고, A 가 표시된다.
- A 는 항상 동일한 데이터를 표시하고, B 는 버튼에 따라 유동적으로 데이터가 변경된다.
- 따라서 A 는 생애 주기에서 단 한 번의 reactor 를 생성, 주입 받는다.
- B 는 생애 주기에서 여러 번의 reactor 를 생성, 주입 받는다.
- A 와 A 의 서브 뷰들은 이벤트를 전달 받을 수 있다.
- B 와 B 의 서브 뷰들은 이벤트를 전달 받을 수 없다.
추측
- 어디선가 중간에
isUserInteractionEnabled
속성이 false 로 변경된다. - B 의 reactor 가 주입되는 순간에
isUserInteractionEnabled
가 false 이면 바인딩이 되지 않는다. - isUserInteractionEnabled 을 직접 변경하지 않았는데 false 가 되는 것에 대한 ChatGPT 답변
isUserInteractionEnabled
속성이 자동으로false
로 설정되는 경우는 일반적으로 다음과 같은 상황에서 발생합니다:
- 뷰가 다른 뷰에 의해 가려져서 사용자의 상호작용을 받지 않아야 할 때: 만약 자식 뷰가 부모 뷰에 의해 가려져야 하는 경우, iOS는 해당 뷰의
isUserInteractionEnabled
속성을 자동으로false
로 설정합니다. 이는 사용자가 가려진 뷰를 터치하지 못하도록 방지하기 위한 것입니다.- 상위 뷰나 상위 뷰 컨트롤러에서 사용자의 상호작용을 가로채야 할 때: 상위 뷰나 뷰 컨트롤러에서 사용자의 상호작용을 처리해야 할 경우, 해당 뷰의
isUserInteractionEnabled
속성이 자동으로false
로 설정될 수 있습니다. 이는 상위에서 처리되는 터치 이벤트에 의해 자식 뷰의 사용자 상호작용이 가로채지는 것을 방지하기 위한 것입니다.- 사용자 상호작용이 필요하지 않은 정적인 콘텐츠를 표시해야 할 때: 사용자 상호작용이 필요하지 않은 정적인 콘텐츠를 표시할 때, 해당 뷰의
isUserInteractionEnabled
속성을false
로 설정하여 사용자의 터치 이벤트를 무시할 수 있습니다.따라서,
isUserInteractionEnabled
속성이 자동으로false
로 설정되는 것은 정상적인 동작일 수 있습니다. 이 경우, 해당 뷰의 사용자 상호작용을 처리하는 코드를 구현할 필요가 없으며, 이벤트를 다른 뷰나 뷰 컨트롤러로 전달하도록 설계해야 합니다. 만약 사용자 상호작용을 받아야 하는 경우에는 해당 속성을true
로 설정해주어야 합니다.
발견
// B.view.isUserInteractionEnabled = true
B.reactor = somethingReactor
// B.view.isUserInteractionEnabled = false
- reactor 를 주입하는 시점에
isUserInteractionEnabled
이 false 로 바뀐다. - ReactorKit 내부에는
isUserInteractionEnabled
과 관련된 코드는 없음 → ?!
시원찮은 해결
- B.reactor 를 주입한 이후에
B.view.isUserInteractionEnabled
를 true 로 설정한다.
참고 자료
- 삽질