사실 취업하고 이리저리 띵까띵까 놀다가, 이것저것 배우고 공부하면서 핵데이에 대한 기억이 많이 지워지고 왜곡되었을 가능성도 있다.

하지만 내 기억인데 뭐... 적어보자.

 

핵데이

핵데이에 합격한 후에 바로 팀을 나누게 되었다.

멘토는 2명, 멘티는 나까지 5명으로 진행됐기에 1-2 / 1-3 구성이 나온 듯하다.

 

나와 팀원은 2명 팀에 구성되었다. 아무래도 포트폴리오(자소서)에 안드로이드 프로젝트가 상대적으로 많았기에 그랬던 것 같다.

당시 외부 동아리에서도 안드로이드 프로젝트를 진행한 직후였으며, MVVM이다 RxJava다 Retrofit이다 뭐다하며 새로운 기술들을 접할 기회가 있어, 사용해보던 시기(이게 중요...)이다.

학생으로써 이리저리 새로운 기술들을 배운다는 것은 '내 실력이 늘어가고 있구나'라고 생각하게 만들었다.

하지만 팀원과 미팅을 진행하면서, 내 모든 자신/자만감은 사라졌다.

이미 깃과 안드로이드에 대해 나보다 많이 알고 있었으며, 멘토님과의 미팅시에도 정확히 생각하고 있는 것들을 얘기하는 것이 멋져보였다.

 

핵데이에서 우수 참가자로 선정되면 -> 인턴 인터뷰 -> 인턴 -> 전환 인터뷰 -> 최종 합격 의 프로세스를 갖는다는 것은 이미 알고 있었다.

하지만 팀원과 함께 팀이 되는 순간 모든 것을 내려놓게 되었다. 

실력 차이도 실력차이지만... 내가 인터뷰에서 합격할 수 있다는 자신이 없었고, 차라리 팀원과 함께 짧은 프로젝트를 진행하면서 스스로 많이 배워보자  라는 생각이었다.

 

어떻게 어떻게 프로젝트를 진행했다. Room/MVVM/RxJava/Kotlin을 사용하여 과제 프로젝트를 마쳤었다.

지금 생각해보면 정말 간단한 프로젝트였으며, 사실 협업 능력이나 코드 그리고 얼마나 열심히 하는 지를 평가하는 것 같았다.

 

프로젝트 마지막 날, 그린 팩토리에서 모두가 모여 발표 및 회고를 진행했다.

같은 프로젝트를 2팀이 진행한 경험이 없어 신기했다. 저렇게도 구현할 수 있구나, 왜 저런 생각을 못했지? 등... 

-> 이래서 페어 프로그래밍이 도움이 많이 되는 것 같다.

 

어쨋든, 그렇게 1~2주 후에 네이버에서 메일이 왔으며

 

대충 이런식으로 왔다.

 

사실 합격을 기대하진 않았지만, 그래도 첫 회사 면접이었기에, 스스로는 열심히 준비하였다.


면접

내 예상과는 전혀 다른 질문들이 들어왔다.

인턴 인터뷰기에 간단한 안드로이드/자바/코틀린에 대해 질문이 들어올 줄 알았는데, 사용한 라이브러리나 프레임워크를 "왜 사용했는지?", "어떤게 좋았는지?" 더 나아가서 "이런 상황에서는 어떻게 할 것인지?" 등이 들어왔다.

사실 저 질문들을 아예 준비하지 않았던 것은 아니다. 준비했다. 하지만 그보다 더 deep한 질문들과 연계 질문들이 날 더더욱 힘들게했다.

 

1시간 면접동안 내가 무슨 대답을 하고 있는지도 모르는 채, 면접이 끝났다.

 

결과는? 당연히 불합격!!

 

나중에 들어보니 나와 팀원이 인터뷰를 진행한 것 같다고 들었다.

그리고 팀원은 역시나 합격!!~

 

뭐... 이러고 SW마에스트로 로 이동했다.

iOS에서 View의 Layout과 Content Update

