Where who wants to meet someone

[2주차] 3. setNeedsLayout과 setNeedsDisplay의 차이에 대해 설명하시오(작성중) 본문

Apple Developer/면접 스터디

[2주차] 3. setNeedsLayout과 setNeedsDisplay의 차이에 대해 설명하시오(작성중)

Lust3r 2023. 7. 19. 20:21
728x90
  1. Generics에 대해 설명하시오
  2. MVC 구조에 대해 블록 그림을 그리고, 각 역할과 흐름을 설명하시오
  3. setNeedsLayout과 setNeedsDisplay의 차이에 대해 설명하시오

3. setNeedsLayout과 setNeedsDisplay의 차이에 대해 설명하시오

Managing your app's life cycle | Apple Developer Documentation

 

Managing your app’s life cycle | Apple Developer Documentation

Respond to system notifications when your app is in the foreground or background, and handle other significant system-related events.

developer.apple.com

여기에 더해 view의 LifeCycle은 override func view~ 에서 목록을 확인할 수 있었고 다음과 같이 추려볼 수 있었다.

UIViewController | Apple Developer Documentation

 

UIViewController | Apple Developer Documentation

An object that manages a view hierarchy for your UIKit app.

developer.apple.com

Managing the view

1. loadView()

loadView() | Apple Developer Documentation

 

loadView() | Apple Developer Documentation

Creates the view that the controller manages.

developer.apple.com

- 컨트롤러가 관리하는 view를 만드는 메서드

이 메서드는 직접 호출해서는 안 됨. ViewController는 View 프로퍼티가 요청되었지만 현재 nil 일 때 이 메서드를 호출한다.

이 메서드는 View를 load하거나 생성하고 View 프로퍼티에 할당한다.

 

ViewController에 관련 nib 파일이 있는 경우 이 메서드는 nib 파일에서 view를 load한다.

init(nibName:bundle:) 메서드를 사용하여 명시적으로 nib 파일을 할당한 경우 ViewController가 스토리보드에서 인스턴스화되었을 때 발생하는 nibName 속성이 nil이 아닌 값을 반환하거나 또는 iOS가 ViewController의 클래스 이름을 기반으로 하는 이름을 가진 앱 번들에서 nib 파일을 찾는 경우 ViewController에 연결된 nib파일이 있다.

ViewController에 연결된 nib 파일이 없는 경우 이 메서드는 대신 일반 UIView 개체를 만든다.

 

Interface Builder를 사용하여 View를 생성하고 ViewController를 초기화하는 경우 이 메서드를 override하면 안 된다.

 

View를 수동으로 생성하기 위해 이 메서드를 재정의할 수 있다. 그렇게 하도록 선택한 경우 View 계층 구조의 root View를 View 속성에 할당한다. 생성한 View는 고유한 인스턴스여야 하고, 다른 ViewController 개체와 공유해서는 안 된다.

이 메서드의 사용자 정의 구현은 super를 호출하지 않아야 함.

 

View의 추가적인 초기화를 수행하기 위해서는 viewDidLoad() 메서드에서 수행.

 

2. viewDidLoad()

viewDidLoad() | Apple Developer Documentation

 

viewDidLoad() | Apple Developer Documentation

Called after the controller's view is loaded into memory.

developer.apple.com

- 컨트롤러의 뷰가 메모리에 로드된 후 호출되는 메서드

이 메서드는 ViewController가 뷰 계층 구조를 메모리에 로드한 후에 호출된다. 뷰 계층 구조가 nib 파일에서 로드되었는지 loadView() 메서드에서 프로그래밍 방식으로 생성되었는지 여부에 관계없이 호출된다.

일반적으로 nib파일에서 로드된 뷰에서 추가적인 초기화를 수행하려면 이 메서드를 override한다.

 

3. loadViewIfNeeded()

loadViewIfNeeded() | Apple Developer Documentation

 

loadViewIfNeeded() | Apple Developer Documentation

Loads the view controller’s view if it’s not loaded yet.

developer.apple.com

- 뷰가 아직 로드되지 않은 경우 ViewController의 뷰를 로드하는 메서드

