UIView

Panther·2021년 8월 19일
0

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

"An object that manages the content for a rectangular area on the screen."

스크린에 있는 사각형 영역에서 컨텐트를 관리하는 객체입니다.

Declaration

@MainActor class UIView : UIResponder

Overview

뷰는 앱 UI의 근본적인 빌딩 블록이며, UIView 클래스는 모든 뷰에 대해 일반적인 동작을 정의합니다. 뷰 객체는 스스로의 bounds 사각형 내에서 컨텐트를 렌더링하고, 해당 컨텐트에 대한 모든 상호작용을 처리합니다. UIView 클래스는 인스턴스화 할 수 있고 고정된 백그라운드 색성을 나타내기 위해 사용할 수 있는 구체화 클래스입니다. 더 복잡한 컨텐트를 드로잉하기 위해서 UIView를 서브클래싱 할 수도 있습니다. 앱에서 흔하게 볼 수 있는 레이블, 이미지, 버튼, 기타 인터페이스 요소를 표시하려면 스스로 직접 정의해서 생성하기보다는 UIKit 프레임워크가 제공하는 뷰 서브클래스를 사용하시기 바랍니다.

뷰 객체는 애플리케이션이 사용자와 상호작용하는 주요 방법이기 때문에 뷰 객체는 몇 가지 책임을 갖습니다. 아래는 그 중 몇 가지를 보여주고 있습니다.

  • 드로잉 및 애니메이션입니다.
    • 뷰는 UIKit 혹은 코어 그래픽스를 사용해서 뷰의 사각형 영역에 컨텐트를 드로잉합니다.
    • 특정 뷰 속성을 새 값으로 애니메이션 처리할 수 있습니다.
  • 레이아웃과 하위뷰 관리입니다.
    • 뷰는 하위뷰를 포함하고 있지 않거나 몇 가지 하위뷰를 포함할 수 있습니다.
    • 뷰는 자신이 갖는 하위뷰의 크기와 위치를 조정할 수 있습니다.
    • 뷰 계층구조에서 변경에 대한 응답으로 뷰를 리사이징하고 위치조정을 하는 규칙을 정의하려면 오토 레이아웃을 사용하시기 바랍니다.
  • 이벤트 처리입니다.
    • 뷰는 UIResponder의 서브클래스이며, 터치 및 기타 이벤트의 타입에 응답할 수 있습니다.
    • 뷰는 일반적인 제스쳐를 처리하기 위해 제스쳐 리코그나이저를 설치할 수 있습니다.

뷰는 관련 컨텐트를 조직하기에 편리한 방법을 제공하고자 하는 맥락으로, 뷰 계층구조를 생성하기 위해서 다른 뷰를 내부에 중첩시킬 수 있습니다. 뷰를 중첩시키는 것은 중첩된 자식 뷰(하위뷰라고도 알려진)와 부모(슈퍼뷰라고도 알려진) 사이에 부모 자식 관곌르 생성합니다. 부모 뷰는 여러 하위뷰를 가질 수 있지만, 각 하위뷰는 오직 하나의 슈퍼뷰만 갖습니다. 기본값으로 하위뷰의 시각적 영역이 슈퍼뷰의 bounds 바깥으로 뻗어나가면, 하위뷰의 컨텐트 잘림은 발생하지 않습니다. 해당 동작을 변경하려면 clipsToBounds 속성을 사용해야 합니다.

프레임과 bounds 속성은 각 뷰의 기하적 특성을 정의합니다. 프레임 속성은 슈퍼뷰의 좌표 시스템에서 뷰의 원점과 차원을 정의합니다. bounds 속성은 보는대로 뷰의 내부 차원을 정의하며, bounds의 사용은 대부분 커스텀 드로잉 코드에서만 사용됩니다. 중심 속성은 뷰의 프레임 혹은 bounds 속성을 직접 변경시키지 않고도 뷰의 위치를 재설정할 수 있는 편리한 방법을 제공합니다.

UIView 클래스 사용 방법에 대한 자세한 정보는 View Programming Guide for iOS를 보시기 바랍니다.

View Programming Guide for iOs
https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/index.html
https://velog.io/@panther222128/series/View-Controller-Programming-Guide-for-iOS

Creating a View