iOS를 개발하다보면 View의 Layout과 Content와 관련된 이슈를 자주 접하게 된다.

실제로 UIView가 언제 Update되는지 모르기 때문에 발생한다.

View가 언제 Update 되는지 알기 위해서는 iOS App's Run Loop 를 이해하고 그것이 UIView가 제공하는 메서드들과 어떤 관계를 갖고 있는지 파악해야 한다.

 

iOS App's Run Loop

iOS App의 Main Run Loop는 유저로부터 모든 input Event를 받고, 응답을 담당한다.

유저가 발생한 모든 상호작용은 Event Queue에 추가된다.

아래의 사진처럼 App 객체는 Event Queue로부터 Event를 하나씩 꺼내서 App의 다른 객체들에게 전달한다.

App 객체는 유저로부터 input Event를 해석하고 그에 상응되는 App의 Core 객체들 안에 있는 Handler를 호출해준다.

또한 이러한 Handler는 개발자들이 만들어놓은 코드를 실행한다.

이러한 메서드들이 반환되면 다시 Main Run Loop로 돌아가 Update Cycle이 다시 시작된다.

Update Cycle은 View들을 배치하고 다시 그리는 역할을 한다.

 

Update Cycle

Update Cycle은 App이 유저로부터의 모든 Event Handling Code를 수행하고 다시 Main Run Loop로 컨트롤을 반환하는 지점

바로 이 지점에서 시스템은 우리의 View들을 배치하고(layout), 보여주고(display), 제약(contraints)한다.

만약 우리가 Event Handler들을 처리하는 과정에서 어떤 UIView에 변화를 준다면, 해당 UIView는 다시 그려져야 한다고 표시됨

다음 Update Cycle에서 시스템은 이 UIView의 모든 변화를 수행한다.

유저가 상호작용하는 것과 Layout이 변하는 시간의 Gap은 유저가 인지하지 못한다.

iOS App은 60 FPS이고, Update Cycle은 이 중 1 프레임에 해당된다.

이렇게 빠르게 Update되기 때문에, 유저는 UI와 상호작용 간의 차이를 느끼지 못한다.

그러나 이벤트가 처리되는 시점과 실제로 View가 다시 그려지는 시점의 차이가 존재하기 때문에, View는 우리가 View를 Update하기 원하는 Run Loop의 특정 시점에 Update되지 않을 수도 있다.

 

이는 다음과 같은 위험을 초래한다.

만약 우리가 View의 마지막 Layout이나 Content에 대해 계산을 해야하는 시점이라면, 예전 정보를 갖고 View를 조작할 가능성이 생긴다.

Layout

  • UIView의 Layout은 화면에서 UIView의 크기와 위치를 의미한다.
  • 모든 View의 frame을 갖고 있고, 이는 SuperView의 좌표계에서의 위치와 크기를 나타낸다.
  • UIView는 시스템에게 Layout이 변했다고 알려줄 수 있는 메서드
  • View의 Layout이 다시 계산되는 시점에 특정 작업을 실행할 수 있게 오버라이드 가능한 콜백 메서드를 제공

layoutSubviews()

  • View와 SubView들의 위치와 크기를 재조정한다.
  • 현재 View와 모든 SubView들의 위치와 크기를 제공한다.
  • 이 메서드는 재귀적으로 모든 SubView들의 layoutSubviews까지 호출되기 때문에, 부하가 크다.
  • 이 메소드를 직접 호출하면 안된다
    • 대신, layoutSubviews를 시스템이 호출하도록 유도하는 방식 존재
      • 이 방식은 모두 run loop가 돌아가는 동안 layoutSubviews가 실행되는 시점이 모두 다르다. 
    • setNeedsLayout() 호출 or 즉시 업데이트를 원하면 layoutIfNeeded() 메소드 호출
  • layoutSubviews가 완료될 때, View를 소유한 VC의 viewDidLayoutSubviews가 호출된다.
    • layoutSUbviews는 View의 layout이 변화했다는 callback이기 때문에, layout 관련 로직은 오래된 layout을 사용하는 것을 방지하기 위해 viewDidLoad/viewWillAppear가 아닌 viewDidLayoutSubviews에 호출해야 한다.

