iPadOS 18부터 탭바 디자인이 컴팩트하게 변경
기존 사이드바도 새로운 UITabBarController API를 통해서 사이드바와 탭바를 통합할 수 있다.
드래그 앤 드롭으로 커스텀 기능도 제공
UITab, UITabGroup
Elevate your tab and sidebar experience in iPadOS
animation
SwiftUI의 Animation을 UIKit의 animation에 사용 가능
switch gesture.state {
case .changed:
UIView.animate(.interactiveSpring) {
bead.center = gesture.translation
}
case .ended:
UIView.animate(.spring) {
bead.center = endOfBracelet
}
}
gesture recognizer
UIKit과 SwiftUI의 제스쳐 시스템 통합 완료
SwiftUI의 제스처를 UIKit에서 참조하기
// Inner SwiftUI double tap gesture
Circle()
.gesture(doubleTap, name: "SwiftUIDoubleTap")
// Outer UIKit single tap gesture
func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldRequireFailureOf other: UIGestureRecognizer
) -> Bool {
other.name == "SwiftUIDoubleTap"
}
기존의 UIKit gestureRecognizer는 UIGestureRecognizerRepresentable 프로토콜을 통해서 사용 가능
더 자세한 내용은 What’s new in SwiftUI 참조
Automatic trait tracking
기존에는 trait변경을 수동으로 구독했어야 했다.
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
registerForTraitChanges([UITraitHorizontalSizeClass.self],
action: #selector(UIView.setNeedsLayout))
}
override func layoutSubviews() {
super.layoutSubviews()
if traitCollection.horizontalSizeClass == .compact {
// apply compact layout
} else {
// apply regular layout
}
}
}
이제는 일반적인 뷰나 뷰컨트롤러 업데이트 메소드(ex. layoutSubviews, drawRect) 등에서 어떤 trait을 참조하는지 기록했다가 관련 trait이 바뀌면 자동적으로 무효화를 한다(ex. setNeedsLayout, setNeedsDisplay)
꼭 필요한 것만 의존함으로써 최대한의 성능을 이끌어 낼 수 있다.
어떤 메소드가 지원하는지는 문서 참조
List improvements
UITraitCollection에 listEnvironment 추가
ex. 파일 앱
iOS 17 구현
func configurations(for location: FileLocation,
listAppearance: UICollectionLayoutListConfiguration,Appearance)) ->
(UIListContentConfiguration, UIBackgroundConfiguration) {
let isSideBar = listAppearance == .sidebar
var contentConfiguration: UIListContentConfiguration
let backgroundConfiguration: UIBackgroundConfiguration
contentConfiguration = isSidebar ? .sidebarCell() : .cell()
backgroundConfiguration = isSidebar ? .listSidebarCell() : .listGroupedCell()
contentConfiguration.text = location.title
contentConfiguration.image = location.thumbnailImage
return (contentConfiguration, backgroundConfiguration)
}
iOS 18 이후
func configurations(for location: FileLocation) ->
(UIListContentConfiguration, UIBackgroundConfiguration) {
var contentConfiguration = UIListContentConfiguration.cell()
let backgroundConfiguration = UIBackgroundConfiguration.listCell()
contentConfiguration.text = location.title
contentConfiguration.image = location.thumbnailImage
return (contentConfiguration, backgroundConfiguration)
}
Update Link
주기적으로 UI업데이트가 필요한 경우에 사용
CADisplayLink와 비슷하지만 더 많은 기능을 가진다.
let updateLink = UIUpdateLink(
view: view,
actionTarget: self,
selector: #selector(update)
)
updateLink.requiresContinuousUpdates = true
updateLink.isEnabled = true
@objc func update(updateLink: UIUpdateLink,
updateInfo: UIUpdateInfo) {
view.center.y = sin(updateInfo.modelTime)
* 100 + view.bounds.midY
}
Symbol animations
sf symbol에 새로운 애니매이션 추가
새로운 반복 옵션
기존 옵션 강화
replace 옵션이 magic replace가 가능하다면 그렇게 동작
불가능한 경우 fallback으로 동작
.replace.magic(fallback: .upUp)
새로운 SF Symbols 앱과 관련 세션 참조
Sensory feedback
UICanvasFeedbackGenerator를 사용
@ViewLoading var feedbackGenerator: UICanvasFeedbackGenerator
override func viewDidLoad() {
super.viewDidLoad()
feedbackGenerator = UICanvasFeedbackGenerator(view: view)
}
func dragAligned(_ sender: UIPanGestureRecognizer) {
feedbackGenerator.alignmentOccurred(at: sender.location(in: view))
}
플랫폼에 따라서 햅틱, 오디오, 둘 다, 혹은 아무것도 없을 수도 있다.
Text Improvements
UITextView에 textAttributes를 커스텀할 수 있는 기능 추가
하이라이트 관련 attribute추가
var attributes = [NSAttributedString.Key: Any]()
// Highlight style
attributes[.textHighlightStyle] =
NSAttributedString.TextHighlightStyle.default
// Highlight color scheme
attributes[.textHighlightColorScheme] =
NSAttributedString.TextHighlightColorScheme.default
편집 패널도 커스텀 가능
// UITextFormattingViewController.Configuration
textView.textFormattingConfiguration = .init(groups: [
.group([
.component(.fontAttributes, .mini),
.component(.fontPicker, .regular),
.component(.textColor, .mini)
]),
.group([
.component(.fontPointSize, .mini),
.component(.listStyles, .regular),
.component(.highlight, .mini)
])
])
쓰기 도구 지원
Menu actions
Apple Pencil