보통은 라이브러리로부터 캔버스로 뷰를 드래그하는 방법으로 스토리보드에서 뷰를 생성할 것입니다. 코드 작성으로 뷰를 생성할 수도 있습니다. 뷰를 생성할 때 초기 크기 및 위치를 슈퍼뷰에 상대적인 형태로 구체화할 것입니다. 예를 들어 아래 예시는 뷰를 생성하고 슈퍼뷰의 좌표 시스템에서 왼쪽 상단 모서리의 (10, 10) 포인트 떨어지도록 위치시키고 있습니다(해당 슈퍼뷰에 추가되는 경우).

let rect = CGRect(x: 10, y: 10, width: 100, height: 100)
let myView = UIView(frame: rect)

다른 뷰에 하위뷰를 추가하려면 슈퍼뷰에서 addSubview(_:) 메소드를 호출해야 합니다. 뷰에 여러 하위뷰를 추가할 수 있으며, 형제 뷰는 iOS에서 문제없이 서로 겹칠 수 있습니다. 각각의 addSubview(_:) 메소드 호출은 다른 모든 형제뷰의 위로 새로운 뷰를 위치시킵니다. insertSubview(_:aboveSubview:)insertSubview(_:belowSubview:) 메소드를 사용해서 하위뷰의 상대적 z-order를 구체화시킬 수 있습니다. exchangeSubview(at:withSubviewAt:) 메소드를 사용해서 기존에 추가된 하위뷰의 위치를 교환할 수도 있습니다.

뷰 생성 후, 뷰 계층구조 나머지 부분의 변경사항에 대한 응답으로 뷰의 크기 및 위치를 어떻게 바꿀 것인지 제어할 수 있도록 오토 레이아웃 규칙을 생성하시기 바랍니다. 더 많은 정보는 Auto Layout Guide를 보시기 바랍니다.

Auto Layout Guide
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html
https://velog.io/@panther222128/series/Auto-Layout-Guide

The View Drawing Cycle

뷰 드로잉은 필요한 시점에 기반해서 발생합니다. 뷰가 처음으로 나타나거나 뷰의 모든 혹은 부분이 레이아웃 변경으로 인해 시각화되면, 시스템은 뷰에게 가지고 있는 컨텐츠를 드로잉하도록 요청합니다. UIKit 혹은 코어 그래픽스를 사용하고 있는 컨텐트를 포함한 뷰의 경우 시스템은 뷰의 draw(_:) 메소들르 호출합니다. 이 메소드의 구현은 시스템이 '이 메소드의 호출보다 선행되도록 자동으로 설정한 현재 그래픽스 컨텍스트'에서 뷰의 컨텐트를 드로잉할 책임이 있습니다. 이는 스크린에 표시될 수 있는 뷰 컨텐트의 정적 시각화 표현을 생성합니다.

뷰의 실제 컨텐트가 변경될 때 뷰가 다시 그려져야 한다고 시스템에게 알리는 것은 직접 구현해야 합니다. 뷰의 setNeedsDisplay() 혹은 setNeedsDisplay(_:) 메소들르 호출해서 그렇게 할 수 있습니다. 이 메소드들은 시스템이 다음 드로잉 주기 동안 뷰를 업데이트해야 함을 알 수 있도록 해줍니다. 뷰를 업데이트하기 위해 다음 드로잉 주기까지 기다려야 하는 이유로, 동시에 뷰들을 업데이트하려면 여러 뷰에 대해서 이 메소드들을 호출할 수 있습니다.

Note
드로잉을 하기 위해 OpenGL ES를 사용하고 있다면 UIView 서브클래싱 대신 GLKView 클래스를 사용해야 합니다. OpenGL ES 사용 방법에 대한 더 많은 정보는 OpenGL ES Programming Guide를 보시기 바랍니다.

OpenGL Programming Guide
https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008793

뷰 드로잉 주기 및 이 주기에서 뷰 가 갖는 역할에 대한 더 자세한 정보는 View Programming Guide for iOS를 보시기 바랍니다.

View Programming Guide for iOs
https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/index.html
https://velog.io/@panther222128/series/View-Controller-Programming-Guide-for-iOS

Animations

몇 가지 뷰 속성에 대한 변경은 애니메이션 처리될 수 있습니다(즉 속성을 변경하는 것은 현재 값에서 애니메이션을 시작하는 것과 구체화한 새로운 값으로 애니메이션이 끝나는 애니메이션을 생성할 수 있습니다). UIView 클래스의 다음 속성이 애니메이션 가능한 속성입니다.

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor

변경사항에 애니메이션 처리를 하려면 UIViewPropertyAnimator 객체를 생성하고, 뷰 속성의 값을 변경시키기 위해 이 객체의 핸들러 블록을 사용하시기 바랍니다. UIViewPropertyAnimator 클래스는 애니메이션의 듀레이션 및 타이밍을 구체화할 수 있게 해주면서 실제 애니메이션을 수행합니다. 애니메이션을 인터럽트하고 상호작용으로 움직이게 하기 위해서 현재 동작하고 있는 속성 기반 애니메이터를 일시정지할 수 있습니다.더 많은 정보는 UIViewPropertyAnimator를 보시기 바랍니다.

UIViewPropertyAnimator
https://developer.apple.com/documentation/uikit/uiviewpropertyanimator
https://velog.io/@panther222128/UIViewPropertyAnimator

Threading Considerations

애플리케이션의 UI 조작은 메인 스레드에서 발생해야 합니다. 그러므로 항상 애플리케이션의 메인 스레드에서 실행하는 코드로부터 UIView 클래스의 메소드를 호출해야 합니다. 이와 같은 내용이 반드시 지켜지지 않아도 되는 경우는 뷰 객체 자체를 생성할 때입니다. 하지만 다른 모든 조작은 메인 스레드에서 발생해야 합니다.

Subclassing Notes

UIView 클래스는 사용자 상호작용 또한 요구하는 시각적 컨텐트의 핵심 서브클래싱 포인트입니다. UIView를 서브클래싱하는 많은 이유들이 있지만, 기본적인 UIView 클래스 혹은 표준 시스템 뷰가 기능을 제공하지 않는 경우에만 권장합니다. 서브클래싱은 뷰 구현 및 뷰의 성능 튜닝을 위해 더 많은 작업을 요구합니다.

서브클래싱을 피하는 방법에 대한 정보는 Alternatives to Subclassing을 보시기 바랍니다.
Alternatives to Subclassing은 아래에 나옵니다.

Methods to Override

UIView를 서브클래싱할 때 오버라이드 해야 하는 메소드는 몇 가지 뿐이고, 필요에 다라 오버라이드할 수 있는 여러 가지 메소드도 존재합니다. UIView는 고수준으로 설정 가능한 클래스이기 때문에 Alternatives to Subclassing 섹션에서 이야기하고 있는 커스텀 메소드의 오버라이드 없이도 복잡한 뷰 동작을 구현할 수 있는 많은 방법이 존재합니다. 아래 리스트는 UIView 서브클래스에서 오버라이드를 고려하게 되는 메소드를 포함하고 있습니다.

  • 초기화입니다.

    • init(frame:) - 이 메소드 구현을 권장합니다. 추가적인 혹은 이 메소드를 대신할 수 있는 커스텀 초기화 메소드 구현 또한 가능합니다.
    • init(coder:) - 스토리보드 혹은 nib 파일로부터 뷰를 로드하는 경우 이 메소드를 구현해야 하며, 뷰는 커스텀 초기화가 필요합니다.
    • layerClass 백업 스토어에서 다른 코어 애니메이션 레이어를 사용하는 뷰를 원하는 경우에만 이 속성을 사용하시기 바랍니다. 예를 들어 뷰는가 크고 스크롤 가능한 영역을 표시하기 위해 기울이는 것을 사용하고 있는 경우에 속성을 CATiledLayer 클래스로 설정하길 원할 것입니다.
  • 드로잉 및 프린팅입니다.

    • draw(_:) - 뷰가 커스텀 컨텐트를 그리는 경우 이 메소드를 구현해야 합니다. 뷰가 어떠한 커스텀 드로잉도 하지 않고 있다면 이 메소드 오버라이드는 피해야 합니다.
    • draw(_:for:) - 뷰 컨텐트를 프린팅 동안 다르게 드로잉하길 원하는 경우에만 이 메소드를 구현하시기 바랍니다.
  • 레이아웃과 제약입니다.

    • requiresConstraintBasedLayout 뷰 클래스가 적합하게 작업하기 위해 제약을 요구하는 경우 이 속성을 사용하시기 바랍니다.
    • updateConstraints() - 뷰가 하위뷰 사이에서 커스텀 제약을 생성할 필요가 있는 경우 이 메소드를 사용하시기 바랍니다.
    • alignmentRect(forFrame:), frame(forAlignmentRect:) - 뷰가 다른 뷰에 어떻게 정렬될지를 오버라이드하기 위해 이 메소드들을 구현하시기 바랍니다.
    • didAddSubview(_:), willRemoveSubview(_:) 하위뷰의 추가 및 제거 추적이 필요한 경우에 이 메소드를 구현하시기 바랍니다.
    • willMove(toSuperview:), didMoveToSuperview() - 뷰 계층구조에서 현재 뷰의 이동을 추적할 필요가 있는 경우 이 메소드를 구현하시기 바랍니다.
  • 이벤트 처리입니다.

    • gestureRecognizerShouldBegin(_:) - 뷰가 터치 이벤트를 직접 처리하고 있고 가지고 있는 제스쳐 리코그나이저가 추가적인 액션을 수행하는 것을 막길 원하는 경우 이 메소드를 구현하시기 바랍니다.
    • touchesBegan(_:with:), touchesMoved(_:with:), touchesEnded(_:with:), touchesCancelled(_:with:) - 터치 이벤트를 직접 처리해야 할 필요가 있는 경우 이 메소드를 사용하시기 바랍니다. (제스쳐 기반 입력의 경우 제스쳐 리코그나이저를 사용하시기 바랍니다.)