자동 refresh triggers

다음과 같은 이벤트들은 자동으로 View가 그것들의 layout에 변화가 생겼다는 것을 인지하여, 시스템에서 layoutSubviews가 다음 update Cycle에서 호출된다.

 

  • View를 Resizing
  • SubView 추가
  • UIScrollView 스크롤 시, UIScrollView와 그것의 부모뷰에 layoutSubviews가 호출됨
  • Device를 회전
  • View의 Constraint를 변경

위와 같은 방법들은 자동으로 시스템이 알아채어 layoutSubviews를 호출해준다.

그러나 layoutSubviews를 직접 호출할 수 있는 방법들도 존재한다.

setNeedsLayout()

layoutSubviews를 가장 적은 부하로 호출할 수 있는 메서드이다.

setNeedsLayouts는 시스템에게 이 View의 Layout이 재계산되어야 한다고 알린다.

setNeedsLayouts는 즉시 반환되고, 실제로 View Update를 해주는 것은 아니다.

대신, 시스템이 다음 Update Cycle에서 layoutSubviews를 View와 SubView들에게 호출하게 한다.

실제로 setNeedsLayouts가 호출되는 시점과 View가 다시 그려지는 시점은 정확하지는 않지만, 유저가 인지할 수는 없다.

layoutIfNeeded()

layoutIfNeeded는 UIView가 layoutSubviews를 호출하도록하는 명시적인 메서드이다.

layoutSubviews가 다음 UpdateCycle에서 호출되는 것이 아니라, View의 Layout의 변경사항이 있다면 즉시 호출한다.

만약 layoutIfNeeded를 setNeedsLayout를 호출한 직후나 자동으로 layoutSubviews를 호출하는 방법 직후에 호출한다면,

layoutSubviews는 뷰에 즉시 호출된다.

그러나 우리가 layoutIfNeeded를 호출했는데 View에 변경사항이 없다면 호출되지 않는다.

 

layoutIfNeeded는 주로 COnstraints를 애니메이션하는 상황에 유용하다.

애니메이션 시작전에 새로운 Constraints를 설정하고, 애니메이션 클로저안에 layoutIfNeeded를 호출한다.

 

 layoutIfNeeded()과 setNeedsLayout()의 차이를 보여준다.

 

출처 : ZeddiOS 블로그

 

Display

Layout이란 것이 View의 위치와 크기를 의미한다면, Display는 View의 속성 중 크기/위치나 SubView들에 대한 정보를 갖지 않는 속성을 포함한다.

ex) 색, 텍스트, 이미지, Core Graphics 등이 있다.

Display는 Layout 과정과 유사한데, 시스템이 자동으로 업데이트가 되게 하는 방식과 우리가 명시적으로 업데이트를 하는 방법이 존재

draw(_ rect:)

뷰에서 CGRect 직사각형으로 특정된 영역에 대해 다시 뷰를 그리는 등의 업데이트를 할 때, 호출되는 메서드

UIView의 draw 메서드는 Layout Update 과정에서의 layoutSubviews와 같은 역할을 한다.

차이점은 draw 메서드는 SubView들의 draw까지 호출하지 않는다는 것이다.

직접 draw 메서드를 호출하면 안된다.

내부 인자

rect는 업데이트되어야 하는 영역을 가지고 있따.

해당 rect의 범위는 업데이트 되는 뷰의 bounds 비율이 된다

ex) 뷰가 그려지는 첫 시점에는 직사각형은 그 자체가 전형적으로 현재 뷰로부터 보이는 전체 영역이 된다.

그러나, 부분적인 그리기 연산이 수행될 때, rect는 해당 뷰의 특정부분이 될 수도 있다

역할

전달된 사각형(rect) 내에서 receiver(수신자)의 이미지를 그립니다.

