[번역] UIView (애플 공식 문서)

삭제된 Velog·2024년 8월 25일

UIKit

목록 보기
5/21
post-thumbnail

본 글은 UIView (애플 공식 문서)를 한국어로 번역하여 옮긴 글입니다.

화면의 사각 영역 컨텐츠를 관리하는 객체(object)

iOS 2.0+ | iPadOS 2.0+ | Mac Catalyst 13.1+ | visionOS 1.0+

@MainActor
class UIView : UIResponder

Overview

뷰는 앱의 사용자 인터페이스를 이루는 기본적인 요소(blocks)이며, UIView 클래스는 모든 뷰에 대한 공통적인 기능을 정의합니다. 뷰 객체는 자신의 경계 사각형(bounds rectangle) 내에서 컨텐츠를 그리며, 해당 컨텐츠와의 모든 상호작용을 처리합니다. UIView는 인스턴스화(instantiate)하여 고정된 백그라운드 색상을 보여줄 수 있는 구체적인 클래스입니다. 이를 서브 클래스하여 더 세련된 컨텐츠를 그릴 수 있습니다. 레이블, 이미지, 버튼과 앱의 일반적인 다른 인터페이스 요소를 보여주기 위해, 직접 정의하려고 시도하기 보다는 UIKit 프레임워크가 제공하는 뷰 서브 클래스를 사용하세요.

뷰 객체는 앱이 사용자와 상호작용을 하는 주요한 방법이기에, 다수의 책임을 가지고 있습니다. 아래는 그 일부입니다.

  • 애니메이션과 그리기

    • 뷰는 UIKit 또는 코어 그래픽스(Core Graphics)를 사용하여 사각 영역에 컨텐츠를 그립니다.
    • 일부 뷰 속성을 새로운 값으로 애니메이션할 수 있습니다.
  • 레이아웃과 하위 뷰 관리

    • 뷰는 원하는 만큼의 하위 뷰를 포함할 수 있습니다.
    • 뷰는 하위 뷰의 크기와 위치를 조정할 수 있습니다.
    • 오토 레이아웃을 사용하여 뷰 계층 구조의 변화에 따라 뷰의 크기와 위치 재조정을 위한 규칙을 정의하세요.
  • 이벤트 처리

    • 뷰는 UIResponder의 서브 클래스이고 터치나 다른 타입의 이벤트에 반응할 수 있습니다.
    • 뷰는 일반적인 제스처를 처리하기 위해 제스처 인식자(gesture recognizers)를 설치할 수 있습니다.

뷰는 다른 뷰 내부에 중첩되어 관련된 컨텐츠를 편리하게 구성하도록 하는 뷰 계층 구조를 만들 수 있습니다. 뷰를 중첩하면 중첩된 자식 뷰(하위 뷰)와 부모 뷰(상위 뷰) 사이에서 부모-자식 관계를 형성합니다. 부모 뷰는 많은 자식 뷰를 포함할 수 있는 반면에, 각 자식 뷰는 오직 하나의 상위 뷰만 가집니다. 기본적으로, 하위 뷰의 가시 영역이 상위 뷰의 경계를 벗어난다면, 하위 뷰의 컨텐츠가 짤리지는 않습니다. 해당 동작을 변경하려면 clipsToBounds 프로퍼티를 사용하세요.

framebounds는 각 뷰의 지오메트리(geometry)를 정의합니다. frame 프로퍼티는 상위 뷰의 좌표 시스템에서 뷰의 원점과 크기를 정의합니다. bounds 프로퍼티는 뷰가 내부적으로 인식하는 자신의 크기를 정의하며, 주로 커스텀 드로잉 코드에서 사용됩니다. center 프로퍼티는 frame이나 bounds 프로퍼티를 직접 변경하지 않고도 뷰의 위치를 쉽게 조정할 수 있는 편리한 방법을 제공합니다.

