Declaration
@MainActor class UIImageView : UIView
Declaration
enum ContentMode : Int, @unchecked Sendable
Declaration
@MainActor class UITextField : UIControl
var placeholder: String? { get set }
-> ios 앱을 사용할 때는 화면이 끊기지 않도록 초당 60 프레임의 속도를 유지해야하는데, 이를 유지하기 위해 GPU에서 직접 실행되는 OpenGL이 생겼다. OpenGL은 그래픽 하드웨어에 가장 빠르게 접근할 수 있다는 점이 가장 큰 장점이지만, 단순한 작업에도 코드가 매우 방대해진다.
따라서 OpenGL보다 더 적은 코드로 그래픽을 구현할 수 있는 Core Graphics라는 것을 만들게 된다. (CGColor, CGRect...)
근데 이 Core Graphics도 약간 Low Level(컴퓨터가 이해하기 쉬운 언어, 기계어,어셈블리어) 작업이라, 더욱 간단하게 사용하도록 만들자해서 Core Animation를 만들었다.
Core Animation에는 그래픽에 접근하는 많은 고급 기능이 들어있는데, 애플은 또 "근데 앱 만드는데 이렇게 고급 기능이 다 필요함? 아닌 것 같은데?"라고 생각해 고급기능을 버렸다. 그래서 Core Animation을 또 간단하게 만들어버린 것이 바로 UIKit!
따라서 우린 UIKit을 통해 최고 High Level(사람이 이해하기 쉽게 작성된 프로그래밍 언어)에서 그래픽에 접근을 할 수 있던 것!
이 UIKit에 단점이라고 한다면 단순화 시켜 사용하기는 좋을 수 있으나, Low Level에 있는 OpenGL이나 Core Graphics 보다는 적은(제한된) 기능을 제공할 수 밖에 없다.
-> UIView는 레이아웃, 터치 이벤트 등 많은 작업을 처리하긴 하지만 사실은 뷰 위에 컨텐츠나 애니메이션을 그리는 행위는 직접 하지 않는다고 보면 된다.
-> UIView는 직접 화면에 그리는 시각적 행위를 Core Animation에게 위임하는데 그게 (CA)layout이다.
UI와 코드를 연결하는 Outlet과 Action
@IBOutlet
과 @IBAction
은 스토리보드의 UI와 코드를 연결하는 역할을 한다.Ctrl 드레그앤 드롭
or 마우스 오른쪽 클릭 드레그앤 드롭
@IBAction func btn(_ sender: Any) {
}
Ctrl 드레그앤 드롭
or 마우스 오른쪽 클릭 드레그앤 드롭
@IBOutlet weak var label: UILabel!
UIGestureRecognizer - 위 클래스는 특정 제스처 인식기에 대한 동작을 정의
UIGestureRecognizer Sub-Class
iOS의 Standard Gesture
→ 제스처 인식기를 사용하기 위해서 Target-Action 연결을 설정한 후 UIView의 메서드인 addGestureRecognizer(_:) 메서드를 통해 뷰에 연결해야 한다.
@IBAction func myActionMethod()
@IBAction func myActionMethod(_ sender: UIGestureRecognizer)
→ 제스처가 인식되면 해당 제스처 이벤트에 연결된 타깃에 액션 메시지가 전달된다. 호출되는 액션메서드는 아래의 메서드 구현 형식 중 하나와 같아야 한다.
init(target: Any?, action: Selector?)
: 제스처 인식기를 타깃-액션의 연결을 통해 초기화 합니다.
func location(in: UIView?)
-> CGPoint : 제스처가 발생한 좌표를 반환합니다.
func addTarget(Any, action: Selector)
: 제스처 인식기 객체에 타깃과 액션을 추가합니다.
func removeTarget(Any?, action: Selector?)
: 제스처 인식기 객체로부터 타깃과 액션을 제거합니다.
func require(toFail: UIGestureRecognizer)
: 여러 개의 제스처 인식기를 가지고 있을 때, 제스처 인식기 사이의 의존성을 설정한다.
var state: UIGestureRecognizerState
: 현재 제스처 인식기의 상태를 나타냅니다.
var view: UIView?
: 제스처 인식기가 연결된 뷰입니다.
var isEnabled: Bool
: 제스처 인식기가 사용 가능한 상태인지를 나타냅니다.
var cancelsTouchInView
: 제스처가 인식되었을 때 터치 이벤트가 뷰로 전달되는 여부에 영향을 미칩니다.
이 프로퍼티가 true(기본값)이고 제스처 인식기가 제스처를 인식했다면, 해당 제스처의 터치는 뷰로 전달되지 않습니다. 이전에 전달된 터치들은touchesCancelled(_:with:)
메시지를 통해 취소됩니다. 제스처 인식기가 제스처를 인식 못하거나 이 프로퍼티의 값이 false라면 뷰가 모든 터치를 전달받게 됩니다.
var delaysTouchesBegan
: began 단계에서 제스처 인식기가 추가된 뷰에 터치의 전달 지연 여부를 결정합니다.
var delaysTouchesEnded
: end 단계에서 제스처 인식기가 추가된 뷰에 터치의 전달 지연 여부를 결정합니다.
swift의 화면전환방법은 크게 3가지
Segue 사용 : Storyboard
Modal을 이용하여 다른 ViewController 호출 : Present
NavigationController을 사용하여 화면전환 : Push (=Show)
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
self.performSegue(withIdentifier: "[연결한 segue의 identifier]", sender: self)
}
@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)
}
@IBAction func [연결하고 싶은 버튼](_ sender: UIButton) {
let pushVC = self.storyboard?.instantiateViewController(withIdentifier: "[연결하고 싶은 화면]")
self.navigationController?.pushViewController(pushVC!, animated: true)
}
-> 2번 방식이랑 비슷하지만 pushViewController로 화면을 push 한다.
계층구조로 구성된 content를 순차적으로 보여주는 container view controller
UINavigationController
가 가지고 있는 요소viewControllers
: navigation controller 는 여러개의 view controller 를 관리할 수 있는 container view controller 이기 때문에 해당 navigation stack 에 쌓인 view controller 들을 배열 형태로 가지고 있습니다. 해당 배열은 push, pop 형태로 관리됩니다.navigationBar
: 앱을 사용하다 보면 상단에 타이틀, 뒤로가기, 설정등 특정 영역에 UI 요소들이 배치된 경우를 볼 수 있는데, 해당 영역을 navigationBar라고 합니다. 해당 navigationBar 를 통해 굳이 UI를 추가하거나 세팅할 필요없이 해당 view controller 를 위한 UI를 설정할 수 있습니다.toolbar
: 사파리 앱에서 흔히 아래쪽에 공유하기나 여러 버튼들이 모여있는 것을 볼 수 있는데, 이를 toolbar라고 합니다. 기본적으로 navigation controller 에서는 숨김처리 되어 있지만, 숨김을 해제하고 해당 영역을 설정할 수 있습니다.delegate
: UITableViewDelegate 처럼 UINavigationController 에도 특정 Event에서 사용할 수 있는 delegate가 선언되어 있습니다. 보통 특정 view controller가 보여지거나, 이동간 애니메이션을 설정하기 위해 사용합니다.UINavigationController
의 뷰 구조열 또는 행에 뷰 집합을 배치하기 위한 간소화된 인터페이스
Spacing, Alignment, Distribution를 사용해서 형태를 잡아 줄 수 있다.
View들을 스택뷰를 이용해 정렬할 때, Alignment를 이용해서 좀 더 세부적인 설정이 가능
Horizontal
Vertical
스택 뷰 안의 뷰들의 관계를 나타낼 때 사용
fill: 설정한 크기에 맞게 뷰 채우기, Priority는 알아서 설정해주어야 함
Fill Equally: 모든 뷰의 크기를 같게 맞춰 줌
Equal Spacing: 모든 뷰의 간격을 동일하게 설정
Equal Centering: 컨텐츠의 가운데를 기준으로 간격을 맞춤
Fill Proportionally: 컨텐츠의 크기가 크면 여백이 커지고 컨텐츠의 크기가 작으면 여백의 작아짐 -> 비율적인 개념
Hint. ContentMode는 컴포넌트를 구성하는 image를 보여주는 방식입니다.
-> UIImeageview, UIButton, UIView
-> UIView를 꾸며서 신호등 만들어보기
-> ?
-> 불가능하다
-> UITouch, UIEvent사용하기
Hint. OOOOViewController().~~~~~style
->
@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)
}
-> FullScreen 은 화면을 모두 덮는 반면
PageSheet, FormSheet 는 dimming view 를 이용하여 Presenting VC 의 컨텐츠가 표시
-> Y 친구 뷰 하나에 프로필, 이름, 노래를 배열하는 것은
StackView로 만든거 같다.