이 메서드를 호출하면 스토리보드 파일에서 ViewController의 View를 로드하거나 설정된 규칙에 따라 필요에 따라 View를 생성.

 

Responding to view-related events

1. viewWillAppear()

viewWillAppear(_:) | Apple Developer Documentation

 

viewWillAppear(_:) | Apple Developer Documentation

Notifies the view controller that its view is about to be added to a view hierarchy.

developer.apple.com

- 뷰가 뷰 계층에 추가될 것임을 뷰 컨트롤러에 알리는 메서드

이 메서드는 뷰 컨트롤러의 뷰가 뷰 계층 구조에 추가되기 전과 뷰를 표시하기 위해 애니메이션이 구성되기 전에 호출된다.

이 메서드를 override하여 뷰 표시와 관련된 사용자 지정 작업을 수행할 수 있다. 예를 들어 이 방법을 사용하여 상태표시줄의 방향이나 스타일을 변경하여 표시되는 뷰의 방향이나 스타일에 맞출 수 있다.

이 메서드를 override하는 경우 구현의 특정 지점에서 super를 호출해야 한다.

 

Note
뷰 컨트롤러가 popover 내부의 뷰 컨트롤러에 의해 표시되는 경우 표시된 컨트롤러가 해제된 후 표시되는 뷰 컨트롤러에서 이 메서드가 호출되지 않는다.

* popover: 필요할 때 표시되고 사용자가 작업을 마치면 사라지는 콘텐츠에 사용되는 임시 인터페이스.
https://developer.apple.com/documentation/uikit/windows_and_screens/displaying_transient_content_in_a_popover

 

2. viewIsAppearing()

viewIsAppearing(_:) | Apple Developer Documentation

 

viewIsAppearing(_:) | Apple Developer Documentation

Notifies the view controller that the system is adding the view controller’s view to a view hierarchy.

developer.apple.com

- 시스템이 뷰 계층 구조에 뷰 컨트롤러의 뷰를 추가하고 있음을 뷰 컨트롤러에 알리는 메서드

- iOS 13.0부터 지원하는 메서드

시스템은 viewWillAppear(_:) 호출 이후 뷰 컨트롤러의 뷰가 나타날 때마다 한 번씩 이 메서드를 호출한다.

viewWillAppear(_:)와 달리 시스템은 뷰 컨트롤러의 뷰를 뷰 계층에 추가하고 superview가 뷰 컨트롤러의 뷰를 배치한 후에 이 메서드를 호출한다. 시스템이 이 메서드를 호출할 때까지 뷰 컨트롤러와 해당 뷰 모두 업데이트된 특성 컬렉션을 수신하고 뷰에 정확한 geometry가 있다.

 

이 메서드를 ovrride하여 뷰 표시와 관련된 사용자 지정 작업을 수행할 수 있다. 예를 들어 이 메서드를 사용하여 뷰 또는 뷰 컨트롤러의 특성 컬렉션을 기반으로 뷰를 구성하거나 업데이트할 수 있다.

또는 스크롤 위치 계산은 뷰의 크기와 geometry에 의존하기 때문에 뷰가 나타날 때 선택한 셀이 표시되도록 컬렉션 또는 테이블뷰를 프로그래밍 방식으로 스크롤할 수 있다.

 

이 메서드를 재정의하는 경우 구현의 특정 지점에서 super를 호출해야 한다.


그렇다면 특성 컬렉션(Trait Collection)이란 무엇인가?

UITraitCollection | Apple Developer Documentation

 

UITraitCollection | Apple Developer Documentation

A collection of data that represents the environment for an individual element in your app’s user interface.

developer.apple.com

- 앱의 사용자 인터페이스에 있는 개별 요소에 대한 환경을 나타내는 데이터 컬렉션

 

UITraitEnvironment 프로토콜의 traitCollection 속성에는 크기 클래스, 표시 배율 및 레이아웃 방향과 같은 iOS 사용자 인터페이스의 다양한 요소 상태를 설명하는 특성이 포함되어 있음. 이러한 특성은 함께 UIKit 특성 환경을 구성한다.

 

