Open SuyeonKim1702 opened 1 year ago
func addGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer)
let view = UIView() let tapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(didTapView)) view.addGestureRecognizer(tapGestureRecognizer)
...
@objc func didTapView() { /// do something }
- UIControl
- `func addTarget( _ target: Any?, action: Selector, for controlEvents: UIControl)`
- `func addAction(_ action: UIAction, for controlEvents: UIControl.Event)` (ios 14부터 지원됨)
- [참고](https://twitter.com/twannl/status/1291364665763733506?s=20)
let button = UIButton()
button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside)
button.addAction(UIAction { [weak self] in ... }, for: .touchUpInside)
...
@objc func didTapButton() { /// do something }
커스텀 뷰 만드는 법
class CustomView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
// 생성자를 override하는 경우 자동으로 추가됨
required init?(coder: NSCoder) {
super.init(coder: coder)
// fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
// set up stuff
}
private func setup() {
// set up stuff
}
}
override init(frame: CGRect)
required init?(coder: NSCoder)
override func awakeFromNib()
layoutSubviews
뷰가 조정되는 시점에 추가로 수행하고 싶은 일이 있다면 오버라이드 할 수 있음
layoutIfNeeded
setNeedsLayout
viewWillLayoutSubViews
viewDidLayoutSubViews
자동으로 layoutSubviews가 호출되는 경우
UIResponder
를 상속받는 responder 객체들을 이용해 이벤트를 처리한다.UIApplication
, UIViewController
, UIView
들은 모두 responder 객체들이다.
// responder chain의 다음 responder 객체를 리턴, 없을 경우 nil 리턴
var next: UIResponder?
// firstResponder 객체 리턴
var isFirstResponder: Bool
// 객체가 firstResponder가 될 수 있는지 여부 리턴
func canBecomeFirstResponder: Bool
// 객체가 firstResponder 상태를 포기할 수 있는지 여부 리턴
var canResignFirstResponder: Bool
// 객체를 Window의 firstResponder로 만들도록 UIKit에 요청
// 내부에서 canBecomeFirstResponder 값 참조함.
func becomeFirstResponder() -> Bool
// 객체가 Window의 firstResponder 상태를 포기하도록 UIKit에 요청
func resignFirstResponder() -> Bool
func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
// 이벤트가 발생한 지점을 포함한 뷰가 아니라면 nil 리턴
if !point(inside: point, with: event) {
return nil
}
// 투명도, user interaction 여부, hidden 여부 확인 -> alpha == 0 or hidden or userInteraction == false일 때에 제스처 처리가 불가능한 이유
if alpha < 0.01 || !isUserInteractionEnabled || isHidden {
return nil
}
// 가장 하위의 서브뷰를 찾는 과정
for subview in subviews.reverse() {
if let hitView = subview.hitTest(point, with: event) {
return hitView
}
}
return nil
}
func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
Color Asset 추가할 때 설정 변경
이미지도 다크모드 설정 가능
info.plist에 Appearance 키를 추가해 다크모드 설정/차단 가능
system color는 라이트/다크 모드에 따라 색상이 다르게 적용됨
코드로 다크모드 여부 아는 방법
UITraitCollection.userInterfaceStyle
를 통해 알 수 있음 class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if self.traitCollection.userInterfaceStyle == .dark {
// User Interface is Dark
} else {
// User Interface is Light
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
// Trait collection has already changed
}
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
// Trait collection will change. Use this one so you know what the state is changing to.
}
}
해당 View가 UIButton이고, 선언되있는 위치는 무조건 해당 VIew가 터치되도록 하려면 다음과 같이 구현해두면 됨
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let superHit = super.hitTest(point, with: event) else { return nil }
return (superHit is UIButton) ? superHit : nil
}
UIKit