Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIViewController 애플 개발자 문서 #155

Closed
Youngminah opened this issue Apr 18, 2022 · 4 comments
Closed

UIViewController 애플 개발자 문서 #155

Youngminah opened this issue Apr 18, 2022 · 4 comments

Comments

@Youngminah
Copy link
Owner

Youngminah commented Apr 18, 2022

UIViewController

UIKit앱의 뷰 계층 구조를 관리하는 객체



  • 모든 뷰 컨트롤러의 공통 행위가 정의되어 있음
  • UIViewController 인스턴스를 직접적으로 다루는 것은 드문일이 될 것임.
  • 대신 UIViewController의 자식 클래스를 생성하고, 뷰계층 구조를 관리하는 메소드나 프로퍼티들을 추가 하여 사용하게 될 것
  • 뷰 컨트롤러의 주요 의무는 다음과 같다.
    • 기본 데이터 변경에 대한 응답으로 뷰의 내용을 업뎃함
    • 뷰와 유저의 상호작용에 반응함
    • 뷰의 사이즈를 재정의하고, 모든 인터페이스의 레이아웃을 관리함
    • 다른 뷰컨트롤러를 포함한 다른 개체들관의 연결을 관리
  • 뷰컨트롤러가 관리하는 뷰에 밀접하게 연결되어 있으며 뷰 계층 구조의 이벤트를 핸들링함
  • 특히, 뷰 컨트롤러는 UIResponder객체이며,
  • 다른 뷰컨의 루트 뷰와 해당 뷰컨에 속하는 상위 뷰 사이에 응답 체인을 주입한다.
  • 만약 뷰컨의 뷰 중 어느 것도 이벤트를 핸들링하지 않는 경우에는,
  • 뷰 컨트롤러는 이벤트를 처리하는 옵션이 있거나, 슈퍼뷰에 이벤트를 전달하는 옵션이 있다.
  • 뷰 컨트롤러는 단독으로 거의 사용되지 않는다.
  • 대신에 각각의 앱의 유저 인터페이스의 일부를 포함하는 여러 뷰컨트롤러를 사용한다.
    • 예를들어 어떤 뷰컨트롤러는 테이블에 아이템을 보여줄 줄 때,
    • 다른 뷰컨트롤러는 테이블로부터 선택된 아이템을 보여줄 수 있다.
  • 보통, 한번에 한 뷰 컨트롤러의 뷰만 볼 수 있다.
  • 뷰 컨트롤러는 다른 뷰 컨트롤러를 제공하거나 다른 뷰 컨트롤러의 콘텐츠에 대한 컨테이너 역할을 하고 원하는대로 뷰를 애니메이션 할 수 있다.


Subclassing Note

  • 모든 앱은 적어도 UIViewController를 상속받는 커스텀 클래스 하나를 포함한다.
  • 더 나아가, 그이상의 커스텀 뷰 컨트롤러 들을 포함 할 수 있다.
  • 커스텀 뷰 컨트롤러들은 앱의 모든 행위를 정의한다.
  • 자세히 정리한 View Controller Programming Guide for iOS를 살표보자!


View Management

  • 각각의 뷰 컨트롤러는 뷰의 계층을 관리하며, 이 계층의 루트 뷰는 그 클래스 뷰 프로퍼티에 저장된다.
  • 루트 뷰는 나머지 계층에 있는 뷰들의 컨테이너로서 행동한다.
  • 즉, 루트뷰의 크기나 포지션은 부모 뷰 컨트롤러 또는 앱의 윈도우의 루트뷰를 소유한 개체에 의해 결정됨
  • 윈도우에서 소유한 뷰컨트롤러는 앱의 루트 뷰 컨트롤러이며, 해당 보기는 창을 채우도록 크기가 조정됨.
  • 뷰 컨트롤러는 뷰를 느리게 로드함
  • 뷰 속성에 처음 엑세스하면 뷰컨트롤러의 뷰가 로드되거나 생성됨.
  • 뷰 컨트롤러에 대한 뷰를 지정하는 방법은 여러가지가 있다.

뷰 컨트롤러는 그것의 뷰와 그것이 생성하는 모든 하위뷰의 유일한 소유자임. 뷰 컨트롤러가 해제될 때와 같이 적절한 시점에 뷰를 생성하고, 소유권을 포기하는 책임이 있다. 만약에 뷰 객체를 저장하기 위해 nib이나 storyboard를 이용한다면, 각각의 뷰 컨트롤러 객체는 자동적으로 그 뷰들의 복사본을 얻어 사용한다. 그러나 뷰를 수동으로 생성하는 경우 각 뷰 컨트롤러에는 각 고유한 뷰 집합이 있어야한다. 그리고 뷰 컨트롤러 간에 뷰를 공유할 수 없다.