Core Graphics 및 UIKit 과 같은 기술을 사용하여 뷰의 내용을 그리는 하위 클래스는 draw 메서드를 재정의해야한다.

하지만, 이외의 방법으로 직접 컨텐츠를 설정하는 경우에는 재정의할 필요가 없다.

 

UIView를 직접 하위클래스로 만들면, super를 호출할 필요가 없다.

다른 View 클래스를 하위 클래스화 하는 경우, 적당한 위치에서 super를 호출해야 한다

이 메소드를 직접 호출하면 안된다 -> setNeedsDisplay() or setNeedsDisplay(_:) 를 호출하라

 

setNeedsDisplay()

setNeedsLayout과 유사하다.

View의 Content가 Update되게 하는 flag를 활성화시키고, 실제로 View가 다시 그리기 전에 메서드는 반환한다.

그러면 다음 Update Cycle에 시스템은 flag가 활성화된 View들의 draw를 호출한다.

우리가 만약 View의 일부분만 다시 그려지길 원한다면, setNeedsDisplay(_ rect:)를 통해 rect 범위만 그릴 수 있다.

대부분 View의 UI Component를 Update하는 것은 View의 dirty flag를 활성화시켜서 우리가 명시적으로 setNeedsDisplay를 호출하지 않아도 다음 Update Cycle에 View가 다시 그려지도록 유도한다.

그러나, 만약 UI Component와 직접적으로 연관되어 있지 않지만, 매 Update Cycle마다 다시 View를 그려줘야 하는 속성이 있다면,

didSet 감시자를 설정하여 setNeedsDisplay()를 명시적으로 호출할 수 있다.

 

 

Constraints

Auto Layout 세계에서는 Layout하고 Draw하는 것에 대한 3단계 과정이 존재한다.

  1. Constraints를 Update한다
    1. 시스템이 View에 필요한 COnstraints들을 계산하고 설정한다.
  2. Layout 단계
    1. Layout 엔진이 View들의 Frame과 SubView들의 Frame을 계산하고 배치한다.
  3. Display 단계
    1. View의 Content를 다시 그릴 필요가 있다면, draw 메서드를 호출한다.

 

updateConstraints

이 메서드는 Auto Layout을 이용하는 View의 COnstraints를 동적으로 변경할 때 사용된다.

Layout 단계에서 layoutSubviews나 Display단계에서 draw처럼, updateConstraints는 오직 오버라이딩되어야 하며 직접 호출해서는 안된다.

우리는 보통 updateConstraints에서 동적으로 변하는 Constraints들을 구현한다.

정적인 Constraints들은 IB나 View의 생성자나 viewDidLoad에서 정의되어야 한다.

 

일반적으로, Constraints를 활성화/비활성화하거나 Constraint의 우선순위나 constant를 변경하거나, View를 계층에서 삭제하는 것은 updateConstraints를 다음 Update Cycle에서 호출하게 한다.

그러나 이 역시 명시적으로 호출하는 방법이 존재한다.

 

setNeedsUpdateConstraints

setNeedsUpdateConstraints를 호출하는 것은 다음 Update Cycle에서 Constraints가 Update되는 것을 보장한다.

setNeedsLayout과 setNeedsDisplay와 비슷하다.

 

updateConstraintsIfNeeded

updateConstraintsIfNeeded는 layoutIfNeeded와 유사하다.

그러나 AutoLayout을 사용하는 View에서만 유효하다.

Constraint Update Flag를 검사하여서, Update가 필요하다면 updateConstraints를 즉시 호출한다.

 

invalidateIntrinsicContentSize

Auto Layout을 사용하는 몇몇 View들은 intrinsicContentSize 속성을 갖고 있다.

View가 갖고 있는 Content의 크기를 의미한다.

intrinsicContentSize는 전형적으로 View가 갖고 있는 요소들의 Constaints로 결정되지만,  Override하여 Custom이 가능하다.

 

 

그렇다면 이것들을 어떻게 연결시키는가?

