UIView
UIView란?
UIView는 화면의 사각형 영역을 관리하는 객체로, 화면을 구성하는 요소들의 기본 클래스입니다. 이 객체는 위치와 크기를 가진 사각형 영역을 정의하며, 배경색을 설정하거나 문자, 이미지와 같은 콘텐츠를 포함할 수 있습니다. 따라서, 앱에서 Label, Image, Button 등 다양한 인터페이스 요소를 표시하려면 UIKit 프레임워크가 제공하는 뷰의 하위 클래스를 사용하면 됩니다. 아래 이미지와 같이 Label, Image, Button은 모든 UIView의 하위 객체라고 생각하면되겠습니다.
선언 방식
@MainActor class UIView: UIResponder
개요
View는 앱의 UI에 있어서 가장 기본적인 구성 요소이며, UIView 클래스 모든 View의 공통적인 동작을 정의합니다. View 객체는 객체의 bounds 사각형 안에서 컨텐츠를 만들며 이 컨텐츠와의 모든 상호 작용들을 처리합니다.
UIView 클래스는 background color를 설정할 수 있는 구체적인 클래스입니다. 또한 이 클래스를 상속 하여 좀 더 정교한 컨텐츠를 그릴 수 있습니다. 앱에서 흔히 보이는 레이블, 이미지, 버튼 및 기타 UI 요소들을 나타내려면 직접 만드는 것보단 UIKit 프레임워크가 제공하는 View를 상속한 것들을 사용하세요.
View 객체는 앱을 통해 사용자와 상호 작용하기 위한 가장 주된 방법이기 때문에 많은 책임이 따릅니다.
첫번째로는 View들은 UIKit 또는 Core Graphics를 이용하여 직사각형 영역안에 컨텐츠를 그립니다. 그리고 View의 속성들을 새로운 값으로 애니메이션을 만들 수도 있습니다. 또한 View들은 0개 이상의 subview를 포함하며 View들은 subview의 size나 position을 조절할 수 있습니다.
오토레이아웃을 사용하여 View의 계층의 변화에 따라 View의 크기와 위치를 변경할 수 있습니다.
View는 UIResponder를 상속받아있어서 터치 및 다른 이벤트에 대해 응답을 할 수 있습니다. 때문에 UIButton과 UIView에 대해 물어보는 질문이 이 때문에 생기는 거죠! 그리고 일반적인 제스쳐를 처리하기 위한 gesture recognizers를 설치할 수 있습니다.
View는 다른 View안에 중첩되어 계층을 형성할 수 있으므로 관련 내용을 쉽게 구성할 수 있습니다. View를 중첩하면 중첩된 자식 뷰와 부모 뷰간의 부모-자식 관계를 형성합니다. 부모 뷰는 원하는 수만큼 subview를 포함할 수 있지만 각각의 subview는 오직 하나의 superview만 존재합니다.
기본적으로 subview의 보여지는 영역이 superview의 bounds보다 넘어가게 되면 subview의 콘텐츠는 잘리지 않게 됩니다. 이를 위해 사용하는 함수가 clipsToBuounds 입니다.
frame과 bounds 속성은 각 View의 기하학적 구조를 정의합니다. frame 속성은 superview의 좌표계에서 View의 원점과 치수를 정의합니다. bounds 속성은 보이는 대로 내부 치수를 정의합니다. center 속성은 View의 frame과 bounds 속성을 직접적으로 사용하지 않고 쉽게 위치를 재정의하는데 사용합니다.
View 생성하기
View를 생성할 때 미래의 superview를 기준으로 사이즈와 위치를 지정합니다. 예를 들어서, 아래 코드는 View를 생성 후 superview의 좌표계에 있는 점 (20,20)에 위치는 왼쪽 상단에 붙게 됩니다.
let rect = CGRect(x: 20, y: 20, width: 100, height: 100)
let myView = UIView(frame: rect)
View에 subview를 추가하면, superview에서 addSubView(_:) 메서드를 호출해야합니다. View에 원하는 수만큼 View를 추가할 수 있고 iOS의 어떤 이슈 없이 View들을 서로 겹칠 수 있습니다.
insertSubview(*:aboveSubview)와 insertSubview(*:belowSubview) 메소드를 사용하여 subview의 상대적인 z-order를 지정할 수 있습니다.
exchangeSubView(at:withSubviewAt) 메소드를 사용하여 이미 추가된 subview의 위치를 바꿀 수도 있습니다.
뷰의 드로잉 사이클
View 드로잉은 필요에 따라 발생하게 됩니다. View가 처음 보여지거나 레이아웃 변경으로 View의 전체 혹은 일부가 표시되면 시스템은 View에게 컨텐츠를 그리도록 요청합니다. UIKit이나 Core Graphics를 통해 커스텀 컨텐츠가 포함된 View일 경우 시스템은 View의 draw(_:) 메소드를 호출합니다. 이 메소드를 구현하면 current graphic context에 View의 컨텐츠를 그릴 수 있으며, 이 메소드를 호출하기 전에 시스템에서 자동으로 설정됩니다. 화면에 표시될 수 있는 정적이고 시각적인 표현이 생성됩니다.
view의 컨텐츠가 바뀔 때, view를 다시 그려야한다고 시스템에게 알리는것은 저희가 해야하는 역할입니다. view의 setNeedDisplay() 혹은 setNeedsDisplay(_:) 메소드를 호출하여 사용할 수 있습니다. 이러한 메소드들은 다음 드로잉 사이클 동안 View를 업데이트 해야한다고 시스템에게 알립니다. View를 업데이트하기 위해 다음 드로잉 사이클까지 기다리기 때문에 여러 View에서 이러한 메소드를 호출하여 동시에 업데이트 할 수 있습니다. (이 메소드를 호출하는 즉시 View의 컨텐츠를 업데이트하는 것은 아닙니다. 다음 드로잉 사이클이 올때까지 기다렸다가 변화된 내용들을 한번에 업데이트합니다. 따라서 호출하는 시점과 변경되는 시점의 차이가 생깁니다.)
애니메이션
View의 여러 속성들에 대한 변경 사항을 애니메이션할 수 있습니다. 즉, 속성을 변경하면 현재 값에서 시작하여 새로 지정한 값에 끝나는 애니메이션을 생성합니다. 다음 나열되는 UIView의 속성들은 애니메이션할 수 있습니다.
- frame
- bounds
- center
- transform
- alpha
- backgroundColor
변화에 대해 애니메이션 하려면 UIViewPropertyAnimator 객체를 만들고 handle block을 사용하여 View의 속성 값을 변경합니다. UIViewPropertyAnimator 클래스를 사용하면 애니메이션의 지속 시간과 타이밍을 지정할 수 있고 실제 애니메이션을 수행합니다. 속성 기반 애니메이터를 일시 중지하여 애니메이션을 중단할 수도 있습니다.