⭐️ 김지지의 NOTE

  • frame은 뷰의 위치와 크기를 상위 뷰의 좌표 시스템에서 계산합니다. 뷰의 위치가 (100, 100)이라면 상위 뷰를 기준으로 (100, 100) 위치에 뷰가 그려진다는 의미입니다. transform 프로퍼티가 identity가 아니라면 해당 프로퍼티는 무시됩니다.
  • bounds는 뷰의 위치와 크기를 자신만의 좌표 시스템에서 계산합니다. 뷰의 위치가 (100, 100)이라면 상위 뷰가 해당 뷰를 (0, 0) 위치로서 바라보는 위치를 (100, 100)으로 이동하겠다는 의미입니다. frame과는 다르게 뷰가 회전하면 bounds 사각 영역도 함께 회전합니다.

UIView 클래스를 사용하는 더 자세한 정보는 View Programming Guide for iOS를 참조하세요.

Create a view

일반적으로, 라이브러리에서 캔버스로 뷰를 드래그하여 스토리보드에서 뷰를 생성할 수 있습니다. 코드로도 뷰를 생성할 수 있습니다. 뷰를 생성할 때, 해당 뷰의 미래 상위 뷰를 기준으로 초기 크기와 위치를 명시해야 합니다. 예를 들어, 아래 예제는 뷰를 생성하고 해당 뷰를 상위 뷰의 좌표 시스템을 기준으로 상단-왼쪽으로부터 (10, 10) 포인트 떨어진 곳에 위치시킵니다.

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

뷰에 하위 뷰를 추가하려면, 상위 뷰의 addSubview(_:) 메서드를 호출하세요. 하나의 뷰에 원하는 만큼의 하위 뷰를 추가할 수 있으며, 동일 계층 뷰(sibling view)는 iOS에서 아무런 문제 없이 서로 겹쳐질 수 있습니다. addSubview(_:) 메서드를 호출할 때마다 새로운 뷰는 다른 동일 계층 뷰들 위에 위치하게 됩니다. insertSubview(_:aboveSubview:)insertSubview(_:belowSubview:) 메서드를 사용하여 하위 뷰를 추가할 때, 해당 뷰의 상대적인 Z축 순서를 지정할 수 있습니다. exchangeSubview(at:withSubviewAt:) 메서드를 사용하여 이미 추가된 하위 뷰들의 위치를 서로 바꿀 수 있습니다.

뷰를 생성하고 나면, 나머지 뷰 계층 구조의 변화에 반응하여 해당 뷰의 크기와 위치를 어떻게 할 지 결정하기 위한 오토 레이아웃 규칙을 생성합니다. 더 많은 정보를 보려면 Auto Layout Guide를 참조하세요.

Draw views

뷰 그리기는 필요할 때마다 수행됩니다. 뷰가 처음 보여질 때, 레이아웃 변화로 인해 전체나 일부 뷰가 보여지기 시작할 때, 시스템은 뷰에게 컨텐츠 그리기를 요청합니다. UIKit이나 Core Graphics를 사용하여 그린 커스텀 컨텐츠를 포함하는 뷰의 경우, 시스템은 뷰의 draw(_:) 메서드를 호출합니다. 이 메서드의 구현에서는 해당 메서드가 호출되기 전 시스템에 의해 자동으로 설정되는 그래픽 컨텍스트(context)에 뷰의 컨텐츠를 그려야 하는 책임이 있습니다. 이 메서드는 뷰의 컨텐츠에 대한 정적인 시각적 표현을 생성하며, 이후 이를 화면에 표시할 수 있습니다.

뷰의 실질적인 컨텐츠가 변경되면, 개발자는 뷰가 다시 그려져야 한다고 시스템에게 알릴 필요가 있습니다. 뷰의 setNeedsDisplay()setNeedsDisplay(_:) 메서드를 호출하여 뷰의 다시 그리기를 요청할 수 있습니다. 이 메서드는 다음 그리기 사이클(drawing cycle) 동안에 뷰가 업데이트되어야 한다고 시스템이 알게 합니다. 이 메서드는 다음 그리기 사이클까지 기다린 후 뷰를 업데이트하므로, 여러 뷰에서 이 메서드를 호출하여 동일한 시간에 뷰를 업데이트할 수 있습니다.

