(※ iOS 16+ 지원)
그라데이션과 그림자를 사용하기 훨씬 쉬워졌다고 소개한다. 확실히 코드를 작성하면 깔끔한 감이 있어서 좋았고, 이러한 사소한 변화들이 SwiftUI 러닝커브를 다소 줄여주는 것 같다.
let colors: [Color] = [.red, .green, .blue]
ForEach(colors, id: \.self) { color in
Rectangle().fill(color.gradient)
}
Circle()
.fill(.red.shadow(.drop(color: .black, radius: 20))) // 원 밖으로 그림자
Circle()
.fill(.red.shadow(.inner(color: .black, radius: 20))) // 원 안으로 그림자
AnyLayout이란 어떤 레이아웃인지 정의되지 않은, 즉 type-erased 인스턴스이다. 조건에 따라(ex. 화면 회전) VStack 혹은 HStack으로 정의하는 데 용이할 것으로 보인다.
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
let layout = horizontalSizeClass == .regular ? AnyLayout(HStack()) : AnyLayout(VStack())
layout { // HStack or VStack
Image(systemName: "1.circle")
Image(systemName: "2.circle")
Image(systemName: "3.circle")
}
아주 심플한 방식으로 사용자에게 앱 스토어 리뷰 요청할 수 있다고 한다. 앱 리뷰 요청을 할 때에 주의할 점은 자주 뜨지 않게 할 것, 사용자가 중요한 작업을 하고 있는 도중 뜨지 않게 할 것 등이 있다.

import StoreKit
@Environment(\.requestReview) private var requestReview
Button("Review the app") {
requestReview()
}
스크롤뷰에서 keyboard때문에 꽤 애먹는 경우가 있을텐데, 이번에 scrollDismissesKeyboard라는 녀석으로 키보드 올라와있는 상태에서 스크롤할 시, 키보드를 어떻게 할 것인지 정의할 수 있게 되었다.
스크롤 indicator 또한 4가지로 커스터마이징이 가능하게 되었는데 사실 엄청 혁신적이다!! 라고는 못 느낀 부분이었다.
ScrollView {
VStack {...}
}.scrollDismissesKeyboard(.interactively) // 스크롤 내리면, 키보드도 그만큼 살짝 내려감
.scrollDismissesKeyboard(.automatic) // 상황에 맞게 최적화
.scrollDismissesKeyboard(.immediately) // 스크롤하면, 즉시 키보드 내려감
.scrollDismissesKeyboard(.never) // 스크롤해도, 절대 안 내려감
.scrollIndicators(.hidden) // 스크롤하는 방향에서 indicator 보이지 않도록 처리
.scrollIndicators(.automatic) // 상황에 따라 보이거나 보이지 않게 설정할 수 있음
.scrollIndicators(.never) // 안 나타남
.scrollIndicators(.visible) // 플랫폼(macOS, iOS)에 따라 보이거나 안 보일 수 있음
유저들이 앱을 사용함에 있어 기본 시스템적인 overlay(ex. 아이폰 하단에 보이는 home indicator 혹은 shareplay indicator, 아이패드에 있는 multi-task indicator, picture-in-picture)들을 가려서 사용성에 영향이 없도록 하는 기능이 추가되었다.
struct ImmersiveView: View {
var body: some View {
Text("Maximum immersion")
.persistentSystemOverlays(.hidden)
}
}
SFSymbol에 값을 유동적으로 변경시킬 수 있음. 유저 interaction시에 재미있게 사용될 수 있을 것으로 기대된다.
@State private var value: CGFloat = 0.0
Image(systemImage: "wifi", variableValue: value)
Image(systemImage: "aqi.low", variableValue: value)
Image(systemImage: "chart.bar.fill", variableValue: value)
Image(systemImage: "waveform", variableValue: value)
Slider(value: $value)

참고