View의 Layout과 Display 그리고 Constaints는 Run Loop에서 다른 시점에 어떻게 Update되고, 명시적으로 Update할 수 있는 지에 대해 유사한 패턴을 갖는다.

각 Component들은 layoutSubviews, draw, updateConstraints와 같은 실제로 Update를 하는 메서드를 갖는다.

이 메서드들은 직접 호출되면 안되기 때문에, 유도할 수 있는 방법이 존재한다.

이러한 메서드들은 Run Loop의 마지막에 View의 해당 Flag가 활성화되어 있으면, 시스템이 호출해주는 방식이다.

Layout과 Constraints의 Update는 즉시 Update할 수 있는 메서드가 존재한다.

다음 표는 Update Cycle과 Event Loop 그리고 위의 메서드들이 Cycle 동안 어떻게 호출되는지를 설명하는 표이다.

우리는 layoutIfNeeded / updateConstraintsIfNeeded를 Run Loop의 어디서든 즉시 호출가능하다.

Loop의 끝은 Update Cycle이다. Update Cycle은 Constraints, Layout, Display를 Flag가 활성화된 View를 Update한다.

 

 

 


 

Q) 근데 항상 View들의 속성을 변경해줬을 때, setNeedsDisplay() 호출 없이도 잘만 업데이트되던데...?

A) 시스템 자체적으로 호출되고 있다, 거의 모든 표준 UI 구성요소 View의 프로퍼티가 수정될 때마다, 내부적으로 setNeedsDisplay()가 트리거된다.

예)

  1. View를 부분적으로 가리고 있던 다른 View이동 및 제거
  2. hidden 프로퍼티를 No로 설정하여, 이전에 숨겨진 View를 다시 볼 수 있게 만들기
  3. View를 화면 밖으로 스크롤한 다음, 화면으로 다시 이동하기

이 3가지 상황에서는 내부적으로 setNeedsDisplay()가 호출되고 있다

 

Q) 그럼 언제 사용해?

A) 나 자신만의 View를 만들고, 자체 draw메소드를 구현하고, 무언가가 변경되면 호출!

 


'iOS' 카테고리의 다른 글

[iOS] Dynamic/Static Framework (1)  (0) 2021.06.01
[iOS] Framework vs Library / 모듈화  (0) 2021.06.01
[iOS] View LifeCycle  (0) 2021.05.24
[iOS] UIWindowScene / UIWindow / UIView  (0) 2021.05.23
[iOS] HitTest  (0) 2021.05.21

iOS App LifeCycle을 공부한 후에는 ViewController의 LifeCycle 그리고 오늘 알아볼 View LifeCycle이 궁금해진다.

 

View는 스토리보드, xib, code 방식으로 다양한 방법으로 생성될 수 있다.

접근 방식과는 별도로 View가 생성, 로드, 표시, 삭제되는 시점을 이해해야만 원하는 UI 디자인, 애니메이션 등의 작업이 가능해진다.

 

왜 알아야 할까?

App LifeCycle을 공부하면, App이 Background로 갔을 때, Suspend될 때, 다시 Foreground로 왔을 때 등등의 상황이 발생하는 것을 알 수 있다. 사용자가 앱을 이용하면서 작업 결과가 바뀌고, 저장되고 App State가 변경된다.

 

반면에 View에 특정 상태 전환이 있을 때, UI를 조작해야할 수도 있다.

ex) 가로모드와 세로모드 간의 차이가 있어야하고, 이 차이를 어느 "시기"에 수행해야 하는지 등

 

무엇을 알아야 할까?

적절한 위치에서 View를 사용하려면 View가 생성, 로드, 표시, 삭제, 종료 시점을 알아야 한다.

UIViewController의 SubClass는 View를 관리한다. 그리고 UIViewController의 rootView는 UIView이다.

 

VC는 UIView의 모든 마법을 처리하는 반면 UIView는 사용자에게 화면과 일부 컨텐츠를 나타낸다.

