blendMode: Sets the blend mode for compositing this view with overlapping views.(해당 뷰를 겹치는 뷰로 합성하기 위한 블렌드 모드 설정)
blendMode(_:) | Apple Developer Documentation
Sets the blend mode for compositing this view with overlapping views.
developer.apple.com
func blendMode(_ blendMode: BlendMode) -> some View
BlendMode를 인자로 받아 뷰를 반환해 준다고 하는군요.
BlendMode | Apple Developer Documentation
Modes for compositing a view with overlapping content.
developer.apple.com
블렌드 모드 설정을 위해 원이 겹치는 뷰를 그려줍니다.
struct ContentView: View {
var body: some View {
ZStack {
Circle()
.fill(.red)
.frame(width: 200, height: 200)
.offset(x: -50)
Circle()
.fill(.blue)
.frame(width: 200, height: 200)
.offset(x: 50)
}
}
}
확인을 위해 임의의 블렌드 모드를 추가해 볼게요.
struct ContentView: View {
var body: some View {
ZStack {
Circle()
.fill(.red)
.frame(width: 200, height: 200)
.offset(x: -50)
Circle()
.fill(.blue)
.frame(width: 200, height: 200)
.offset(x: 50)
.blendMode(.colorBurn)
}
}
}
정확히 어떤 모드인지는 몰라도, 블렌드 모드가 정상적으로 적용되는 것을 확인할 수 있습니다.
BlendMode는 Enum으로 기본 값인 normal을 포함해 21가지가 있는데, 각 값들이 어떤 식으로 표현되는지 확인을 위해 Picker에서 선택해 변화를 확인할 수 있도록 코드를 작성해 보겠습니다.
BlendMode의 상태가 변화할 때마다 뷰를 새로고침 할 수 있도록 State 변수를 선언하고, 할당해줍니다.
struct ContentView: View {
@State var blendState: BlendMode = BlendMode.normal
var body: some View {
ZStack {
Circle()
.fill(.red)
.frame(width: 200, height: 200)
.offset(x: -50)
Circle()
.fill(.blue)
.frame(width: 200, height: 200)
.offset(x: 50)
.blendMode(blendState)
}
}
}
Picker와 ForEach를 사용해서 선택한 블렌드 모드가 적용되길 바랐는데, Enum 타입이라 적용이 되지 않네요.
extension을 통해 BlendMode를 Picker에서 사용할 수 있도록 만들어주겠습니다.
extension을 위해 파일을 추가한 후, CaseIterable 프로토콜을 추가해 줄게요.
import SwiftUI
extension BlendMode: CaseIterable {
public static var allCases: [BlendMode]
}
BlendMode.allCases에 값을 넣어줍니다.
extension BlendMode: CaseIterable {
public static var allCases: [BlendMode] = [.color, .colorBurn, .colorDodge, .darken,
.destinationOut, .destinationOver, .difference, .exclusion,
.hardLight, .hue, .lighten, .luminosity,
.multiply, .normal, .overlay, .plusDarker,
.plusLighter, .saturation, .screen, .softLight,
.sourceAtop]
}
수정한 extension에 맞춰 Picker를 고치고 확인해 보면 0부터 20까지 21개가 모두 들어있는 걸 확인할 수 있습니다.
Picker(selection: $blendState) {
ForEach(BlendMode.allCases.indices) { state in
Text(state.description)
}
} label: { }
하지만, 우리가 원하는 건 숫자로 나오는 게 아니죠. extension에 코드를 추가해줍시다.
extension BlendMode: CaseIterable {
public static var allCases: [BlendMode] = [.color, .colorBurn, .colorDodge, .darken,
.destinationOut, .destinationOver, .difference, .exclusion,
.hardLight, .hue, .lighten, .luminosity,
.multiply, .normal, .overlay, .plusDarker,
.plusLighter, .saturation, .screen, .softLight,
.sourceAtop]
var state: String {
switch self {
case .normal:
return "normal"
case .multiply:
return "multiply"
case .screen:
return "screen"
case .overlay:
return "overlay"
case .darken:
return "darken"
case .lighten:
return "lighten"
case .colorDodge:
return "colorDodge"
case .colorBurn:
return "colorBurn"
case .softLight:
return "softLight"
case .hardLight:
return "hardLight"
case .difference:
return "difference"
case .exclusion:
return "exclusion"
case .hue:
return "hue"
case .saturation:
return "saturation"
case .color:
return "color"
case .luminosity:
return "luminosity"
case .sourceAtop:
return "sourceAtop"
case .destinationOver:
return "destinationOver"
case .destinationOut:
return "destinationOut"
case .plusDarker:
return "plusDarker"
case .plusLighter:
return "plusLighter"
@unknown default:
fatalError()
}
}
}
마지막으로, Picker를 수정해 주면 끝입니다.
Picker(selection: $blendState) {
ForEach(BlendMode.allCases, id: \\.self) { state in
Text(state.state)
}
} label: { }
각 BlendMode에 따른 변화
Dark Mode
Light Mode
'Swift' 카테고리의 다른 글
Vision: visionOS simulator (0) | 2023.08.22 |
---|---|
Vision: visionOS란? (0) | 2023.08.22 |
SwiftUI: map, compactMap, flatMap (0) | 2023.08.11 |
SwiftUI: Mask Design (0) | 2023.08.11 |
SwiftUI: 온보딩 (0) | 2023.08.07 |