⚪️ NOTE
그리기에 OpenGL ES를 사용한다면, UIView를 서브 클래싱하는 대신 GLKView 클래스를 사용해야 합니다. 어떻게 OpenGL ES를 사용하여 그리는 지는 OpenGL ES Programming Guide를 참조하세요.

뷰 그리기 사이클과 사이클에서 뷰가 하는 역할에 대한 자세한 정보는 View Programming Guide for iOS를 참조하세요.

Animate views

일부 뷰 프로퍼티의 변경은 애니메이션으로 처리될 수 있습니다. 즉, 프로퍼티를 변경하면 현재 값에서 시작하여 지정한 새로운 값까지 움직이는 애니메이션을 생성합니다. 아래 UIView의 프로퍼티는 애니메이션이 가능합니다.

변경 사항을 애니메이션하려면, UIViewPropertyAnimator 객체를 생성하고 해당 객체의 핸들러 블록(handler block)을 사용하여 프로퍼티의 값을 변경하세요. UIViewPropertyAnimator 클래스는 애니메이션의 지속 시간과 타이밍을 지정하며, 실제 애니메이션도 수행합니다. 현재 실행 중인 프로퍼티 기반 애니메이터는 애니메이션을 중단(interrupt)하고 역동적인 동작을 위해 멈출(pause) 수 있습니다. 더 자세한 정보는 UIViewPropertyAnimator를 참조하세요.

Threading considerations

앱의 사용자 인터페이스에 대한 조작은 반드시 메인 쓰레드에서 이루어져야 합니다. 그러므로, 개발자는 UIView 클래스의 메서드를 앱의 코드가 메인 쓰레드에서 동작하고 있을 때 호출해야 합니다. 이 점이 엄격하게 필요하지 않은 때는 뷰가 스스로 객체를 생성할 때 뿐이며, 이 밖에 다른 모든 조작은 메인 쓰레드에서 이루어져야 합니다.

Subclassing notes

UIView 클래스는 사용자 상호작용을 필요로 하는 시각적인 컨텐츠를 위한 핵심 서브 클래싱 포인트입니다. UIView를 서브 클래싱하는 데는 많은 타당한 이유가 있겠지만, 기본적인 UIView 클래스나 시스템 표준 뷰가 필요로 하는 기능을 제공하지 않을 때만 서브 클래싱을 하는 걸 권장합니다. 서브 클래싱은 뷰를 구현하고 성능을 높이기 위해 많은 노력을 요구합니다.

서브 클래싱을 피하는 방법에 대한 자세한 정보는 Alernatives to subclassing을 참조하세요.

Methods to override

UIView를 서브 클래싱할 때, 반드시 재정의를 해야 하는 일부 메서드가 있으며, 필요에 따라 (선택적으로) 재정의를 해야 하는 메서드가 있습니다. UIView 클래스는 강력한 구성 가능한 클래스(configurable class)이므로, Alternatives to Subclassing 섹션에서 언급한 커스텀 메서드를 재정의하지 않고도 복잡한 뷰를 구현하는 다양한 방법이 있습니다. 아래 목록은 UIView 서브 클래스에서 재정의할 것을 고려할 수 있는 메서드를 포함하고 있습니다.

  • 초기화:

    • init(frame:) - 이 메서드를 구현하는 걸 권장합니다. 이 메서드를 대신하거나 추가로 커스텀 이니셜라이저 메서드를 구현할 수도 있습니다.
    • init(coder:) - 스토리보드나 nib 파일에서 뷰를 로드하거나 커스텀 이니셜라이저를 요구한다면 이 메서드를 구현하세요.
    • layerClass 뷰가 백킹 스토어(backing store)에 다른 코어 애니메이션 레이어를 사용하길 원한다면 이 프로퍼티를 사용하세요. 예를 들어, 뷰에 거대한 스크롤 가능한 영역 표시를 위해 타일링(tiling)을 사용한다면, 해당 프로퍼티를 CATiledLayer로 설정할 수 있습니다.
  • 그리기와 출력:

    • draw(_:) - 뷰에 커스텀 컨텐츠를 그려야 한다면 이 메서드를 구현하세요. 뷰가 아무것도 그려야 할 필요가 없다면, 해당 메서드를 재정의하지 마세요.
    • draw(_:for:) - 뷰에 커스텀 컨텐츠를 다르게 그려야 한다면 이 메서드를 구현하세요.
  • 레이아웃과 제약:

⭐️ 김지지의 NOTE

  • requiresConstraintBasedLayout 클래스 프로퍼티는 뷰가 제약 기반 레이아웃 시스템을 필수로 요구하는지 여부를 나타냅니다. 값이 true라면 해당 뷰는 반드시 제약 기반 레이아웃 시스템을 사용합니다.
  • translatesAutoresizingMaskIntoConstraints 프로퍼티는 프레임 기반 레이아웃을 제약 기반 레이아웃 시스템으로 변환할지 여부를 나타냅니다. 값이 true라면 프레임 기반 레이아웃을 제약 기반 레이아웃 시스템으로 자동으로 변환합니다. 코드로 제약 기반 레이아웃 시스템을 적용하려면 값을 false로 설정해야 합니다.

Alternatives to subclassing

많은 뷰의 동작은 서브 클래싱 없이도 구성될 수 있습니다. 메서드를 재정의하기 전에, 아래 프로퍼티나 동작을 수정하는 게 필요로 하는 기능을 제공할 수 있을지 고려해보세요.

  • addConstraint(_:) - 뷰와 하위 뷰에 대한 자동 레이아웃 동작을 정의하세요.

  • autoresizingMask - 상위 뷰의 프레임이 변할 때 자동 레이아웃 동작을 정의하세요. 이 동작은 다른 제약과 결합될 수 있습니다.

  • contentMode - 뷰의 프레임과 배치되는 뷰의 컨텐츠에 대한 레이아웃 동작을 정의하세요. 이 프로퍼티는 컨텐츠가 어떻게 뷰에 알맞게 커지는지나 캐시되는지 또는 다시 그려지는지에도 영향을 끼칩니다.

  • isHidden 또는 alpha - 뷰의 렌더링된 콘텐츠에 알파를 적용하거나 숨김을 하는 것보다 뷰 전체의 투명도를 변경하세요.

  • backgroundColor - 색을 직접 그리는 것보다 뷰의 색상을 설정하세요.

  • Subviews - 콘텐츠를 그리기 위해 draw(_:) 메서드를 사용하는 것보다 표시하길 원하는 컨텐츠의 이미지나 레이블 하위 뷰를 포함하세요.

  • Gesture recognizers - 서브 클래스에서 터치 이벤트를 직접 처리하거나 가로채기보다 제스처 인식기를 사용하여 타깃 객체에서 처리해야 할 동작을 정의하세요.

  • Animations - 직접 애니메이션 적용을 시도하기보다 빌트-인 애니메이션을 사용하세요. Core Animation에서 제공되는 애니메이션은 빠르고 사용하기 쉽습니다.

  • Image-based backgrounds - 비교적 정적인 콘텐츠를 뷰에 보여주고자 한다면 직접 이미지를 그리거나 서브클래싱을 하기 보다 제스처 인식기를 사용하는 UIImageView를 사용하는 걸 고려하세요. 또는, 일반적인 UIView 객체를 사용하고, 해당 뷰의 CALayer 객체의 콘텐츠로 이미지를 할당하세요.

애니메이션은 서브 클래싱이나 복잡한 그리기 코드를 구현하지 않더라도 뷰에 시각적인 변화를 줄 수 있는 또 다른 방법입니다. UIView 클래스의 많은 프로퍼티는 애니메이션 적용이 가능합니다. 이는 해당 프로퍼티 값을 변경하는 것 만으로 시스템이 생성하는 애니메이션을 트리거할 수 있다는 의미입니다. 애니메이션을 시작하려면 모든 변경 사항이 애니메이션되어야 한다는 걸 나타내는 적어도 한 줄의 코드가 필요합니다. 뷰의 애니메이션 지원에 대한 자세한 정보는 Animate views를 참조하세요.

참고 자료

profile
rlarjsdn3.github.io

0개의 댓글