뷰 컨트롤러와 뷰가 iOS 인터페이스 환경의 변경 사항에 응답하도록 하려면 traitCollectionDidChange(_:) 메서드를 override 한다.

인터페이스 환경 변경에 대한 응답으로 뷰 컨트롤러 애니메이션을 사용자 지정하려면 UIContentContainer 프로토콜의 willTransition(to:with:) 메서드를 override한다.


Choosing the appropriate callback

시스템은 viewWillAppear(_:) 이후에 이 메서드를 호출하지만 두 콜백은 동일한 CATransaction 내에서 발생.

이것은 두 방법 중 하나에서 변경한 사항이 동시에 사용자에게 표시됨을 의미한다.

trait과 geometry는 시스템이 viewWillAppear(_:)를 호출할 때 최신 상태가 아니지만 시스템이 viewIsAppearing(_:)을 호출할 때 업데이트되므로 viewIsAppearing(_:)을 사용하여 뷰를 업데이트 해야 한다.

 

다음과 같은 경우에만 viewWillAppear(:_)를 사용하세요

  • 애니메이션과 함께 추가하기 위해 transitionCoordinator에 접근할 때와 같이 뷰 전환이 시작되기 전에 콜백이 필요하다.
    뷰 컨트롤러 전환 애니메이션과 동시에 수행하도록 프레임워크를 지시하는 애니메이션이 있다.
  • 뷰 컨트롤러나 뷰 특성, 계층 구조 또는 geometry에 의존하지 않는 작업을 수행하려면 균형 잡힌 콜백이 필요하다.
    사용 사례에는 viewWillAppear(_:)에서 데이터베이스 알림 등록 및 viewDidDisappear(_:)에서 등록 취소가 포함된다.

다른 모든 경우에는 viewIsAppearing(_:)을 사용하여 뷰를 업데이트한다.

시스템은 뷰가 layoutSubviews()를 실행할 때마다 viewWillLayoutSubviews() 및 viewDidLayoutSubviews()와 같은 레이아웃 메서드를 호출한다. 이는 전환 중 또는 뷰가 표시되는 동안 언제든지 발생할 수 있다.

그러나 시스템은 화면 전환 중에 viewIsAppearing(_:)을 한 번만 호출하고 화면이 표시될 때 레이아웃이 필요하지 않더라도 호출한다.

 

3. viewDidAppear()

viewDidAppear(_:) | Apple Developer Documentation

 

viewDidAppear(_:) | Apple Developer Documentation

Notifies the view controller that its view was added to a view hierarchy.

developer.apple.com

- 뷰가 뷰 계층에 추가되었음을 뷰 컨트롤러에 알리는 메서드

 

이 메서드를 override하여 뷰 표시와 관련된 추가 작업을 수행할 수 있다.

이 메서드를 override하는 경우 구현의 특정 지점에서 super를 호출해야 한다.

 

Note
뷰 컨트롤러가 popover 내부의 뷰 컨트롤러에 의해 표시되는 경우 표시된 컨트롤러가 해제된 후 표시되는 뷰 컨트롤러에서 이 메서드가 호출되지 않는다.

 

4. viewWillDisappear()

viewWillDisappear(_:) | Apple Developer Documentation

 

viewWillDisappear(_:) | Apple Developer Documentation

Notifies the view controller that its view is about to be removed from a view hierarchy.

developer.apple.com

- 뷰가 뷰 계층에서 제거되려고 한다는 것을 뷰 컨트롤러에 알리는 메서드

 

이 메서드는 뷰 계층 구조에서 뷰가 제거될 때 호출된다. 뷰가 실제로 제거되기 전과 애니메이션이 구성되기 전에 호출됨.

 

서브클래스는 이 메서드를 override하고 편집 변경 사항을 커밋하거나 뷰의 first responder 상태를 포기하거나 기타 관련 작업을 수행하는 데 사용할 수 있다. 예를 들어 이 메서드를 사용하여 뷰가 처음 표시되었을 때 viewDidAppear(_:) 메서드에서 수행된 상태 표시줄의 방향 또는 스타일에 대한 변경 사항을 되돌릴 수 있다. 이 메서드를 ovrride하는 경우 구현의 특정 지점에서 super를 호출해야 한다.

 

5. viewDidDisappear()

viewDidDisappear(_:) | Apple Developer Documentation

 

viewDidDisappear(_:) | Apple Developer Documentation

Notifies the view controller that its view was removed from a view hierarchy.

developer.apple.com

- 뷰 계층 구조에서 뷰가 제거되었음을 뷰 컨트롤러에 알리는 메서드

 

이 메서드를 override하여 뷰 해제 또는 숨기기와 관련된 추가 작업을 수행할 수 있고, override하는 경우 구현의 특정 지점에서 super를 호출해야 한다.

 


Displaying and managing views with a view controller

Displaying and managing views with a view controller | Apple Developer Documentation

 

Displaying and managing views with a view controller | Apple Developer Documentation

Build a view controller in storyboards, configure it with custom views, and fill those views with your app’s data.

developer.apple.com

MVC 디자인 패러다임에서 뷰 컨트롤러는 화면에 정보를 표시하는 뷰 개체와 앱의 콘텐츠를 저장하는 데이터 개체 사이에 맞다.

특히 뷰 컨트롤러는 뷰 계층 구조와 해당 뷰를 최신 상태로 유지하는 데 필요한 상태 정보를 관리한다.

모든 UIKit 앱은 콘텐츠를 표시하기 위해 뷰 컨트롤러에 크게 의존하며 뷰 및 UI관련 로직을 관리하기 위해 사용자 정의 뷰 컨트롤러를 자주 정의한다.

 

사용자가 만드는 대부분의 사용자 지정 뷰 컨트롤러는 콘텐츠 뷰 컨트롤러이다. 즉, 뷰 컨트롤러는 모든 뷰를 소유하고 해당 뷰와의 상호 작용을 관리한다. 콘텐츠 뷰 컨트롤러를 사용하여 앱의 사용자 지정 콘텐츠를 화면에 표시하고 뷰 컨트롤러 개체를 사용하여 사용자 지정 뷰와의 데이터 전송을 관리한다.

Note

콘텐츠 뷰 컨트롤러와 달리 컨테이너 뷰 컨트롤러는 다른 뷰 컨트롤러의 콘텐츠를 뷰 계층 구조에 통합한다.
UINavigationController는 컨테이너 뷰 컨트롤러의 예시이다. 컨테이너 뷰 컨트롤러를 구현하는 방법에 대한 자세한 내용은
Implementing a Custom Container View Controller를 참조.

콘텐츠 뷰 컨트롤러를 정의하려면 UIViewController를 서브클래싱하여 시작합니다. 인터페이스에 테이블 뷰 또는 컬렉션 뷰가 포함되어 있으면 대신 UITableViewController 또는 UICollectionViewController를 하위 클래스로 만든다. 

새 Xcode 프로젝트에는 수정할 콘텐츠 뷰 컨트롤러 클래스가 하나 이상 포함되어 있으며 더 추가할 수 있다.

 

Add views to your view controller

UIViewController에는 뷰 계층 구조의 root 뷰 역할을 하는 뷰 속성에서 접근할 수 있는 콘텐츠 뷰가 포함되어 있다.

해당 root 뷰에 인터페이스를 제공하는 데 필요한 사용자 정의 뷰를 추가한다. 스토리보드에서는 뷰를 뷰 컨트롤러 scene으로 드래그하여 뷰를 추가한다. 예를 들어, 다음 그림은 iPhone에 이미지 뷰와 버튼이 있는 뷰 컨트롤러를 보여준다.

뷰 컨트롤러에 뷰를 추가한 후에는 항상 오토 레이아웃 제약 조건을 추가하여 해당 뷰의 크기와 위치를 설정해야 한다.

제약 조건은 부모 또는 형제 뷰와 관련하여 각 뷰의 크기와 위치를 지정하는 방법을 정하는 규칙이며 뷰가 다양한 환경 및 장치에 자동으로 적응하도록 한다. 자세한 내용은 View layout 참조.

 

Store references to important views