Alternatives to Subclassing

많은 뷰 동작이 서브클래싱 없이 설정될 수 있습니다. 오버라이드 메소드를 시작하기 전에 아래 속성 혹은 동작을 수정하는 것이 필요한 동작을 제공할 수 있는지 생각해보시기 바랍니다.

  • addConstraint(_:) - 뷰 및 뷰의 하위뷰에 대한 자동 레이아웃 동작을 정의합니다.
  • autoresizingMask - 슈퍼뷰의 프레임이 변경될 때 자동 레이아웃 동작을 제공합니다. 이러한 동작은 제약과 조합될 수 있습니다.
  • contentMode - 뷰의 프레임에 반대로써 뷰의 컨텐트에 레이아웃 동작을 제공합니다. 또한 이 속성은 컨텐트가 뷰에 맞게 스케일되는 방법과 캐시될지 혹은 다시 그려질지를 결정하는 데 영향을 미칩니다.
  • isHidden 혹은 alpha - 뷰의 렌더링된 커컨텐트에 대한 알파를 숨기거나 적용하는 것 대신 뷰 전체의 투명도를 변경시킵니다.
  • backgroundColor - 색상을 직접 그리는 것 대신 뷰의 색상을 설정합니다.
  • Subviews - draw(_:) 메소드를 사용해서 컨텐트를 그리는 것 대신, 나타내고자 하는 컨텐트를 갖는 이미지 및 레이블을 끼워넣습니다.
  • Gesture recognizers - 터치 이벤트를 직접 가로채거나 처리하기 위해 서브클래싱을 하는 것 대신 타깃 객체에 타깃 액션을 보내기 위해 제스쳐 리코그나이저를 사용할 수 있습니다.
  • Animations - 애니메이션 변경을 직접 시도하는 것 대신 내장되 ㄴ애니메이션 지원을 사용합니다. 코어 애니메이션에서 제공하는 애니메이션 지원은 빠르고 사용하기 쉽습니다.
  • Image-based backgroudns - 상대적으로 정적인 컨텐트를 표시하는 뷰의 경우 이미지를 직접 서브클래싱하고 드로잉하는 것 대신 제스쳐 리코그나이저를 갖는 UIImageView 객체 사용을 고려하시기 바랍니다. 대안으로 제너릭 UIView 객체를 사용할 수 있고, 이미지를 뷰의 CALayer 객체 컨텐트로 할당할 수 있습니다.

애니메이션은 서브클래싱 및 복잡한 드로잉 코드 구현 필요 없이 뷰에 대한 시각적 변경을 만드는 다른 방법입니다. UIView 클래스의 많은 속성이 애니메이션 가능합니다. 이는 속성에 대한 변경이 system-generated 애니메이션을 트리거할 수 있음을 의미합니다. 애니메이션 시작은 애니메이션으로 처리되어야 하는 변경사항을 나타내기 위한 적은 줄만의 코드를 요구합니다. 뷰를 위한 애니메이션 지원에 대한 설명은 Animations를 보시기 바랍니다.

Animations는 이 글의 위에 있습니다.

0개의 댓글