[iOS] 3주차
INDEX
UIImageView.contentMode
textField.placeholder
layer
IBAction
IBOutlet
Gesture
화면 전환
UINavigationController
화면 생명 주기
StackView
UIImageView.contentMode
: 컨텐츠의 사이즈에 따라 어떻게 보여질 지 뷰를 결정하는 옵션
ContentMode의 종류
- scaleToFill
- 이미지의 높이와 너비는 UIImageView의 크기와 일치하도록 늘어납니다.
- AspectFit이렇게 하면 전체 이미지를 표시하면서 높이나 너비를 왜곡시키지 않으면서 가능한 한 이미지를 크게 만듭니다.
- 이미지의 가장 긴쪽(높이 또는 너비)은 뷰와 일치하도록 늘어납니다.
- AspectFillAsepct Fit처럼 이미지의 비율이 원래 비율에서 왜곡되지 않습니다.
- 이미지의 가장 짧은곳 (높이 또는 너비) 은 뷰와 일치하도록 늘어납니다.
- center이미지의 길이와 너비가 늘어나지 않습니다.
- 이미지가 뷰의 중앙에 배치됩니다.
- redraw커스텀해서 뷰를 사용하지 않으니 redraw를 사용하지 않습니다.(redraw는 뒷단에서 더 많은 작업을 합니다.)
- redraw는 UIImageView의 scaleToFill모드와 동일한 결과를 줍니다.
- redraw는 자체적으로 scaling 이나 resizing를 수행해야 하는 경우 사용합니다.
textField.placeholder
: 텍스트 필드에 다른 텍스트가 없을 때 표시되는 문자열
: 기본 값은 nil값이며 시스템 정의 색상을 사용 함
Layer
layer가 생겨난 역사
- OpenGL→ 따라서 초당 60프레임을 계속 유지하기 위해, GPU에서 직접 실행되는 그래픽에 강력한 OpenGL이 생겼다.
- iOS 어플을 사용할 때 화면이 끊기지 않고 부드럽게 그려지도록하기 위해선 초당 60 프레임 속도를 유지해야 한다.
- 그러나 단순한 작업에도 코드 양이 매우 방대해진다.(CGColor, CGRect 등등)
- 따라서 OpenGL보다 더 적은 코드로 그래픽을 구현할 수 있는 Core Graphics라는 것을 만들었다.
- OpenGL의 최대 장점은 그래픽 하드웨어에 가장 빠르게 액세스 할 수 있다는 것
- 이것마저 더욱 간단하게 사용하도록 만들고자 생긴 게 Core Animation이다.
- 근데 이 Core Graphics도 약간 Low Level 작업이라,
- 따라서 UIKit을 통해 최고 High Level에서 그래픽에 접근을 할 수 있다.
- Core Animation에는 그래픽에 접근하는 많은 고급 기능이 들어있는데, 애플 측에선 고급기능을 다 안고 갈 필요가 없다고 판단하고, Core Animation을 간단하게 만들어버린 것이 바로 UIKit이다.
UIKit의 장단점
UIKit의 장점: 계속 간단하게 단순화 시켜왔기 때문에 사용하긴 편하다.
UIKit의 단점: 가장 Low Level에 있는 OpenGL이나 Core Graphics 보다는 적은(제한된) 기능을 제공할 수 밖에 없다.
- LayerUIView는 직접 화면에 그리는 시각적 행위를 Core Animation에게 위임하는데,
- layer라는 CALayer 타입의 프로퍼티를 통해서 가능하다.
- UIView는 레이아웃, 터치 이벤트 등 많은 작업을 처리하긴 하지만 사실은 뷰 위에 컨텐츠나 애니메이션 을 그리는 행위는 직접 하지 않는다.
Layer의 구성
→ UIView는 **하나의 CALayer(Root)**만 가지고 있다.
→ CALayer(Root)는 SubLayer를 여러 개 둘 수 있다.
→ UIView의 SubView는 UIView의 CALayer(Root) 위에 얹혀지는 것이다.
IBAction / IBOutlet
IBAction
- 컨트롤에서 발생한 이벤트를 코드를 통해서 처리할 때 사용한다.
- 즉, 버튼등이 클릭되는 '이벤트' 가 발생했을때 어떤 동작을 할 것인지 정의하는 메소드라고 생각하면 된다.
- Ctrl + 드레그&드롭 or 마우스 오른쪽 클릭 + 드레그&드롭
IBOutlet
- 컨트롤러의 header file에 선언된 객체를 인터페이스 빌더가 인식하도록 연결 하는것.
- 코드를 통해서 스토리보드의 UI에 접근할 때 사용한다.
- UI에 접근하기 위한 속성이라고 생각하면 된다.
- Ctrl + 드레그&드롭 or 마우스 오른쪽 클릭 + 드레그&드롭
Gesture
UIGestureRecognizer
: 위 클래스는 특정 제스처 인식기에 대한 동작을 정의한다.
UIGestureRecognizer Sub-Class
- UITapGestureRecognizer : 싱글탭 또는 멀티탭 제스처
- UIPinchGestureRecognizer : 핀치(Pinch) 제스처
- UIRotationGestureRecognizer : 회전 제스처
- UISwipeGestureRecognizer : 스와이프(swipe) 제스처
- UIPanGestureRecognizer : 드래그(drag) 제스처
- UIScreenEdgePanGestureRecognizer : 화면 가장자리 드래그 제스처
- UILongPressGestureRecognizer : 롱프레스(long-press) 제스처
→ 제스처 인식기를 사용하기 위해서는 Target-Action 연결을 설정한 후 UIView의 메서드인 addGestureRecognizer(_:) 메서드를 통해 뷰에 연결해야 한다.
@IBAction func myActionMethod()
@IBAction func myActionMethod(_ sender: UIGestureRecognizer)
→ 제스처가 인식되면 해당 제스처 이벤트에 연결된 타깃에 액션 메시지가 전달된다.
화면 전환
swift에서의 화면전환 방법은 크게 3가지가 있다.
1. segue 사용
2. Modal을 사용하여 다른 viewController 호출: Present
3. NavigationController을 사용하여 화면전환 : Push (=Show)
Segue 사용
- 스토리보드 상에서 viewcontroller들을 연결시키는 방법
- 전환흐름을 시각적으로 알 수 있어서 눈으로 보기에 편함
- 별다른 코드 없이 간단하게 화면전환을 할 수 있지만 직접 드래그 & 드롭으로 연결해야해서 불편할 수 있음
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
self.performSegue(withIdentifier: "[연결한 segue의 identifier]", sender: self)
}
Modal을 이용하여 present
- 새로운 viewcontroller를 하나 만든 다음 스토리보드의 ID 정해주기
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
let newVC = self.storyboard?.instantiateViewController(identifier: "[연결하고 싶은 화면 스토리보드의 ID]")
//modal에서는 ransitionStyle과 resentationStyle를 따로 지정을 해줄 수 있음 -> present를 이용해서 화면 전환
newVC?.modalTransitionStyle = .coverVertical
newVC?.modalPresentationStyle = .automatic
self.present(newVC!, animated: true, completion: nil)
}
NavigationController을 사용하여 push
- NavigationController을 사용하여 Push하기, 여기서 push는 show의 개념
- 새로운 뷰를 만들고 스토리보드의 ID 정해주기
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
let pushVC = self.storyboard?.instantiateViewController(withIdentifier: "[연결하고 싶은 화면]")
self.navigationController?.pushViewController(pushVC!, animated: true)
}
→ 2번 방식이랑 비슷하지만 pushViewController로 화면을 push 한다.
UINavigationController
계층구조로 구성된 content를 순차적으로 보여주는 container view controller
- stack 구조로 구현되어 있다 - navigation stack
- 계층 구조 탐색으로 앱 content 를 보여주기에 적절하다
- 한번에 한 child view controller 의 content 만 보여진다.
- pop/push method를 사용하여 보여지는 child view controller 를 변경한다.
화면 생명 주기
UIViewController의 생명주기
뷰의 상태 감지 메소드
- viewDidLoad()
- 뷰 계층이 메모리에 로드된 직후 호출되는 메서드
- 1회 호출되며 메모리 경고로 뷰가 사라지지 않는 이상 다시 호출되지 않음.
- 주로 뷰의 초기화 작업을 담당합니다.
- viewWillAppear
- 뷰가 뷰 계층에 추가되고 화면이 표시되기 직전에 호출되는 메서드
- 화면이 새로 올라올 때마다 수행
- 그때마다 수행해야 할 작업을 담당하기에 유용
- viewDidAppear
- 뷰가 뷰 계층에 추가되어 화면이 표시되면 호출되는 메서드
- 뷰를 보여줄 때 필요한 추가적인 작업을 할때 유용
- viewWillDisappear
- 뷰가 뷰 계층에서 사라지기 직전에 호출되는 메서드
- 뷰를 생성하고나서 했던 행동들을 되돌리는 작업할 때
- 작성 또는 선택된 정보들을 삭제되기 전에 저장해두는 작업할 때
- viewDidDisappear
- 뷰가 뷰 계층에서 사라진 후 호출되는 메서드
- 뷰를 숨기는 것과 관련된 추가적인 작업을 할때
StackView
열 또는 행에 뷰 집합을 배치하기 위한 간소화된 인터페이스
→ 그냥 뷰를 배치하는 것과 스택뷰에 넣어서 배치하는 것을 구분짓는 기준은
스택뷰에 들어가는 뷰가 런타임 도중 동적으로 제거되거나 추가될 때에 기존 뷰들의 레이아웃이 바뀌냐 안바뀌냐에 따라 나눌 수 있다.
→ StackView를 사용하려면 Position을 정확히 지정해줘야하며, 상황에 따라 Size를 지정해줄 수 있다.
UIStackView.Distribution
- fill
2. fill propertionally
→ StackView를 채우고, 남은 공간이 생긴다면 intrinsic content size 의 비율에 맞게 공간을 분배하여 resize
3. equal spacing
4. equal centering
→ 각 View들의 center - center간 거리를 동일하게