런타임 시 뷰 컨트롤러의 코드에서 뷰에 접근해야 할 수 있다. 예를 들어 텍스트 뷰에서 텍스트를 가져오거나 이미지 뷰에서 이미지를 변경하려고 할 수 있다. 이를 위해서는 뷰 계층 구조의 뷰에 대한 참조가 필요하다. outlets를 사용하여 이러한 참조를 만든다.

 

outlet은 IBOutlet 키워드를 포함하는 뷰 컨트롤러의 속성이다. 해당 키워드가 있으면 스토리보드에서 해당 속성을 노출하도록 Xcode에 알린다. 다음 예제 코드는 두 outlet에 대한 정의를 보여준다. Swift에서 뷰 컨트롤러가 뷰에 대한 두 번째 강력한 참조를 보유하지 못하도록 약한(weak) 키워드를 포함한다. 첫 번째는 뷰 계층 구조 자체에서 시작된다.

 

@IBOutlet weak var imageView : UIImageView?
@IBOutlet weak var button : UIButton?

Add an outlet connection to send a message to a UI object에 설명된 대로 스토리보드에서 각 outlet을 해당 뷰에 연결한다.

뷰 계층 구조의 모든 뷰에 대한 참조를 저장할 필요는 없다. 나중에 수정하는 뷰에 대한 참조만 저장한다.

 

뷰 컨트롤러를 인스턴스화하면 UIKit은 스토리보드에서 구성한 outlet을 다시 연결한다. UIKit은 뷰 컨트롤러의 viewDidLoad() 메서드를 호출하기 전에 이러한 연결을 다시 설정하므로 해당 메서드에서 해당 속성의 개체에 접근할 수 있다.

프로그래밍 방식으로 뷰를 생성하는 경우 해당 뷰를 뷰 컨트롤러의 적절한 속성에 명시적으로 할당해야 한다.

 

Handle events occurring in views and controls

컨트롤은 target-action 디자인 패턴을 사용하여 사용자 상호 작용을 보고하고 일부 뷰는 변경 사항에 대한 응답으로 알림을 게시하거나 delegate 메서드를 호출한다. 뷰 컨트롤러는 뷰를 업데이트할 수 있도록 이러한 많은 상호 작용에 대해 알아야 하며 이를 수행할 수 있는 몇 가지 방법이 있다.

  • 뷰 컨트롤러에서 delegate 및 action 메서드를 구현한다. 이 옵션은 간단하고 구현하기 쉽지만 유연성이 떨어지고 코드를 테스트하고  검증하기가 더 어렵다.
  • 뷰 컨트롤러의 클래스 extension에서 delegate 및 action 메서드를 구현한다. 이 옵션은 이벤트 처리 코드를 뷰 컨트롤러의 나머지 부분과 분리하여 해당 코드를 더 쉽게 테스트하고 유효성을 검사할 수 있도록 한다.
  • 관련 정보를 뷰 컨트롤러로 전달하는 전용 개체에서 delegate 및 action 메서드를 구현한다. 이 옵션은 최고의 유연성과 재사용성을 제공한다. 책임을 분리하면 Unit test를 더 쉽게 할 수 있다.

컨트롤과의 사용자 상호 작용에 응답하려면 다음 코드 목록에 표시된 서명 중 하나를 사용하여 action 메서드를 정의한다.

메서드 정의에서 UIControl에 대한 일반 참조를 보다 구체적인 컨트롤 클래스로 바꿀 수 있다.

@IBAction func doSomething()
@IBAction func doSomething(sender: UIControl)
@IBAction func doSomething(sender: UIControl, forEvent event: UIEvent)

 

Prepare your views to appear onscreen

UIKit은 화면에 표시하기 전에 뷰 컨트롤러와 뷰를 구성할 수 있는 여러 기회를 제공한다.

스토리보드에서 뷰 컨트롤러를 인스턴스화하면 UIKit은 init(coder:) 메서드를 사용하여 해당 객체를 생성한다.

Note