Handling View-Related Notifications

  • will 콜백 함수는 did 콜백 함수와 항상 짝을 이루진 않는다.


Handling View Rotations

  • iOS 8 이전에, 회전 관련 메소드는 삭제되었음.
  • 대신에 회전은 뷰 컨트롤러의 뷰 크기 변경으로 처리되므로 viewWillTransition(to:with:)매서드를 사용하여 보고됨
  • 인터페이스 방향이 변경되면 UIKit은 window의 루트 뷰 컨트롤러에서 이 메서드를 호출함.
  • 그러고 뷰컨트롤러는 자식 뷰 컨트롤러에 이를 알리고 뷰 컨트롤러 계층 구조 전체에 메시지를 전파.
  • iOS 6,7에서 앱은 앱 Info.plist에 정의된 인터페이스 방향을 지원한다.
  • 뷰 컨트롤러는 지원되는 방향 목록을 제한하기 위해 supportedInterfaceOrientations 메서드를 재정의 할 수 있다.
  • 일반적으로 시스템은 창의 루트 뷰 컨트롤러 또는 전체 화면을 채우기 위해 표시되는 뷰 컨트롤러에서만 이 메서드를 호출
  • 자식 뷰컨트롤러는 부모 뷰 컨트롤러가 제공한 윈도우의 일부를 사용하고 더 이상 지원되는 회전에 대한 결정에 직접 참여하지 않는다.
  • 뷰컨트롤러에서 최전 하는동안, willRotate(to:duration:), willAnimateRotation(to:duration:), didRotate(from:) 메서드가 호출된다.
  • viewWillLayoutSubviews() 메서드도 부모로부터 재배치 되거나 다시 크기가 정해지면 호출된다.


관련 함수 간단 정리

  • viewWillLayoutSubviews() : 뷰 컨트롤러의 뷰가 하위 뷰를 배치하려고 할 때 알려주는 메서드
  • viewWillTransition(to:with:) : 뷰컨트롤러의 뷰의 사이즈가 바뀌면 메서드 호출. 예를들면 가로 -> 세로 , 세로-> 가로 모드 가 바뀌면 호출
    • 만약에 뷰컨트롤러가 방향이 바뀔 때 보이지 않는 상황이라면, 회전 메소드는 호출되지 않는다.
  • statusBarOrientation : 13.0이상부터 삭제됨.


런치 타임에, 앱은 항상 portrait 방향을 설정해야함. application(_:didFinishLaunchingWithOptions:) 메서드가 반환하고 나면, 앱은 뷰 컨트롤러의 회전 메카니즘을 사용하여 창을 표시하기 전에 뷰를 적절한 방향으로 회전한다.



Implementing a Container View Controller

  • UIViewController의 자식 클래스 또한 컨테이너 뷰 컨트롤러로써 행동한다.
  • 컨테이너 뷰 컨트롤러는 그것의 자식과 연결하기 위해 public한 인터페이스를 선언해야한다.
  • 그리고 뷰컨트롤러에 한번에 얼마나 많은 자식들을 보일 것인지 결정해야함.
  • addChild(_:) : 현재 뷰컨트롤러에 특정한 뷰컨트롤러를 자식으로서 추가함.
  • removeFromParent() : 현재 뷰 컨트롤러를 부모로부터 제거함.
  • willMove(toParent:) : 컨테이너 뷰컨트롤러에 뷰컨트롤러가 제거나 추가 되기 직전에 불러짐.
  • didMove(toParent:) : 컨테이너 뷰컨트롤러에 뷰컨트롤러가 제거나 추가된 후 불러짐.


컨테이너 뷰 컨트롤러를 만들때 어떠한 메소드도 오버라이드 할 필요가 없다. 기본적으로 회전이나 외형 콜백들은 자식에 자동으로 들어간다. 선택적으로 shouldAutomaticallyForwardRotationMethods()shouldAutomaticallyForwardAppearanceMethods 메소드를 오버라이드하여 이 동작들을 제어할 수 있다. 사실 shouldAutomaticallyForwardRotationMethods는 현재 제거됨. shouldAutomaticallyForwardAppearanceMethods 얘는 아직있음