VC는 화면에 올 때, rootView에 알려준다.

먼저 VC는 rootView를 생성하고 로드한다. 로드 후에 View들이 나타나고 필요할 때 사라지도록 지시한다.

 

또한 VC는 다른 VC의 자식일 수도 있다. 따라서 VC의 LifeCycle은 rootView에 관심있을 뿐만아니라, 부모 VC로 이동했는지에 대한 다른 VC와의 관계도 포함한다.

 

마지막으로 rootView에는 자체 컨텐츠와 수명주기가 있다. rootView에는 버튼, 레이블, 스위치 등의 하위 View가 있다.

이런 하위 View의 수명주기를 보통 고려하지 않는다. 

그러나 VC를 다른 VC의 내부에 표시하는 경우에는 VC의 View들에 대한 LifeCycle 작업을 모방할 필요가 있다(?)

 

LifeCycle Event 알림

UIViewController에는 특정 작업이 발생했을 때, 알려주는 메소드들이 있다.

viewDidLoad, viewWillAppear 등과 rootView를 설정하는 loadView 메소드가 있다.

 

UIViewController - UIView 관계

  • loadView
    • VC의 rootView가 로드되는 곳
    • 현재 VC의 view는 nil이다.
    • Custom View를 만들고 설정하려면 해당 메소드를 override해야 한다.
    • IB를 사용해 만드는 경우에는 override하면 안된다.
    • 이 메소드를 직접 호출해서는 안된다.
  • viewDidLoad
    • View를 생성하고 메모리에 로드한 후에 한번 호출한다.
    • 그러나 View의 Bounds가 설정되지 않았기 때문에, 화면에 표시되지 않은 상태이다.
  • viewWillAppear
    • 화면에 View가 나타나기 직전에 호출된다.
    • View의 Bounds는 정의되지만, 방향을 설정되지 않은 상태이다.
  • viewDidAppear
    • 애니메이션을 시작하기에 좋은 시기
  • viewWillLayoutSubviews
    • LifeCycle에서 View의 Bounds를 배우는 첫 시기
    • UIView에서 layoutSubviews 메서드가 트리거되기 직전에 호출된다.
    • rootView의 하위뷰가 로드될 때도 호출된다.
    • ex) CollectionView의 Cell이 로드될 때 호출됨
  • viewDidLayoutSubviews
    • layoutSubviews가 호출된 직후에 호출됨
    • 하위뷰가 설정되고 크기, 위치, 제약 등이 적용된다.
    • viewWillLayoutSubviews와 viewDidLayoutSubviews는 가로 <-> 세로 변경시에도 호출된다.
    • 그 말은 View의 Bounds가 업데이트되거나 View의 Layout이 재계산될 때마다 재 호출된다는 것이다.
  • viewWillDisappear
    • 화면에서 뷰가 사라지려고할 때 호출된다.
    • 여기서 할 수 있는 작업
      • 데이터를 잃지 않도록 저장하는 것
      • 네트워크 작업 취소

 

 

UIViewController - UIViewController 관계

단순히 VC의 LifeCycle이 아니라 VC 내에 VC가 존재하는 상황을 이해하고자 한다.

시스템에 상태를 알리기 위해, 일부 LifeCycle 메서드를 직접 호출해야 하는 경우가 있기 때문이다.

 

 

 

 

 

'iOS' 카테고리의 다른 글

[iOS] Framework vs Library / 모듈화  (0) 2021.06.01
[iOS] UIView / 레이아웃 업데이트 관련 메소드  (0) 2021.05.24
[iOS] UIWindowScene / UIWindow / UIView  (0) 2021.05.23
[iOS] HitTest  (0) 2021.05.21
[iOS] Responder / Responder Chain  (0) 2021.05.21

View 란 무엇인가?

  • View는 UIView의 인스턴스이거나 UIView의 하위 클래스의 인스턴스이다.
  • 자신을 어떻게 그리는지 알고 있다.
  • 터치와 같은 Event를 처리할 수 있다.
  • 뷰 계층 구조상에 존재한다.
  • View들의 Root는 Application의 Window이다.

 

