배경

  • 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로 설정되는 경우는 일반적으로 다음과 같은 상황에서 발생합니다:

  1. 뷰가 다른 뷰에 의해 가려져서 사용자의 상호작용을 받지 않아야 할 때: 만약 자식 뷰가 부모 뷰에 의해 가려져야 하는 경우, iOS는 해당 뷰의 isUserInteractionEnabled 속성을 자동으로 false로 설정합니다. 이는 사용자가 가려진 뷰를 터치하지 못하도록 방지하기 위한 것입니다.
  2. 상위 뷰나 상위 뷰 컨트롤러에서 사용자의 상호작용을 가로채야 할 때: 상위 뷰나 뷰 컨트롤러에서 사용자의 상호작용을 처리해야 할 경우, 해당 뷰의 isUserInteractionEnabled 속성이 자동으로 false로 설정될 수 있습니다. 이는 상위에서 처리되는 터치 이벤트에 의해 자식 뷰의 사용자 상호작용이 가로채지는 것을 방지하기 위한 것입니다.
  3. 사용자 상호작용이 필요하지 않은 정적인 콘텐츠를 표시해야 할 때: 사용자 상호작용이 필요하지 않은 정적인 콘텐츠를 표시할 때, 해당 뷰의 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 로 설정한다.

참고 자료

  • 삽질