Memory Management

  • iOS에서 메모리는 중요한 요소임.
  • 뷰 컨트롤러는 크리티컬한 시간에 메모리 공간을 줄이기 위한 Built-in을 지원함
  • UIViewController 클래스는 불필요한 메모리를 해제하는 didReceiveMemoryWarning() 메서드를 통해 낮은 메모리 상태를 자동으로 처리.
  • didReceiveMemoryWarning : 메모리에 경고 사항이 있을 때, 뷰 컨트롤러에게 보내는 메소드. 앱이 직접적으로 호출하지 않음.


State Preservation and Restoration

  • 뷰 컨트롤러의 restorationIdentifier 프로퍼티에 값을 지정해주면, 시스템은 뷰컨트롤러에게 앱이 백그라운드에서 전환될때 자체 인코딩을 요청할 수 있음.
  • 뷰 컨트롤러를 보존하면, restorationIdentifier들을 가지고있는 모든 뷰 계층들의 상태를 유지할 수 있음.


@Youngminah
Copy link
Owner Author

Responding to View-Related Events

  • isBeingPresented : Modal로 뷰컨의 뷰가 띄워지고 있으면 true
  • isBeingDismissed : Modal로 뷰컨의 뷰가 사라지고있으면 false
  • isMovingToParent : Push로 뷰컨의 뷰가 띄워지고 있으면 true
  • isMovingFromParent : Push로 뷰컨의 뷰가 사라지고있으면 false


image



image



@Youngminah
Copy link
Owner Author

Youngminah commented Apr 22, 2022

Managing the View

  • view : 뷰컨트롤러의 뷰 계층을 관리하는 루트 뷰
  • viewIfLoaded -> UIView? : 루트 뷰가 로드되어있으면 루트뷰를 리턴하고 아니면 nil 리턴
  • isViewLoaded -> Bool : 루트 뷰가 로드되어있으면 true 리턴 아니면 false 리턴
  • loadView : 생명주기 가장 첫번째 단계 함수. 뷰컨트롤러는 요청된 루트뷰가 nil이라면 이 메소드를 호출함. 직접적 호출 노노
  • loadViewIfNeeded : 루트뷰가 로드되어 있지 않으면 뷰컨트롤러의 루트뷰를 로드한다.
  • title : 네비게이션 이나 탭바의 타이틀
    • Navi -> Tabbar -> VC 순으로 Childe View Controller를 쌓은 경우
    • VC에서 title을 변경하면 Navi는 변경안되고, Tabbar만 변경
    • image
    • Tabbar -> Navi -> VC 순으로 Child View Controller를 쌓은 경우
    • VC에서 title을 변경하면 Tabbar, Navi의 item title 모두 변경
    • image
  • preferredContentSize : 주로 팝 오버에 뷰컨트롤러의 내용을 표시할 때 주로 사용.
@IBAction func buttonTap(_ sender: Any) {
        guard let c = self.storyboard?.instantiateViewController(withIdentifier: "YellowViewController") else {
            return
        }
        c.modalPresentationStyle = .popover
        if let popover = c.popoverPresentationController {
           popover.sourceView = self.view
           popover.permittedArrowDirections = UIPopoverArrowDirection.init(rawValue: 0)
           popover.sourceRect = CGRect(x: self.view.bounds.width, y: self.view.bounds.height/2, width: 1, height: 1)
           c.preferredContentSize = CGSize(width: 500, height: 400)
           popover.delegate = self
        }
        self.present(c, animated: true)
    }
    
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
       return UIModalPresentationStyle.none
    }

@Youngminah
Copy link
Owner Author

Getting Other Related View Controllers

  • presentationController : 현재 뷰 컨을 관리하는 프레젠테이션 컨트롤러 반환
  • presentedViewController : 현재 뷰 컨에서 모달로 띄워진 뷰컨트롤러를 반환, 없으면 nil
  • presentingViewController : 현재 뷰 컨이 어떠한 뷰컨에서 모달로 띄워진 뷰컨이라면, 현재 뷰 컨을 띄웠던 뷰컨트롤러 반환 없으면 nil
    • 참고로 현재 뷰 컨을 띄웠던 상위 뷰컨트롤러가 ContainerViewController가 있다면 최상위 ContainerViewController를 반환한다.


UIPresentationController란?

  • 뷰 컨트롤러의 전환 애니메이션을 담당하는 컨트롤러.
  • present()메소드를 이용하여 뷰컨트롤러를 띄우면 , UIKit은 항상 프레젠테이션 과정을 거친다.

@Youngminah
Copy link
Owner Author

Presentation Controller - from to container completion cancel gesture
CollectionView - layout(테이블뷰와의 다른점) compositional, flowlayout

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant