[iOS] ViewController의 최상위 클래스는 무엇일까??

 

정답!

UIViewController이다. 

 

모든 뷰 컨트롤러는 UIViewController를 상속받고 있는데,

UIViewController가 하는 역할은 무엇일까? 하고 생각해 보면다면 일단 생각나는 건 아래와 같당.

  • 속한 객체의 크기 및 레이아웃을 잡음 (UI를 구성)
  • 사용자의 response를 받아서 처리함
  • ... ... 또 뭐가 있을까?

UIViewController가 하는 역할을 명확히 알려면, UIViewController가 상속받고 있는 객체들이 무엇인지 알면 더 좋을 것 같다는 생각에 조금 더 파헤쳐 보게 되었다.

 

 

UIViewController 뜯어보기

먼저, UIViewController가 상속받고 있는 class들은 다음과 같당.

 

 

차례대로, 

  • UIResponder
  • NSCoding
  • UIAppearanceContainer
  • UITraitEnvironment
  • UIContentContainer
  • UIFocusEnvironment

이다.

 

왠지 익숙한 친구들도 보이고, 처음 보는 친구들도 왕왕 보인다.

 

차례차례 알아봅시당~!

 

 

 

UIResponder

이 친구는 익숙하다! 사용자의 반응을 받아서 처리하는 친구 아녔나? 그래도 공식 문서의 설명을 읽어 보자면,

 

Responder objects — instances of UIResponder — constitute the event-handling backbone of a UIKit app. Many key objects are also responders, including the UIApplication object, UIViewController objects, and all UIView objects (which includes UIWindow). As events occur, UIKit dispatches them to your app’s responder objects for handling.

 

 

UIResponder의 인스턴스인 Responder object들은 UIKit app의 이벤트를 처리하는 중추를 구성하고 있다고 한다. 이에는 UIApplication, UIViewController, UIView 등이 속한다고 나와 있다! 이벤트가 발생하면, UIKit은 해당하는 오브젝트에게 동작하라고 전달한다구 한다.

 

대부분 그냥 후루룩~ 읽고 넘기는데 UIResponder는 익숙하지만 늘 새로워서 끝까지 읽어 보겠당 ^__^

 

 

 

 

There are several kinds of events, including touch events, motion events, remote-control events, and press events. To handle a specific type of event, a responder must override the corresponding methods. For example, to handle touch events, a responder implements the touchesBegan(_:with:), touchesMoved(_:with:), touchesEnded(_:with:), and touchesCancelled(_:with:) methods. In the case of touches, the responder uses the event information provided by UIKit to track changes to those touches and to update the app’s interface appropriately.

 

터치와 모션, 원격 제어, 꾹 누르는 event를 포함한 여러 종류의 이벤트가 이에 해당한다. (그러니까, UIResponder가 처리하는 이벤트에 해당하는거죵.) 이런 특정한 이벤트를 핸들링하기 위해서는 해당 객체가 method를 오버라이딩해야 한다구 함. 이후에는 예를 들고 있군뇨! 터치 이벤트의 경우에 responder는 touchesBegan(_:with:), touchesMoved(_:with:), touchesEnded(_:with:), and touchesCancelled(_:with:)와 같은 이벤트를 처리하는 method를 오버라이딩해야 한다고 말입니당. 그럼 터치 이벤트가 발생했을 때, 해당하는 객체는 UIKit에서 제공하는 event 정보를 사용하여 터치에 해당하는 변화를 추적하고 앱의 인터페이스를 적절히 업데이트할 수 있겠죵.

 

 

 

 

In addition to handling events, UIKit responders also manage the forwarding of unhandled events to other parts of your app. If a given responder doesn’t handle an event, it forwards that event to the next event in the responder chain. UIKit manages the responder chain dynamically, using predefined rules to determine which object should be next to receive an event. For example, a view forwards events to its superview, and the root view of a hierarchy forwards events to its view controller. 

추가적으로 이벤트를 제어하기 위해서는, UIKit의 객체들은 자신이 처리하지 않는 이벤트들을 다른 객체에게 전달하는 역할도 수행한다. 만약 해당 객체가 이벤트를 수행하지 않는다면, 이 객체가 다음 Responder Chain의 다음 responder에게 이벤트를 전달한다.

Responder Chain은 UIKit에 정해진 규칙에 의해 동적으로 관리된다.

UIKit은 정해진 규칙에 의해 responder chain을 동적으로 관리한다. 이 규칙은, 해당 객체가 다음에 어떤 객체에게 event를 전달할지에 대한 규칙으로, 그 예시로는 하나의 view는 자신의 superView에게 이벤트를 전달하고, 가장 최상위에 있는 뷰는 ViewContorller에게 이벤트를 전달한다.

 

 

왜 이 친구가 익숙했는지~~~!! 새삼 느끼는군뇨. Responder Chaining 때문이었습니당.

다만, View도, 뭔가 입력을 받을 수 있는 여러 객체들도 UIResponder를 채택하기 때문에 이벤트를 받고 다른 객체에게 evnet를 전달할 수 있는 거였군뇽.

 

 

고럼! ViewController의 첫 번째 역할은 확정되었습니다. 

 

responder chain의 경우 위와 같이 전개되는데, UIViewController는 하위에 있는 객체들에게 이벤트를 전달받고 처리할 수 있는 event는 처리하며, UIWindow에게 자신이 처리하지 못하는 evnet를 전달하는 역할을 합니다.

 

 

 

 

 

 

 

NSCoding

 

NSCoding은 이름에서도 알 수 있듯이 객체를 encoding / decoding 할 수 있도록 만들어주는 프로토콜입니다.

객체나 클래스가 disk에 아카이빙 할 수 있도록 해 주고, 객체들이 각기 다른 메모리 주소에 저장될 수 있도록? 도와주는 것 같습니당.

이 친구는 UIViewController의 역할보다는 존재 자체에 필요한 프로토콜 같네요!

 

ViewController가 화면을 보여주는 역할을 하다 보니 잘 보여주고, 저장해야 하니까요.

 

 

 

 

 

 

 

 

 

UIAppearanceContainer

 

호오 ......

이 친구는 UI에 관여하는 친구인가 봅니당.

 

UIAppearance는 익숙한 친구인 게, 프로젝트의 전체적인 색깔을 미리 입힐 때 해당하는 객체의 Appearance를 지정해 주지 않았던가?

거기서 나오는 것 같습니당.

 

 

 

UIAppearance도 일종의 프로토콜로, 해당하는 클래스에 대한 appearance의 대리자 권한을 준다구 생각하면 된다.

프록시가 뭐지?? 싶어서 검색해 봤는데 일종의 대리자 .. 쯤으로 생각하면 되지 않을까? 싶다

아무튼 아래 설명을 보면

 

You can customize the appearance of instances of a class by sending appearance-modification messages to the class’s appearance proxy.
There are two ways to customize appearance for objects: for all instances, and for instances contained within an instance of a container class.

 

중간의 노트는 빼고 슥닥 가져와봤다. 공식 문서에 따르면, 외관 수정 메세지를 해당 클래스의 appearance proxy에 보냄으로써 클래스 인스턴스의 외관을 커스터마이징할 수 있다.

객체의 외관을 커스터마이징 방법에 대해 두 가지 방법이 있다고 하는데, 모든 인스턴스에 대해 해당 외형을 적용하거나 containerClass를 지정하여 해당하는 외관을 지정하거나! 중의 하나이다.

아하, 그럼 UIViewController의 경우에는 container로 appearance가 적용된 상태라고 보면 될 것 같당.

 

 

 

 

 

 

UITraitEnvironment

 

이 친구는 아주 익숙하다!!!!!! ^___^ 

나는 다크모드 전환을 할 때 불러서 사용했는데, 주로 user interface와 display와 관련된 특성을 포함한 iOS interface 환경을 앱에 사용가능하게 만들어주는 protocol이라고 보면 될 것 같다.

 

 

 

 

UIContentContainer

우와 얘는 난생 첨 들어보는 것 같다 ㅋ

근데 막상 하는 역할을 보면 익숙한 역할을 하고 있었다.

 

The methods of this protocol handle size-related transitions that are related to changes in the current trait environment or view controller hierarchy. When the parent view controller changes, or when trait changes occur that affect the size of a view controller, UIKit calls these methods to give the affected objects a chance to respond appropriately.

 