프로젝트의 View Hierarchy를 보면 UIWindowScene, UIWindow, UIViewController, UIView 등이 계층적으로 생성된 걸 볼 수 있다.

 

관리

AppDelegate (~ iOS 12)

iOS 12 까지는 Window 관리를 AppDelegate에서 하였습니다.

프로젝트를 생성후에, AppDelegate에 프로퍼티로는 var window: UIWindow? 가 있었죠.

 

SceneDelegate (iOS 13 ~)

iOS 13 부터는 Window 관리를 SceneDelegate에서 합니다.

여러개의 window를 사용할 수도 있다고 합니다.

이전 App Life Cycle 포스팅에서 SceneDelegate에서는 여러개의 Scene을 사용할 수 있다고 언급했었다.

그렇다면 Window랑 Scene은 같은 개념인 것인가?

 

 

여러개의 Scene

이 상황에서는 3개의 Scene이 존재한다. 

각각의 Scene들에 대해 SceneDelegate를 통해 Life Cycle을 관리할 수 있다.

 

 

UIWindowScene

  • UIScene의 서브 클래스로 App의 하나 이상의 Window를 관리한다.
  • 직접 생성하면 안된다. 대신 configuration time에 원하는 UIWindowScene에 대해 명시하라고 한다.
    • 방법으로는 info.plist의 scene configuration details 부분에 원하는 UIWindowScene의 Class 이름을 넣으면 된다고 한다.

그림과 같이 하나의 UIWindowScene에는 여러개의 Window를 가질 수 있다.

프로퍼티로는 [UIWindow] 와 UIScreen이 있다.

또한, UISceneDelegate를 채택하는 Protocol인 UIWindowSceneDelegate가 존재한다.

우리가 프로젝트를 생성한 후, SceneDelegate 코드를 보면 UIWindowSceneDelegate Protocol을 채택한 것을 볼 수 있다.

class SceneDelegate: UIResponder, UIWindowSceneDelegate

 

 

UISceneSession

App의 Scene들 중 하나의 Scene에 대한 정보를 갖고 있는 객체이다. 그래서 내부에 scene이라는 프로퍼티가 존재한다.\

옵셔널인 이유는 scene이 session으로부터 connect/disconnect 될 수 있기 때문인 것 같다.

 

 

UIWindow

App의 UI에 대한 배경과 Event를 View에 전달하는 객체이다.

 

class UIWindow: UIView

Window들은 VC와 함께 작동하여 EVent를 처리하고, App 작업의 기본이 되는 다른 작업들을 수행한다.

사용하는 경우는 아래와 같다.

  • App의 컨텐츠를 표시할 기본 Window를 제공한다.
  • 추가 컨텐츠를 표시할 때, 필요한 경우 추가 Window를 생성한다.

쉽게 말해, UIWindow는 "액자"이고, UIView는 끼워넣는 그림/사진이다.

 

 

UIWindowScene객체를 이용해서 앱의 UI를 관리함

UIWindowScene은 UIScene을 상속받은 class이다.

-> 위에서 3개의 Scene을 가진 메모 Application인 경우, 3개의 Scene(WindowScene) 인 것 같음...

(WindowScene vs Scene 에 대한 얘기가 전혀 없다..)

 

scene은 여러개의 window들과 view controller들을 포함하며 하나의 UI의 인스턴스를 표현

 scene은 UIWindowSceneDelegate객체를 가지고 있음 (각 same memory를 공유하며 동기화)

'iOS' 카테고리의 다른 글

[iOS] UIView / 레이아웃 업데이트 관련 메소드  (0) 2021.05.24
[iOS] View LifeCycle  (0) 2021.05.24
[iOS] HitTest  (0) 2021.05.21
[iOS] Responder / Responder Chain  (0) 2021.05.21
[iOS] State Preserving/Restoring ViewControlle  (0) 2021.05.20

+ Recent posts