codesquad-members-2024 / swift-drawing

iOS 세번째 프로젝트
0 stars 1 forks source link

[스터디] View Programming #6

Closed godrm closed 5 months ago

godrm commented 6 months ago

수업 자료에 뷰 프로그래밍 관련 영상을 학습하고 정리해서 댓글로 남기세요 질문꺼리도 정리해도 좋습니다

joho2022 commented 5 months ago
좌표시스템 좌표시스템 세로모드일때 - 오른쪽으로 갈 수록 x축이 증가하고 - y축이 증가할 수록 아래로 내려간다 가로모드일때 - 오른쪽으로 갈 수록 x축 증가 - 위로 올라갈수록 y축 증가 보통 Points단위로 계산한다 익숙한 단위의 포인트를 알면 뷰를 계산할 때 도움됨 아이폰은 보통 세로로 돌아가는 것을 기본으로 한다. 아이패드는 가로 세로 동일하게 동작하도록 권장한다. (0.75, 0.7, 0.65화면비율) 뷰를 만들기 위해서는 좌표시스템을 알아야 하고, 화면 비율에서도 고민해야하고, 회전 축도 고려하는데, 화면을 어떻게 보여줄 것인가에 대해서는 Frame과 Bounds에 대해서 알고 있어야 한다 Frame이 가장 중요한데, Frame이란 뷰를 어떤 틀에 보여줄 것인가를 의미한다. Frame을 나타내기 위한 크게 4가지 값이 있다. - X - Y - width - height x, y를 합쳐서 origin 그리고 width, height를 합쳐서 size라고 부른다. View의 속성으로 들어가 있다. 그래서 뷰를 보여줄려면 항상 어느 위치에 보여질 것인지 x, y값이 필요하고 거기서부터 얼마나 큰 크기에 보여줄것인지 width, heigth가 필요하다. ← 중요!!! Bounds는 내부의 값을 의미한다. Frame에서 origin값은 그 뷰의 속한 (상위뷰)슈퍼뷰의 좌표시스템을 따라간다. 원점에서부터 얼마나 떨어져 있는가에 대한 것 생성되면 센터값도 정해짐 오리진 값과 센터값이 연관되어 있음 Bounds는 오리진이 바뀌면 스크롤 효과, 사이즈가 바뀌면 확대 축소 효과가 나타난다 ### Boundary Clipping 애플은 이미지를 둥글게 처리하는 것을 권장한다 - UIView의 ClipsToBounds 프로퍼티 - CALayer의 maskToBounds 프로퍼티 모서리에 반지름 값을 주고 clip을 하겠다. mask를 하겠다 속성을 바꾸면 잘리는 효과가 나타난다. 두 가지 중 하나의 속성을 사용하여 모서리를 둥글게 처리한다 ### View Content Mode 뷰를 보여질 때 어떤식으로 채워지게 만들것인가에 대한 것 ### UIKit Catalog UIKit에 어떤 뷰요소가 들어있는지를 보여질수 있는 것을 애플에서 제공하는 샘플코드가 있다
뷰레이아웃 ### 목차 - Frame-based 프레임 기반으로 좌표를 지정하는 방식 살펴보기 - AutoResizeMask 어떻게 동작하는가 - AutoLayout으로 지정하기 위해서 Constaints를 지정하는 방법 - Layout 예시 ## Frame 기반 뷰 만들기 인터페이스 빌더에서 뷰를 만들 때 드래그 앤 드랍 → 특정한 위치 놓기 → 크기를 지정하는 방식으로 흘러감 x, y width, height 4가지 값이 지정한다 = 프레임기반으로 뷰를 생성한다 의미함. UIKit에서는 슈퍼뷰가 보통 하위뷰의 레이아웃을 지정하는 흐름으로 작업하게 된다. 예를 들어 titleLabel을 생성할 때 지정생성자 init(frame:)을 가지고 생성을 할 때 Rect값에 4가지 값을 한꺼번에 지정할 수 있다. 뷰를 만들 때 frame값을 Rectangle한 값으로 4가지 속성을 지정하는 방식이 있고, init을 할 때 뷰의 어떤 특징들을 기반으로 일단 생성을 하고 frame값을 바꿔서 넣어주는 방식이 있다. 상위뷰에서 하위뷰의 레이아웃을 지정해주는 방식이 UIKit에서 굉장히 익숙한 방법이다. 이렇게 뷰를 추가해주고 나면 지정해준 값에 생성되서 보여지고, 앱을 사용하는 동안에 불변한다는 의미이다. frame값을 바꿀려면 런타임에 frame 4가지 속성값을 다시 지정해주면, 다시 그려지기 때문에 바뀌게 될 수 있다. → 계속해서 frame값을 계산해야되기 때문에 불편하다. 특히 맥os에서 화면이 바뀌는 경우를 Resize가 일어난다라고 표현하는데, resize가 일어났을 때 같이 변화하기 위해서는 autoResizeMask라는 방식을 사용한다. ## AutoResizeMask Spring과 Strut를 사용한다. 외곽 H를 Strut이라고 불리고, 점선 화살표를 Spring이라고 한다. Spring을 지정해주면 같이 늘어나고, Strut을 지정해주면 그 위치가 고정이 된다. 좌측정렬, 우측정렬, 상단기준, 하단기준으로 총 6가지 속성을 지정할 수 있다. 화면에서는 인터페이스 빌더에서 특정한 뷰를 선택한 다음에, 그 뷰가 좌측정렬을 할건지, 우측정렬을 할건지, 혹은 늘어나게 할건지, 안 늘어나게 할건지, 선택함으로써 지정해줄 수 있다. 위와 같은 방식을 AutoResizingMask방식이라고 불린다. AutoResizing표현도 함. 뷰가 늘어날 때 같이 늘어나기만 하면 되는 경우에는 AutoResizeMask를 사용해서, 뷰가 같이 늘어나도록 지정할 수 있다. AutoResizeMask는 슈퍼뷰의 관계에서만 지정이 가능하다. (6가지 속성 지정이 가능) - flexibleTopMargin - flexibleBottomMargin - flexibleLeftMargin - flexibleRightMargin - flexibleHeight - flexibleWidth ```swift colorLabel.autoresizingMask = [.flexibleWidth] ``` autoresizingMask라는 속성이 OptionSet형식으로 되어있는데, 마치 배열처럼 가로를 열고 그 안에 필요한 속성을 콤마로 넣어줄 수 있다. 오직 슈퍼뷰와의 관계에서만 지정이 가능하기 때문에, 슈퍼뷰가 늘어났을 때 늘어날건지, 늘어나지 않더라도 우측에 따라서 이동할건지 등등 고정하거나 늘어나는 역할만 지정할 수 있다. 그 외에 것들은 AutoResizeMask가 할 수 없다. 그 외에 것들 중에 ## Constraint 블루 뷰와 레드 뷰의 관계처럼, 블루 뷰가 늘어났을 때 레드 뷰가 같이 옆으로 움직이거나, 혹은 간격이 유지되거나, 같이 크기가 커지고, 작아지는 것처럼 관계식을 지정할 수 없다. 이러한 것들에 지정해서 사용하는 것이 Constraint 제약사항이다. Constraint 제약사항은 방정식이 아니라, 관계식이다. 왼쪽은 어떤 특정한 아이템의 속성이 오른쪽에 있는 아이템의 속성과 multiplier와 constant를 계산을 해서 두 개의 관계가 유지되는 제약사항을 추가할 수 있다. 이때 Relationship은 반드시 equal만 있는게 아니라 부등호가 좌우로 있을 수도 있다. 이렇게 속성을 다룰 때 제약사항으로 줄 수 있는 attribute가 총 10가지가 준비되어 있다. 여기서 Left, Right는 물리적인 디바이스 기준으로 (화면의 왼쪽, 오른쪽) 사용한다. 왼쪽에서 사용하는 언어가 있고, 오른쪽에서 왼쪽으로 사용하는 언어가 있는 것처럼 LTR, RTL표현을 사용하는데, 언어적으로 쓰기 시작하는 지점을 리딩이라고 이야기 하는데 레이블이나 버튼같은 어느 위치에 줄거냐 이야기 할 때 LTR이나 RTL 2가지 지원할려면 Leading과 Trailing을 알고 있어야한다. 습관적으로 Leading과 Trailing을 사용하는 것이 좋다. 화면에 무조건적으로 왼쪽 오른쪽에 나오게 하고 싶으면 Left, Right를 사용해도 무방하다. Baseline은 레이블같은 경우에 폰트 타입그래피에 따라서 글씨에 베이스라인을 맞춰서 보여주는 것이 안정적이기 때문에 Baseline을 맞추는 경우도 있다. AutoLayout을 작업하는 경우에는 주로 인터페이스 빌더에서 하거나, 코드작업을 한다. ### 인터페이스빌더에서 작업 방식 1. 드래그 앤 드롭 보통 컨트롤키 누르고 클릭하고 드래그해서 드롭을 하는 방식 (관계를 맺을 때) 그냥 제약사항을 주고 싶을 때, - 뷰내부에서 하는 경우 (width, height같은 경우) - 다른 뷰에서 끝나는 경우 다른 관계를 추가할 수 있다. 보통 슈퍼뷰에서 주는 관계가 많기 때문에 안에서 시작해서 바깥으로 끝나는 드래그 앤 드롭을 사용한다. 그래서 다른 뷰와 관계를 제약사항으로 추가하게 되는데 팝업창이 뜬다. 팝업메뉴도 쉬프트를 누르거나 옵션키를 눌러서 한꺼번에 여러가지를 추가가능하다. 배치를 적당히 간단히 해놓고 제약사항을 한꺼번에 여러가지를 주는 작업으로 진행하면 좋음 팝업메뉴에서 SafeArea용어가 나오는데 슈퍼뷰의 특정한 영역이랑 관련을 지어주는 용어라고 생각한다. 1. 인터페이 메뉴 스토리보드나 xib를 선택했을 때 아래쪽에 인터페이스 메뉴가 나오는데 Align(정렬을 할 수있음), Pin(top,bottom, left, right, width, height, 비율), Resolve Issues(제약사항을 준 다음에 어떻게 보일건지 주황색 점선으로 보여주는 경우가 있다. 그때 이슈가 되거나 제약사항을 다 안 줬을 때, 이슈들을 해결하는방법들이 지원됨, xcode가 자동으로 해주다보니 되는 경우가 있고, 안되는 경우가 있음. 근데 깔끔하지 않아서 잘못누르면 오히려 Constraint망칠 수 있다.) Stack( 스택 쌓는 경우) ### 코드로 제약사항 추가하기 오토레이아웃을 줄 때 프레임이 의미가 없어서 ```swift let btn = UIButton(type: .roundedRect) ``` 처럼 생성한 다음에 AutoresizeMask 옵션을 꺼야한다. (오토레이아웃을 사용하겠다라는 의미) AutoresizeMask만으로도 자동적으로 UIKit은 내부적으로 Constraint만들어내는 코드가 들어있다. 그렇기 때문에, resize될 때는 대응할 수 있으나 그 이외에 것들은 AutoresizeMask옵션을 끄고, 원하는 Constraint를 주면 된다. x, y, width, height에 대해서 각각 계산하는 제약사항을 추가하는 것 예를 들어 x y width만 있고 height만 없는 경우 경고가 나올 수 있다. 코드에서는 그런 것이 없지만 뷰가 잘못하면 보여지지 않는 상황이 발생 그래서 적어도 4개 값이 계산이 잘 되는지 유추할 수 있어야 된다. 예시로 LeadingMargin과 TrailingMargin으로 맞추면 width을 계산할 수 있게 됨. Priority를 주지않고 생략하면 1000 기본값인데 항상 지켜져야 할 Constraint → 깨지면 뷰가 안 보일 수 있다는 의미 priority 1000보다 작은 값들은 깨질 수 있다는 의미, 조건이 맞지 않더라도 깨져되는 부가적인 옵션 standard값은 아이폰과 아이패드에서 다를 수 있는데 화면 크기에 따라서 심리적으로 느끼는 거리가 다르기 때문에 standard라는 값을 아이패드나 iOS에서 지정해서 쓸 수 있게끔 미리 들어있는 값임. 보통은 10픽셀정도 된다. 적어도 10정도는 떨어져야 뷰가 겹치지 않기 때문에 그정도 값을 주도록되어있는데 아이패드같은 경우는 아이폰에서 10은 아이패드 10이 더 좁게 느껴지는데 그래서 16이나 20정도 떨어지도록 내부적에서 값을 바꿔준 가이드라인이라고 standard를 생각한다. AutoresizeMask로 할 수없는 것중 하나가 관계를 주는 것 예시 ) 노란색 뷰와 초록색 뷰의 가로가 항상 같아야 한다 예시 ) 배율을 줄 때, 특정한 비율을 가졌으면 좋겠을 때 multiplier를 사용(정수만 사용하지 않고, 1.4, 0.75처럼 가능) 예시 ) 더 복잡한, 블루 뷰가 150이상일 때는 레드 뷰 비율 2배를 유지하되 이것을 못지키겠으면 (폭이 좁아져서 블루뷰가 150보다 작아지거나 비율 2배유지를 못할 때 조건이 깨질 수 있게끔 priority를 낮춤) 균형을 맞춰서 배치하고 싶을 때는 StackView 사용하자 오토레이아웃을 준다는 것은 서로간에 연쇄작용으로 width height가 다같이 계산되지 않으면, 다같이 안보인 상황이 발생할 수 있다. 그래서 요즘 레이블이나 텍스트필드같은 경우에는 안에있는 텍스트영역을 최대한 보호해주기 위해서, 다양하게 최소한 폭은 유지하되 늘어날 수 있게 제약사항을 주거나, 가려지지 않게 고정적인 width나 heigth속성을 주지않는 것이 추세다. 제약사항들이 연쇄작용으로 깨지지않는지 꼭 확인해야 함. ## 정리 frame 기반으로 좌표값을 정할 때는 x, y, width, height 4가지 속성을 다 넣어줘야 함 만약에 값이 바뀌면 그 값들을 다시 넣어주는 코드가 있어야 한다. 그리고 그게 화면크기가 늘어난다고만 하면 AutoResizeMask로 충분히 커버가 가능 하지만 뷰 끼리의 관계를 맺어주거나, 혹은 더 자동으로 계산되도록 만들려면 오토레이아웃방식을 사용해야 하고, 제약사항을 x에 대한, y에 대한 width에 대한, height에 대한 것들 4가지 이상 넣어줘야 한다. 그럼에도 불구하고 오토레이아웃이 만병통치약이 아님 계산하는데 느릴 수 있어서 오토레이아웃을 남발하는 것에 대해 신경을 써야한다. 화면크기에 대응하기 위해서 모든 뷰에 항상 오토레이아웃을 써야하는 것이 아님 → autoResizeMask로 충분히 커버 가능하기 때문에 오토레이아웃 제약사항을 추가했을 때 뷰는 처음에 그려질 때 frame을 계산하고 그린다. 뷰가 appear되는 순간 처음 계산 시점이다. frame값은 viewDidAppear이후에만 확인이 가능하다 그전에 viewWillAppear나 ViewDidLoad상에서는 오토레이아웃이 계산되기 전이기 때문에 frame값이 계산되어 있지 않는다. 그리고 이후에 frame값을 바꾸면 제약사항은 깨져서 다시 frame값이 계산되지 않는다. 오토레이아웃을 사용하기 시작하면 오토레이아웃에 있는 것을 가지고만 frame이 계산되도록 해야하고, frame값을 강제로 수동으로 바꾸는 일은 없어야 된다. NSLayoutConstraint에서 Constant, Priority만 read-write가능 나머지는 read only라고 생각
뷰관리하기 ### 목차 - Trait이 무엇인지 - SafeArea가 어떤식으로 가이드라인이 제공되는지 - Xib와 스토리보드의 차이, 어떤 접근이 필요한지 - 에셋 카탈로그, 로컬라이즈, 접근성 제외된 내용이니 학습하기 ## Trait 여러가지 아이폰이나 아이패드가 동일한 화면크기, 동일한 화면비율가지고 있다가 점점 다양한 크기가 나오고 화면의 방향에 따라서 가로세로가 달라지기 때문에 이러한 것들을 대응하기 위해서, 크기별로 어떻게 대응할거냐에 대해 나온 것이 size Class가 처음 시작이고 그 이외에 여러가지 경우의 수가 있는데 - 아이패드 경우에는 가로세로 비율이 4:3이여서 회전을 하더라도 보여지는 영역이 크게 달라지지 않는다. 그래서 Regular Regular 표현을 쓴다. - 아이폰같은 경우는 가로화면과 세로화면이 높이와 폭의 비율이 세로가 더 길기 때문에, 세로일 때 잘보이는 컨텐츠도 회전을 하면 굉장히 좁아서 잘 안보이는 경우가 있다. 그런 현상때문에 Regular Compact용어를 사용함. 컨텐츠가 보여지는 기준을 가지고 분류를 정해놓음. 화면에 대응하는 것은 size class라고 불림. 여러가지 특징들을 모아놓은 것을 Trait, TraitCollection이라고 부른다. ## UITraitCollection 가로 세로 사이즈의 분류만 있는 것이 아니고, 회전, 화면 비율, 스타일, 속성에 대해서 분류함 분류에 따라서 다른 뷰가 보여지거나 보여지지 않거나, 스타일이 달라지거나 예외적으로 처리하기 위해서 `뷰 디바이스 속성에 따라서, 특정에 따라서 뷰가 달라지는 것을 대응하기 위해서 만들어진 모아놓은 값` 대표적인 것 - 가로, 세로 사이즈 클래스(size class) - 디스플레이 배율(scale), 색범위(gamut) - UI 스타일(light / dark) 이디엄( phone/pad/tv/mac) - UI레벨, 접근성 고대비, 텍스트 무게 - UI활성화 여부 등 이런 예외적인 상황에 따라서 속성들의 값을 읽어와서 처리하도록 모아놓은 것이 TraitCollection이다. 그래서 특정한 배율일때, 특정한 스타일때만 다른 컬러값이 보인다거나 다른 화면요소가 보이는 것이 가능하다. ## Safe Area 기존에는 적당한 위치에 컨텐츠가 보여지면 된다라고 이야기했지만, 아이폰 X이 나온 이후에는 화면 영역안에서 일어나는 일들이 굉장히 복잡해졌기 때문에, 화면 자체도 모서리가 둥글게 깎이고, 위에 영역에 노치불리는 영역이 생기고, 하단에 홈버튼이 없기 때문에 제스처를 위한 bar가 들어간 영역을 제외하고 컨텐츠를 적절하게 보여줘야 해서 Safe Area를 꼭 지켜라는 것을 의미 그래서 Safe Area를 이해하기 위해서 UILayoutGuide와 LayoutAnchor를 이해해야 한다. ### UILayoutGuide 마치 숨겨진 공백을 표현하는 뷰라고 생각한다. 레이아웃가이드를 추가해놓고, 이것을 가지고 오토레이아웃을 지정해주면, 그 레이아웃가이드 그공간을 채워주는 역할을 하게 된다. 그래서 SafeArea가 UILayoutGuide의 속성으로 들어있다. 슈퍼뷰가 SafeArea를 제공해주는 것은 슈퍼뷰가 레이아웃가이드로 보여지는 영역(SafeArea)을 제공하는 것을 의미한다. `레이아웃 가이드도 frame속성이 있다!!` ## XIB 발음은 엑스아이비 이지만, NIB 닙이라고 읽는다. Next Interface Builder의 약자이고, 예전에는 바이너리 형식이였기 때문에 리소스 파일이라고 읽었다. 소스버전관리하는 툴들이 바이너리가 아니라, 텍스트기반으로 하기 때문에 XML로 바뀌었다. 그래서 NIB파일이지만 XML포맷의 닙파일이다라고 해서 그냥 닙이라고 여전히 부른다. 닙파일은 XML구조로 되어있고, 화면 UI를 기록하는 XML이기 때문에 HTML처럼 계층구조가 화면의 디자인한 구조들이 마크업언어로 표현되어 있음. - 안드로이드의 layout XML과 비슷 - 닙 자체가 뷰이다. 디자인할 때는 XML로 만들지만, 인터페이스 툴이 XML를 분석을 해서 컴파일을 해가지고 리소스파일(뷰 파일)만들어 내는 것, 그 뷰파일을 나중에 메모리에 로딩을해서 사용하는 구조 (미리 디자인해놓는 측면에서 수월한 방법) - XIB를 생성할 때는 템플릿에서 View파일을 선택하면 됨. 만든 다음 원하는 인터페이스를 디자인하고, 그 자체를 저장하고 나면 XIB파일로 저장된다. ### 그것을 메모리에 로딩해서 사용하는 방법이 2가지가 있다. - NSBundle라고 하는 Bundle객체가 있는데, 앱의 들어있는 리소스들을 불러올 수 있는 프레임워크이다. 그래서 번들에 있는 main의 loadNibNamed해서 XIB의 이름을 주고(예시: View.xib) 로딩된 객체에는 사실 여러개의 뷰들이 들어있을 수 있는데, 그중에서 제일 최상위의 first오브젝트를 불러와서 UIView로 캐스팅해서 사용하면 된다. 이러한 API는 사실 맥용이냐, iOS이냐 구분없이 만들 수 있는 방법이기 때문에 NSView일 수도 있고, UIView일 수 있어서 캐스팅을 해야하는 방법이 있는 것이다. - XIB를 만들고 난 다음에 특정한 뷰 컨트롤러에 연결시켜서 불러오는 방법 - 요새는 이러한 방법을 쓰지 않는다. 스토리보드에서 만든 뷰컨트롤러의 Scene을 사용하는 방법을 더 사용함 ### XIB를 사용하는 이유 독립적인 뷰 디자인을 계속 반복해서 재사용하기 위해서임. XIB가 만들어진 이유가 바로 뷰를 이미 만들어놓고, 그 뷰를 자체로 보관하는 것임 그래서 콘텐츠 구성이나 레이아웃이 동적으로 바뀌는 경우 적용하기 어려움. 로딩하고 바꿀려고 하면 굳이 XIB로 만들 필요가 없음 뷰컨트롤러 단위를 처리하는 것은 사용하기 어렵다 그래서 일정한 뷰를 재사용하고 싶을 때 ( Cell와 같은 반복적으로 사용하는 경우 ) ## StoryBoard 인터페이스 빌더를 열면 기본적으로 사용함. 화면의 흐름을 한 눈에 볼 수 있는 것이 장점, 앱을 만들 때 화면 전환 흐름이라도 보고싶을 때가 있는데 화면 전환만이라도 스토리보드로 만들고 그 사이에 채워놓는 것들은 코드로 만드는 팀들도 있음. 스토리보드 상에는 용어가 2가지가 나온다. ### 화면 Scene 일반적으로 뷰컨트롤러와 매칭이 되고, 화면을 채워서 구성하는 단위이다.(Window를 채우는 구성단위) 제일 처음 보는 화면부터 화면 전환이 일어날 때의 화면들을 다 디자인하게 되는 것을 제공 뷰컨트롤러는 최상위 뷰하나만 가지고 있고 서브뷰들을 추가하는 것을 가정함. 그래서 Scene하나가 뷰컨트롤러에 해당되고, 뷰컨트롤러의 self.View라고 할 수 있는 최상위 RootView가 있고, 그 뷰밑에 버튼을 추가하던.. 레이블을 추가하던.. 이미지를 추가하던.. 계층적으로 뷰를 추가하는 화면을 만들 때 Scene을 만들게 된다. 그래서 뷰컨트롤러 용어보다 Scene용어를 더 많이 사용한다. 뷰컨트롤러이지만 Scene이라고 표현하고 있기 때문임. 거의 같은 개념 Scene과 Scene을 이어주는 사이의 전환을 이어주는 Seque 세그웨이 라고 말함. 이탈리아어에서 옴. 스토리보드도 결국 XML형식 소스코드, XIB의 확장판이다. XIB는 화면 하나만 볼 수 있는 버전이였다면, 스토리보드의 XIB는 화면을 여러개 볼 수 있는 확장판이라고 생각 (형식은 다르지만 처리하는 방식은 비슷함.) 그래서 XIB와 스토리보드는 인터페이스 빌더가 변환과정을 통해서 컴파일을 하고, 그대로 배포가 되는 것이 아닌 컴파일된 리소스파일이 앱 번들에 포함되게 된다. ### 앱 번들 안에는… - Resources 디렉토리가 있다. - 스토리보드 파일은 컴파일하게 되면 .storyboardc 컴파일된 파일이 만들어짐. 기술적으로 말하면 뷰 객체들이 Archived 아카이브됨 - 아카이브 : 뷰객체들을 인스턴스로 만들어 놓은 다음에, 메모리에 있는 그걸 그대로 파일로 저장해놓은 것처럼 아카이브되어 있는 모습 - 그래서 컴파일된 스토리보드 파일을 같이 앱에 배포되었다가 나중에 Unarchive 언아카이브를 하게 되면 UIStoryboard 메모리상 으로 올라가게 됨 스토리보드도 결국 닙파일이기 때문에 3가지 아카이브 되어있을 때 동작하는 3가지 메소드가 같이 활용이 된다. ### awakeFromNib() 메모리상에 로딩이 될 때 닙파일로 되어있었던게 다 깨어나서 메모리에 로딩이 되었다는 것을 알려줄 때 메서드가 호출이 된다. 뷰자체가 로딩이 되었음을 확인할 수 있을 때 사용함 뷰컨트롤러 입장에서는 viewDidLoad가 관련되어 있는 뷰들에 xib나 스토리보드에 연결되어 있으면, 메모리에 다 로딩이 되었을 때 viewDidLoad가 기본적으로 init(frame:)을 사용하는데 특별히 뷰 객체가 스토리보드가 XIB상태로 되어 있던게 로딩이 될 때 ( 언아카이브가 될 때) init(frame:)사용되는 것이 아니고 init?(coder:)가 사용된다. 간혹 샘플코드를 가지고 뷰클래스를 만들다 보면 init?(coder:)메소드를 구현해놓고 나서 템플릿에서 fatalerror를 찍어놓는 코드들이 있는데, 그냥 놔두고 스토리보드나 XIB를 사용해서 init?(coder:)생성자가 호출되기 때문에 앱이 죽게 된다. 앱이 죽도록 만들면 안되기 때문에 두 가지 메서드들을 동일한 형태로 구현해야 함. 뷰객체를 다룰 때는 스토리보드로 사용이 될지, 그냥 이니셜라이저로 사용이 될지 모르기 때문에 두 메서드를 호출하더라도 동일하게 동작하도록 만드는 것이 좋다. init(frame:) 뷰객체를 직접 생성할 때 init?(coder:) 뷰객체를 unarchive할 때 awakeFromNib() 뷰객체를 모두 unarchive 처리한 직후 ### 스토리보드 사용방법 1. 번들에서 특정 스토리보드 파일을 불러오는 경우 2. 스토리보드 객체에서 시작 지점의 뷰 컨트롤러 객체 만들기 3. 스토리보드 객체에서 특정 이름의 뷰 컨트롤러 객체 만들기 ### 스토리보드 장단점 전체화면 흐름, 미리보기, 프로토타이핑 가능 콘텐츠 구성과 레이아웃이 동적으로 바뀌는 경우, 버전관리 도구에서 충돌이 자주 발생 ## 정리 ### XIB vs Storyboard vs Code 3개가 상황에 맞게 선택하는 것이 중요하고 기준에 따라 판단하여서 선택한다. 1. 프로토타입을 빨리 만들기 위해 화면 전체 흐름이 중요한가? 2. 데이터 구조에 따라 달라지는 동적 화면인가? 3. 반복적으로 재사용하는 단위가 무엇인가? 4. 화면 레이아웃 처리를 디자인 타임에 하나? 런타임에 하나? 5. 코드로 해야만 하는 커스텀 UI처리가 얼마나 많은가? 6. UI리소스가 얼마나 많거나 복잡한가? 7. 팀내에서 코드가 익숙한가? IB가 익숙한가?
godrm commented 5 months ago

@joho2022 영상을 보고 거의 수업자료를 만들었네요 영상으로 주는 이유는 여러번이라도 보고 스스로 생각을 정리할 시간을 주려는 겁니다 받아쓰기를 하기보다는 설명한 내용을 다른 사람에게 설명할 수 있을 정도로 정리하려고 해보세요.

그래야 질문꺼리가 생깁니다. 이게 맞나? 어 이런 방법도 있구나. 여러 방법이 있을 때 선택의 기준이 무엇이지 항상 여러 방법이 있습니다. 그걸 선택하는 기준이 중요한 것이지, 시간내에 개발하기 위해서 아무거나 선택해야 하는 건 아닙니다

내일까지 제가 퀴즈 몇 개 만들어볼게요 :) 위에 정리하느냐고 수고하셨어요