뷰 컨트롤러에 코더 개체가 제공할 수 있는 것 이상으로 사용자 지정 초기화가 필요한 경우 UIStoryboard의 instantiateInitialViewController(creator:) 메서드를 사용하여 프로그래밍 방식으로 인스턴스화할 수 있다.
이 방법을 사용하면 블록과 UIKit에서 제공하는 코더 객체를 사용하여 뷰 컨트롤러를 직접 만들 수 있다.
이 옵션을 사용하면 뷰 컨트롤러에 필요한 사용자 지정 데이터로 뷰 컨트롤러를 초기화하고 스토리보드의 뷰 및 기타 개체 구성을 계속 복원할 수 있다.

뷰에 뷰 컨트롤러를 표시할 때 UIKit은 먼저 해당 뷰를 로드하고 구성해야 하며 다음 단계 순서를 사용하여 수행한다.

 

  1. 뷰의 init(coder:) 메서드를 사용하여 각 뷰를 만든다
  2. 뷰 컨트롤러의 해당 action과 outlet에 뷰를 연결한다
  3. 각 뷰와 뷰 컨트롤러의 awakeFromNib() 메서드를 호출한다
  4. 뷰 컨트롤러의 뷰 프로퍼티에 뷰 계층을 할당한다
  5. 뷰 컨트롤러의 viewDidLoad() 메서드를 호출한다

load할 때, 뷰 컨트롤러를 사용할 수 있도록 준비하는 데 필요한 일회성 구성 단계만 수행해야 한다.

load시간을 스토리보드의 일부가 아닌 추가 뷰를 만들고 구성하는데 사용해라.

뷰 컨트롤러가 화면에 나타날 때마다 발생해야 하는 작업을 수행하지 마라. 예를 들어 애니메이션을 시작하거나 뷰 값을 업데이트 하지 마라.

 

뷰가 화면에 처음 나타날 때 최종 뷰 관련 작업을 수행한다. UIKit은 뷰가 화면에 나타날 때 그것을 소유한 뷰 컨트롤러에 알리고 다음과 같은 방식으로 현재 환경에 맞게 해당 뷰의 레이아웃을 업데이트한다.

 

  1. 전환 시작 시 viewWillAppear(_:)를 호출
  2. 뷰를 계층구조에 추가
  3. 뷰 컨트롤러와 그것의 뷰의 특성 컬렉션(trait collection)을 업데이트
  4. superview에서의 크기와 위치를 포함하여 뷰의 geometry를 업데이트. 레이아웃 여백 및 safe area를 업데이트하고 필요한 경우 viewLayoutMarginsDidChange()viewSafeAreaInsetsDidChange() 메서드를 호출한다.
  5. 뷰 컨트롤러의 뷰가 화면에 표시되고 있음을 알리기 위해 viewIsAppearing(_:) 메서드를 호출
  6. viewWillLayoutSubviews() 메서드 호출
  7. 뷰 계층 구조의 레이아웃 업데이트
  8. viewDidLayoutSubviews() 메서드 호출
  9. 뷰를 화면에 표시
  10. 애니메이션이 끝나면 뷰 컨트롤러의 viewDidAppear(_:) 메서드를 호출

뷰 컨트롤러의 viewIsAppearing(_:) 메서드에서 뷰의 내용을 업데이트 해야 한다. 시스템이 이 메서드를 호출할 때 이미 뷰 계층 구조에 뷰를 추가하고 frame, bounds, margins, insets를 정의했다. 시스템이 viewIsAppearing(_:)에 추가하는 콘텐츠는 뷰가 화면에 처음 표시될 때 표시된다.

 

시스템은 뷰가 레이아웃을 수행할 때마다 viewWillLayoutSubviews()viewDidLayoutSubviews() 메서드를 호출한다.

이는 뷰가 표시되는 동안 언제든지 발생할 수 있다. 시스템은 각 appearance의 전환의 일부로 viewIsAppearing(_:)한 번만 호출하기 때문에 이 메서드에서 변경한 사항은 뷰가 레이아웃을 수행할 때마다 반복되지 않는다.

 

시스템이 viewIsAppearing(_:)을 호출하면 뷰 컨트롤러와 해당 뷰의 특성 컬렉션(trait collection)이 최신 상태가 된다.

뷰 컨트롤러의 traitCollection 속성을 사용하여 디스플레이 배율 또는 수직 및 수평 크기 클래스와 같은 현재 환경에 대한 정보에 접근할 수 있다. 사용 가능한 특성에 대한 자세한 내용은 UITraitCollection을 참조

 

(UITraitCollection은 위에 잠깐 언급했던 그것. horizontal, vertical Size, 디스플레이 비율, gamut, 레이아웃 방향 등을 가지고 있음.

-> 앱 사용자 인터페이스의 개별 요소에 대한 환경을 나타내는 데이터 모음)


setNeedsLayout() | Apple Developer Documentation

 

setNeedsLayout() | Apple Developer Documentation

Invalidates the current layout of the receiver and triggers a layout update during the next update cycle.

developer.apple.com

- receiver의 현재 레이아웃을 무효화하고 다음 업데이트 주기 동안 레이아웃 업데이트를 트리거하는 메서드

뷰의 하위 뷰 레이아웃을 조정하려면 애플리케이션의 메인 스레드에서 이 메서드를 호출해야 한다.

이 메서드는 요청을 기록하고 즉시 반환한다. 이 방법은 즉시 업데이트를 강제하지 않고 대신 다음 업데이트 주기를 기다리기 때문에 해당 뷰가 업데이트되기 전에 여러 뷰의 레이아웃을 무효화하는 데 사용할 수 있다. 이 동작을 통해 모든 레이아웃 업데이트를 하나의 업데이트 주기로 통합할 수 있으며 이는 일반적으로 성능에 더 좋다.

 

layoutIfNeeded() | Apple Developer Documentation

 

layoutIfNeeded() | Apple Developer Documentation

Lays out the subviews immediately, if layout updates are pending.

developer.apple.com

- 레이아웃 업데이트가 보류중인 경우 하위 뷰를 즉시 배치하는 메서드

이 메서드를 사용하여 뷰가 레이아웃을 즉시 업데이트하도록 한다. 오토 레이아웃을 사용할 때 레이아웃 엔진은 제약 조건의 변경 사항을 충족하기 위해 필요에 따라 뷰의 위치를 업데이트한다. 메시지를 받는 뷰를 루트 뷰로 사용하여 루트에서 시작하는 뷰 하위 트리를 배치한다.

보류 중인 레이아웃 업데이트가 없으면 이 메서드는 레이아웃을 수정하거나 레이아웃 관련 콜백을 호출하지 않고 종료된다.

 

setNeedsDisplay() | Apple Developer Documentation

 

setNeedsDisplay() | Apple Developer Documentation

Marks the receiver’s entire bounds rectangle as needing to be redrawn.

developer.apple.com

- receiver의 전체 bounds rectangle을 다시 그려야 하는 것으로 표시하는 메서드

이 메서드 또는 setNeedsDisplay(_:) 메서드를 사용하여 뷰의 콘텐츠를 다시 그려야 함을 시스템에 알릴 수 있다.

이 메서드는 요청을 기록하고 즉시 반환한다. 뷰는 무효화된 모든 뷰가 업데이트되는 시점인 다음 그리기 주기까지 실제로 다시 그려지지 않는다.

 

Note

만약 뷰가 CAEAGLLayer 개체에 의해 지원되는 경우 이 방법은 효과가 없다.
콘텐츠를 렌더링하기 위해 네이티브 그리기 방법(ex. UIKit 및 Core Graphics)을 사용하는 뷰에서만 사용하기 위한 것임.

* CAEAGLLayer: (iOS 12.0 Deprecated!) iOS 및 tvOS 애플리케이션에서 OpenGL 콘텐츠 그리기를 지원하는 계층

뷰의 내용이나 모양이 변경될 때만 뷰를 다시 그리도록 요청하려면 이 방법을 사용해야 한다.

뷰의 형상만 변경하면 일반적으로 뷰가 다시 그려지지 않는다. 대신 기존 콘텐츠는 뷰의 contentMode 속성 값에 따라 조정된다.

기존 콘텐츠를 다시 표시하면 변경되지 않은 콘텐츠를 다시 그릴 필요가 없으므로 성능이 향상된다.

 

 

setNeedsLayout()은 layoutSubviews()

setNeedsDisplay()은 draw(CGRect)