study record
[WWDC2022] What's new in UIKit 본문
주제
Productivity improvements
Control enhancements
API refinements
UIKit and SwiftUI
1. Productivity
- Improved navigation bars
- Title menu
- Find and replace
- Editing interactions
Improved navigation bars
Navigation styles
iOS16에서는 두 가지 다른 네비게이션 스타일 Browser, Editor 스타일이 등장했다.
이들로 하여금 브라우저 베이스 앱들이 Editor style 인터페이스와 함께 유저들에게 친숙한 인터페이스를 제공할 수 있고, Browser style로 document 베이스 앱을 도울 것이다.
또한 타이틀 뷰 대신에 센터 아이템들로 하여금 유저들에게 더 많은 선택지를 준다. 어플리케이션 윈도우들이 옆에 있을 때, 자동적으로 아이템들이 스크린에 맞추어 오버플로우 메뉴가 된다. 추가적으로 Mac Catalyst는 필요로 하는 코드 없이 네비게이션 바를 개선하는 이점을 가진다.
Find and replace
UIKit view들(UITextView, WKWebView, PDFView)을 위한 하나의 flag와 함께 활성화될 수 있다.
Edit menu
iOS16에서 edit menu는 큰 업데이트를 가진다. 터치 상호작용에서 더 인터랙지브하게 재디자인된 메뉴를 가질 수 있다. 또한 포인터들을 위해서 더 특징화된 컨텍스트 메뉴를 제공한다. 이 새로운 특징들을 제공하기 위해서 UIMenuController(Deprecated)의 대체재인 UIEditMenuInteraction API를 사용할 수 있다.
2. Control enhancements
UICalendarView
이제 프로젝트에 캘린더를 사용하고자 할 때, UICalendarView와 함께 사용할 수 있다.
- 단일, 다중 선택 같은 선택 행동들의 타입 제공
- 선택 가능, 선택 불 가능 날짜를 설정
- 다양한 기본 데코레이션 같은 커스텀 뷰 제공
- NSDate 대신 NSDateComponents를 표현하며, 더 옭은 date value 제공
다중 선택을 위해서는 UICalendarSelectionMultiDateDelegate, 단일 선택을 위해서는 UICalendarSelectionSingleDateDelegate을 채택하면 된다.
private lazy var calendarView: UICalendarView = {
let calendarView = UICalendarView()
calendarView.calendar = Calendar(identifier: .gregorian)
calendarView.timeZone = .autoupdatingCurrent
calendarView.locale = .current
calendarView.fontDesign = .default
calendarView.delegate = self
calendarView.visibleDateComponents = DateComponents(calendar: Calendar(identifier: .gregorian), year: 2022, month: 6, day: 1)
// Set singleDateSelection if you want to set for Single Selection
calendarView.selectionBehavior = multiDateSelection
calendarView.selectionBehavior = singleDateSelection
return calendarView
}()
private lazy var multiDateSelection: UICalendarSelectionMultiDate = {
let multiDateSelection = UICalendarSelectionMultiDate(delegate: self)
return multiDateSelection
}()
private lazy var singleDateSelection: UICalendarSelectionSingleDate = {
let singleDateSelection = UICalendarSelectionSingleDate(delegate: self)
return singleDateSelection
}()
UICalendarViewDelegate 프로토콜을 채택함으로써 컨트롤러로 하여금 뷰를 꾸밀 수 있다.
extension UICalendarViewExample: UICalendarViewDelegate {
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
guard let event = eventDays.filter({ $0.dateComponents.isSameDate(with: dateComponents) }).first else {
return nil
}
switch event.decorationType {
case .none:
return nil
case .defaultDecorator:
return .default(color: .purple, size: .large)
case .image:
return .image(.init(systemName: "applelogo"), color: .red)
case .customView:
return .customView {
let label = UILabel()
label.text = "WWDC"
label.textColor = event.titleColor
label.font = .boldSystemFont(ofSize: 10)
return label
}
}
}
}
PageControl
UIPageControl을 더욱 즐기고 작업을 쉽게 하기 위해 control layout의 수직, 수평같은 방향을 설정할 수 있다. 게다가, 커스텀 이미지 특징 또한 상태에 맞추어 추가되었다.
UIPasteControl
iOS16 전에는 copy-paste 기능은 유저에게 배너 형식으로 보여졌다. 지금은 alert형식으로 대체되었다. 이 permission alert는 자동적으로 시스템에 의해 작동되며, 답변에 따라 컨텐츠 접근을 할 수 있다.
3. API Refinements
Customizing Sheets
Sheets는 iOS15에 등장하여, iOS16에서는 그들의 사이즈를 커스텀할 수 있다. 계산된 detents는 safe area를 계산하면 안 된다.
extension UISheetPresentationController.Detent.Identifier {
static let developerDefiened = UISheetPresentationController.Detent.Identifier("developerDefiened")
}
final class UISheetPresentationControllerExample: UIViewController {
private func presentBottomSheet() {
let vc = SFSymbolsExample()
vc.view.backgroundColor = .white
guard let sheet = vc.sheetPresentationController else {
return
}
// sheet.largestUndimmedDetentIdentifier = .developerDefiened - You can add if clear background.
sheet.detents = [
.custom(identifier: .developerDefiened) { context in
context.maximumDetentValue * self.multiplier
}
]
self.present(vc, animated: true)
}
}
Symbol images
iOS15이전에는 monochrome 렌더링이 디폴트로 사용되었다. iOS16에서는 계층적 렌더링이 사용된다. 만약 애플리케이션에서 monochrome을 사용하기 원한다면, UIImage.SymbolConfiguration.preferringMonochrome()을 호출함으로써 monochrome을 사용하는 것을 지속할 수 있다.
또한 iOS16에서 다양한 심볼들이 등장하였다. 팔레트 설정에 의해 렌더링 모드를 사용할 수 있다.
@objc private func sliderDidValueChange(_ sender: UISlider) {
imageView.image = UIImage(
systemName: "wifi",
variableValue: Double(sender.value),
configuration: UIImage.SymbolConfiguration(paletteColors: [.orange])
)
}
Self-resizing cells
iOS16에서 UICollectionView와 UITableView는 self resizing cell을 가지게 된다. “selfSizingInvalidation” 파라미터가 기본으로 접근가능하다.
UICollectionView에서는 UICollectionLayoutListConfiguration와UICollectionViewCompositionalLayout를 사용하는 것이 필요하다. 또한 셀 내에서 컨텐츠뷰 내에 하위뷰들을 더해야 한다. resize 작동을 수동으로 하기위해서는 셀 내부에서 self.invalidateIntrinsicContentSize()를 호출할 수 있다.
private lazy var collectionView: UICollectionView = { [weak self] in
var config = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
let layout = UICollectionViewCompositionalLayout.list(using: config)
let collectionView = UICollectionView(
frame: .zero,
collectionViewLayout: layout
)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.dataSource = self
collectionView.register(
SelfResizingCollectionViewCell.self,
forCellWithReuseIdentifier: SelfResizingCollectionViewCell.description()
)
//Enable by default
collectionView.selfSizingInvalidation = .enabledIncludingConstraints
return collectionView
}()
4. UIKit and SwiftUI
두 프레임워크를 하나의 앱에서 함께 쓰기 위해 개발되었다.
UIHostingConfiguration
UIHostingConfiguration을 활용하여 SwiftUI 뷰를 UITableView나 UITableView 안에서 사용할 수 있다. 가장 좋은 점은 UIKit과 SwiftUI 함께 셀을 만들어 사용할 수 있다는 점이다.
extension UIHostingConfigurationExample: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contentDatas.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let contentData = contentDatas[indexPath.row]
let cell = indexPath.row == 0 ? createSwiftUICell(with: contentData) : createUIKitCell(with: contentData)
return cell
}
}
private extension UIHostingConfigurationExample {
func createSwiftUICell(with contentData: ContentData) -> UITableViewCell {
let cell = UITableViewCell()
cell.contentConfiguration = UIHostingConfiguration {
CustomSwiftUICell(contentData: contentData)
}
return cell
}
func createUIKitCell(with contentData: ContentData) -> UITableViewCell {
let cell = CustomUIKitCell()
cell.configure(with: contentData)
return cell
}
}
UIDevice Deprecations
// Synonym for model. Prior to iOS 16, user-assigned device name (e.g. @"My iPhone").
// In iOS 16 => iPhone 13 Pro Max
// Now it reports device name
UIDevice().name
//Now UIDevice().orientation now supported
//use preferredInterfaceOrientationForPresentation
UIDevice().orientation
UIViewController().preferredInterfaceOrientationForPresentation
참고
'iOS > WWDC' 카테고리의 다른 글
Get started with Writing Tools - WWDC24 (0) | 2024.06.30 |
---|