ViewController에 있는 내용을 size와 trait changes에 맞게 적용시켜주는 프로토콜인 것이당.

아래 overview를 보면 더욱 명쾌해진다.

이 프로토콜의 Method들은 ViewController의 계층관계에 있는 현재 trait 환경과 연결지어 사이즈와 관련된 변화를 다룬다구 한다.

만약 부모 VC가 변화하거나 ViewController의 사이즈 변화와 연관된 trait 변화가 일어난다면, UIKit은 이러한 영향받는 객체들에게 적절히 반응할 수 있도록 method를 호출한다구 한다.

 

사이즈 변화와 관련된 프로토콜이군아.

ViewController의 사이즈가 변화할만한? 게 뭐가 있지? 뷰컨 안에서 뷰컨을 호출하는 것 외에는 잘 생각이 나지 않는다. 암튼.

 

 

 

UIFocusEnvironment

 

호오 ㅋㅋ 얘도 첨 들어보는 애다.

view의 계층관계와 관련된 주요 행위를 정의하는 method를 포함하고 있다고 한다.

해당하는 클래스는 UIView, UIViewCotnroller, UIWindow, UIPresentationController와 같은 클래스가 채택하고 있는데, 다른 말로 하면 스크랜에 있는 View의 접근에 직접적으로나 간접적으로 제어하고 있다는 뜻이다.

 

아하, UIViewController는 화면의 View의 제어도 하고 있군아.

 

 

 

 

 

 

결론

ViewController의 최상위 클래스는 UIViewController이다.

UIViewController가 하는 역할은 ...

  • 계층 관계에 있는 View를 제어한다.
  • 뷰의 크기를 조정하고, 레이아웃을 관리한다.
  • iOS 환경에 대한 변화를 감지하고 뷰를 업데이트한다.
  • 사용자의 event를 처리하기도 하고, 전달하고 전달받는다.

 

이렇게 볼 수 있겠다!

 

 

 

 

가볍게 시작한 글이었는데 생각보다 너무 길어졌다~~~ ㅜㅜ

오늘 질문 다 하고 싶었는데 ...... 일단 하나는 끝냈다. 짱!

 

 

 

 

 

 

참고 자료

https://developer.apple.com/documentation/uikit/uiresponder 

 

UIResponder | Apple Developer Documentation

An abstract interface for responding to and handling events.

developer.apple.com

https://jeonyeohun.tistory.com/257

 

[iOS] UIResponder: iOS의 이벤트 처리 - Responder Chain과 First Responder

UITextField 쓰면서 많이 본거.. 최근데 UITextField를 사용하면서 사용자가 키보드의 엔터(return)을 눌렀을 때 현재 텍스트 필드 바로 다음에 있는 텍스트 필드로 editing이 전환되도록 만들어야 하는 작

jeonyeohun.tistory.com

https://developer.apple.com/documentation/foundation/nscoding

 

NSCoding | Apple Developer Documentation

A protocol that enables an object to be encoded and decoded for archiving and distribution.

developer.apple.com

https://woozzang.tistory.com/126

 

[iOS] NSCoding 이란? (feat. 인코딩, 디코딩, 아카이빙)

안녕하세요. 오늘은 공식문서에서 설명하는 NSCoding 를 공부해보겠습니다🐶 NSCoding protocol NSCoding NSCoding은 클래스가 encoding 과 decoding 되는 것을 가능하게 해주는 프로토콜입니다. 다시 말하면, NSC

woozzang.tistory.com

https://developer.apple.com/documentation/uikit/uiappearance

 

UIAppearance | Apple Developer Documentation

A collection of methods that gives you access to the appearance proxy for a class.

developer.apple.com

https://developer.apple.com/documentation/uikit/uitraitenvironment

 

UITraitEnvironment | Apple Developer Documentation

A set of methods that makes the iOS interface environment available to your app.

developer.apple.com

https://developer.apple.com/documentation/uikit/uifocusenvironment

 

UIFocusEnvironment | Apple Developer Documentation

A set of methods that define the focus behavior for a branch of the view hierarchy.

developer.apple.com

https://developer.apple.com/documentation/uikit/uicontentcontainer

 

UIContentContainer | Apple Developer Documentation

A set of methods for adapting the contents of your view controllers to size and trait changes.

developer.apple.com