SwiftUI ΠΈΠΌΠ΅Π΅Ρ ΠΎΡΠ»ΠΈΡΠ½ΡΠΉ API Π΄Π»Ρ ΡΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΠΈ view Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΠΈΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ. Π ΡΡΠΎΠΌ ΠΏΠΎΡΡΠ΅ ΠΌΡ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ, ΠΊΠ°ΠΊ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΠΈΠ»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ view ΡΠ°ΠΊΠΈΠΌ ΠΆΠ΅ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ.
Π ΠΏΡΠΎΡΠ»ΠΎΠΌ Π³ΠΎΠ΄Ρ Π² Ρ ΠΎΠ΄Π΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΡΠΏΠΈΠ·ΠΎΠ΄ΠΎΠ² Π½Π° Swift Talk ΠΌΡ ΠΏΡΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΠΎΠ²Π°Π»ΠΈ, ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΡΠ΅ΠΏΠΏΠ΅Ρ Π΄Π»Ρ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΈΡ ΠΈ ΡΠΌΠ΅Π½ΡΡΠ΅Π½ΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ. ΠΠ½ Π±ΡΠ» ΠΏΠΎΡ ΠΎΠΆ Π½Π° Stepper Π² SwiftUI, Π½ΠΎ Ρ API, ΠΊΠΎΡΠΎΡΡΠΉ Π΄Π΅Π»Π°Π΅Ρ Π΅Π³ΠΎ ΡΡΠΈΠ»ΡΠ½ΡΠΌ.
ΠΡΠΎΡ ΠΏΠΎΡΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΊΡΠ°ΡΠΊΠΈΠΌ ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΌΡ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π»ΠΈ ΡΠΎΠ³Π΄Π°, Π° ΡΠ°ΠΊΠΆΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ ΠΏΡΠΈΡΠΌΠ°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΡ Π½Π°ΡΡΠΈΠ»ΠΈΡΡ Ρ ΡΠ΅Ρ ΠΏΠΎΡ, ΡΡΠΎΠ±Ρ Π½Π°ΡΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ ΡΡΠΈΠ»ΠΈ view (ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΠ΅, Π²ΡΡ, Π²ΡΡΡΠΊΠ°) ΡΠ°Π±ΠΎΡΠ°Π»ΠΈ Π΅ΡΡ Π»ΡΡΡΠ΅, ΠΊΠ°ΠΊ built-in (Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠ΅) Π² SwiftUI. Π ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΠΏΠΎΡΡΠ΅ ΠΌΡ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΡ Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ.
Β
Π‘ΡΠΈΠ»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° Π΄Π°Π²Π°ΠΉΡΠ΅ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ Π½Π° ΠΏΡΠΎΡΡΡΡ ΠΊΠ½ΠΎΠΏΠΊΡ:

Button("Continue") {
Β Β // Continue
}
Β
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΡΡΠΈΠ»Ρ ΡΡΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠΈ, Π΄ΠΎΠ±Π°Π²ΠΈΠ² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠ² view ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π΄ΡΡΠ³ΠΎΠΉ ΠΌΠ΅ΡΠΎΠ΄ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ label (ΠΌΠ΅ΡΠΊΠΈ) ΠΊΠ½ΠΎΠΏΠΊΠΈ:
Button { Β Β
Β Β // Continue
} label: {
Β Β HStack {
Β Β Β Β Spacer()
Β Β Β Β Text("Continue")
Β Β Β Β Spacer()
Β Β }
Β Β .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
Β Β }
Β Β .font(.system(.title2, design: .rounded, weight: .bold))
Β Β .foregroundColor(.yellow)
Β Β .background(Capsule().stroke(.yellow, lineWidth: 2))
Β
Π₯ΠΎΡΡ SwiftUI Π΄Π΅Π»Π°Π΅Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΡ view ΠΎΡΠ΅Π½Ρ ΡΠ΄ΠΎΠ±Π½ΠΎΠΉ, Π½ΠΎ ΠΏΠ»ΠΎΡ ΠΎ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΡΠ΅ΡΡΡ. ΠΠ΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ ΠΎΠ΄Π½ΠΈ ΠΈ ΡΠ΅ ΠΆΠ΅ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ ΠΈ ΠΎΠ±ΠΎΡΠ°ΡΠΈΠ²Π°ΡΡ ΠΌΠ΅ΡΠΊΡ Π² HStack. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π½Π°ΠΌ Π½ΡΠΆΠ΅Π½ Π±ΠΎΠ»Π΅Π΅ ΠΌΠ½ΠΎΠ³ΠΎΡΠ°Π·ΠΎΠ²ΡΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄.

Π’Π°ΠΊΠ°Ρ ΠΊΠ½ΠΎΠΏΠΊΠ° Π²ΠΎ Π²ΡΡ ΡΠΈΡΠΈΠ½Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ½Π½ΡΠΌ ΡΡΠΈΠ»Π΅ΠΌ, Π½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ Π΅Ρ Π½Π΅ΠΏΡΠΎΡΡΠΎ.
Β
ΠΠΎΠ²ΡΠΎΡΠ½ΠΎΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΠΈΠ»Ρ
ΠΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π°ΠΌ ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ, ΡΡΠΎΠ±Ρ view ΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΈΠΌΠ΅Π»ΠΈ Π΅Π΄ΠΈΠ½ΡΠΉ ΡΡΠΈΠ»Ρ Π²ΠΎ Π²ΡΠ΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, ΡΠ΄Π΅Π»Π°ΡΡ ΠΈΡ ΡΠ·Π½Π°Π²Π°Π΅ΠΌΡΠΌΠΈ Π΄Π»Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΏΡΠΈ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄Π΅ Ρ ΡΠΊΡΠ°Π½Π° Π½Π° ΡΠΊΡΠ°Π½, Π° ΡΠ°ΠΊΠΆΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ΅ΠΌΡ Π΄Π»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈΠ»ΠΈ ΠΏΡΠΈΠ²ΡΠ·ΠΊΡ ΠΊ Π±ΡΠ΅Π½Π΄Ρ ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΈ.
Π§ΡΠΎΠ±Ρ ΡΠΏΡΠΎΡΡΠΈΡΡ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ ΡΠΎΠ³ΠΎ ΠΆΠ΅ ΡΡΠΈΠ»Ρ ΠΊΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠΌ view Button, ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ² β ΡΡΠΎ ΡΠΎΠ·Π΄Π°ΡΡ Π½ΠΎΠ²ΠΎΠ΅ view ΠΊΠ½ΠΎΠΏΠΊΠΈ Ρ API, Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΡΠΌ SwiftUI Button, ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΠΊ Π½Π΅ΠΌΡ ΡΡΠΈΠ»Ρ:
struct MyButton
Β Β var action: () -> Void
Β Β var label: Label
Β Β init(action: @escaping () -> Void, @ViewBuilder label: () -> Label) {
Β Β Β Β self.action = action
Β Β Β Β self.label = label()
Β Β }
Β Β var body: some View {
Β Β Β Β Button {
Β Β Β Β Β Β action()
Β Β Β Β } label: {
Β Β Β Β Β Β HStack {
Β Β Β Β Β Β Β Β Spacer()
Β Β Β Β Β Β Β Β Label
Β Β Β Β Β Β Β Β Spacer()
Β Β Β Β Β Β }
Β Β Β Β Β Β .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
Β Β Β Β }
Β Β Β Β .font(.system(.title2, design: .rounded, weight: .bold))
Β Β Β Β .foregroundColor(.yellow)
Β Β Β Β .background(Capsule().stroke(.yellow, lineWidth: 2))
Β Β }
}
Β
ΠΠ΄Π½Π°ΠΊΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΎΠ±ΡΡΡΠΊΠΈ view, ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΠ΅Π³ΠΎ ΡΠ΅ ΠΆΠ΅ ΡΠ΄ΠΎΠ±Π½ΡΠ΅ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΎΡΡ, ΡΡΠΎ ΠΈ ΠΎΠ±ΡΡΡΠΊΠ° view, ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠ°Π±ΠΎΡΡ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΏΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΠΎΠΌ Π½ΠΈΠΆΠ΅ ΠΊΠΎΠ΄Π΅:
struct MyButton where Label == Text {
Β Β @_disfavoredOverload
Β Β init(_ title: some StringProtocol, role: ButtonRole? = nil, action: @escaping () -> Void) {
Β Β Β Β self.action = action
Β Β Β Β self.role = role
Β Β Β Β self.label = Text(title)
Β Β }
Β Β init(_ titleKey: LocalizedStringKey, role: ButtonRole? = nil, action: @escaping () -> Void) {
Β Β Β Β self.action = action
Β Β Β Β self.role = role
Β Β Β Β self.label = Text(titleKey)
Β Β }
}
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΡΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΊΠΎΠ΄Π°, Button ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ Π»ΠΈΡΠ΅ΡΠ°Π» String ΠΊΠ°ΠΊ LocalizedStringKey, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΠ°Π±Π»ΠΎΠ½ @_disfavoredOverload. ΠΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΡΠΎΠ½ΠΊΠΎΡΡΠΈ ΠΌΠΎΠ³ΡΡ ΡΠ΄Π΅Π»Π°ΡΡ Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠΉ Π·Π°ΠΌΠ΅Π½Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ view Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΄ΠΎΡΠΌΠΊΠΎΠΉ, ΡΠ΅ΠΌ ΠΎΠΆΠΈΠ΄Π°Π»ΠΎΡΡ.
Π₯ΠΎΡΡ ΡΡΠΈΠ»Ρ, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅, ΡΡΠΎ Ρ ΠΎΡΠΎΡΠΎ, Π²Π°ΠΆΠ½ΠΎ Π½Π΅ Π·Π°Π±ΡΠ²Π°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ view MyButton Π²ΠΌΠ΅ΡΡΠΎ ΠΊΠ½ΠΎΠΏΠΊΠΈ SwiftUI Π²ΠΎ Π²ΡΡΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ. Π ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ Π½Π΅ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΡΠΈΠ»Ρ.
VStack {
Β Β MyButton("OK") {
Β Β Β Β // Confirm
Β Β }
Β Β Button("Cancel") {
Β Β Β Β // Oops, wrong button
Β Β }
}

Π ΡΡΠ°ΡΡΡΡ, Ρ SwiftUI Π΅ΡΡΡ API, ΡΠ΅ΡΠ°ΡΡΠΈΠΉ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
Β
View ΡΡΠΈΠ»Π΅ΠΉ
API view ΡΡΠΈΠ»Π΅ΠΉ SwiftUI ΡΠ°Π±ΠΎΡΠ°ΡΡ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ view font(_:) ΠΈ tint(_:), ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΡΡΠΈΠ»Ρ Π² ΠΈΠ΅ΡΠ°ΡΡ ΠΈΡ view ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ ΡΡΠΎΡ ΡΡΠΈΠ»Ρ ΠΊΠΎ Π²ΡΠ΅ΠΌ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ view Π² ΡΡΠΎΠΉ ΠΈΠ΅ΡΠ°ΡΡ ΠΈΠΈ:
HStack {
Β Β Button("Undo") { /* β¦ */ }
Β Β Button("Redo") { /* β¦ */ }
}
.foregroundColor(.black)
.font(.system(.title3, design: .rounded).bold())
.tint(.yellow)
.buttonStyle(.borderedProminent)

Β
ΠΠ΄Π΅ΡΡ ΡΠ²Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π½Π΅Π³ΠΎ ΠΏΠ»Π°Π½Π°, ΡΡΠΈΡΡ, ΠΎΡΡΠ΅Π½ΠΎΠΊ ΠΈ ΡΡΠΈΠ»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ, ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π² HStack, ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΡΡΡΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΡΡ ΠΊΠ½ΠΎΠΏΠΊΡ.
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, ΡΡΠΎΠ±Ρ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΡΡΠΈΠ»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π²ΠΎ Π²ΡΠ΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, ΠΏΡΠΈΠΌΠ΅Π½ΡΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π² ΠΊΠΎΡΠ½Π΅ ΠΈΠ΅ΡΠ°ΡΡ ΠΈΠΈ view:
@main
struct MyApp: App {
Β Β var body: some Scene {
Β Β Β Β WindowGroup {
Β Β Β Β Β Β ContentView()
Β Β Β Β Β Β Β Β .tint(.yellow)
Β Β Β Β Β Β Β Β .buttonStyle(.borderedProminent)
Β Β Β Β }
Β Β }
}
Β
SwiftUI ΠΈΠΌΠ΅Π΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ ΡΡΠΈΠ»Π΅ΠΉ Π½Π° Π²ΡΠ±ΠΎΡ, Π° Π΄Π»Ρ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ view, Π΄ΠΎΠΏΡΡΠΊΠ°ΡΡΠΈΡ ΡΡΠΈΠ»ΠΈ, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ Π½ΠΎΠ²ΡΠ΅ ΡΡΠΈΠ»ΠΈ.
Β
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ ΡΡΠΈΠ»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ
Π§ΡΠΎΠ±Ρ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π½Π°ΡΡΡΠΎΠΈΡΡ ΡΡΠΈΠ»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ, Π½Π°ΠΌ ΡΠ½Π°ΡΠ°Π»Π° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΡΠΎ-ΡΠΎ, ΡΡΠΎ SwiftUI ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΡΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΈ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΈ ΠΊΠ½ΠΎΠΏΠΊΠΈ.
ΠΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ buttonStyle(_:), ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π΄Π»Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΡΠΈΠ»Ρ ΠΊΠ½ΠΎΠΏΠΎΠΊ, ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠΈΠΏ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ Π»ΠΈΠ±ΠΎ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Ρ ButtonStyle, Π»ΠΈΠ±ΠΎ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Ρ PrimitiveButtonStyle.
ΠΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΡΡΠΈΠ»Ρ, ΠΌΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΡΠΈΠΏ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΎΠ΄Π½ΠΎΠΌΡ ΠΈΠ· ΡΡΠΈΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΎΠ².
ΠΠ»Ρ ΠΎΠ±ΠΎΠΈΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΎΠ² ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ makeBody(configuration:). ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ, ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½Π°Ρ ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ, ΠΈΠΌΠ΅Π΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ²ΠΎΠΉΡΡΠ², ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΡ, ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ ΠΎΡΠΎΡΠΌΠ»ΡΠ΅ΠΌ.
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ configuration.label, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ view, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡΠ΅Π΅ ΠΌΠ΅ΡΠΊΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ, ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ Π½Π°Ρ ΡΡΠΈΠ»Ρ ΠΊ ΡΡΠΎΠΉ ΠΌΠ΅ΡΠΊΠ΅:
struct CustomButtonStyle: ButtonStyle {
Β Β func makeBody(configuration: Configuration) -> some View {
Β Β Β Β HStack {
Β Β Β Β Β Β Spacer()
Β Β Β Β Β Β configuration.label
Β Β Β Β Β Β Spacer()
Β Β Β Β }
Β Β Β Β .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
Β Β Β Β .font(.system(.title2, design: .rounded).bold())
Β Β Β Β .padding(EdgeInsets(top: 12, leading: 24, bottom: 12, trailing: 24))
Β Β Β Β .foregroundColor(.yellow)
Β Β Β Β .background {
Β Β Β Β Β Β Capsule()
Β Β Β Β Β Β Β Β .stroke(.yellow, lineWidth: 2)
Β Β Β Β }
Β Β }
}
Β
ΠΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΉ Π²ΡΡΠ΅ ΠΊΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΡΠΈΠ»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ .buttonStyle(CustomButtonStyle()).
Β ΠΡΡΠ³ΠΈΠ΅ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ view, Π΄Π»Ρ ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΡΠΈΠ»ΠΈ:
- Toggle
- DatePicker
- Gauge
- ProgressView
- Label
- LabeledContent
- DisclosureGroup
- ControlGroup
- GroupBox
- Form
ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΡΠΈΠ»Ρ ΡΠ°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ ΡΠ²ΠΎΠΉΡΡΠ²Π°, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΡΡΠΈΠ»Ρ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ, Π½Π°ΠΆΠ°ΡΠ° Π»ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ° ΠΈ ΠΊΠ°ΠΊΡΡ ΡΠΎΠ»Ρ ΠΈΠ³ΡΠ°Π΅Ρ ΠΊΠ½ΠΎΠΏΠΊΠ°.
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π°, ΡΡΠΎΠ±Ρ ΠΏΡΠΈΠ΄Π°ΡΡ ΠΊΠ½ΠΎΠΏΠΊΠ΅ Π΄ΡΡΠ³ΠΎΠΉ Π²ΠΈΠ΄ ΠΏΡΠΈ Π½Π°ΠΆΠ°ΡΠΈΠΈ ΠΈΠ»ΠΈ Π΅ΡΠ»ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ° Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ Π΄Π΅ΡΡΡΡΠΊΡΠΈΠ²Π½ΠΎΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅:
.background {
Β Β Capsule()
Β Β Β Β .stroke(configuration.role == .destructive ? .red : .yellow, lineWidth: 2)
}
.opacity(configuration.isPressed ? 0.5 : 1)
VStack(spacing: 16) {
Β Β Button(role: .destructive) {
Β Β Β Β // Delete
Β Β } label: {
Β Β Β Β Label("Delete", systemImage: "trash")
Β Β }
Β Β Button("Cancel", role: .cancel) {
Β Β Β Β // Cancel Deletion
Β Β }
}
.buttonStyle(CustomButtonStyle())

Β
Β
Π‘ΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡΠΊΠ»ΡΡΠ΅Π½Π½ΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ
ΠΡΠΈΠΌΠ΅ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎ, ΡΡΠΎ Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ ΡΠ»Π°Π³, ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΠΈΠΉ, Π²ΡΠΊΠ»ΡΡΠ΅Π½Π° Π»ΠΈ ΠΊΠ½ΠΎΠΏΠΊΠ°. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π²ΡΠΊΠ»ΡΡΠ΅Π½Π½ΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ, ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ view disabled(_:).
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΠΎΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ view ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ view, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π²ΡΠΊΠ»ΡΡΠ΅Π½Π½ΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ Π² Π»ΡΠ±ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ ΠΈΠ΅ΡΠ°ΡΡ ΠΈΠΈ view. ΠΡΠΎ ΡΠ΄ΠΎΠ±Π½ΠΎ, ΠΊΠΎΠ³Π΄Π°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΠΎΡΠΊΠ»ΡΡΠΈΡΡ Π²ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π²ΠΎ view Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΡΠΌΡ.
ΠΠ΄Π½Π°ΠΊΠΎ Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ Π½Π΅ ΡΠΊΠ°Π·Π°Π½ΠΎ, ΡΡΠΎ ΡΡΠΎΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ environment (ΡΡΠ΅Π΄Ρ). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ Π½Π°ΡΡΡΠΎΠΈΡΡ ΠΊΠ½ΠΎΠΏΠΊΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½Π° ΠΎΡΠΊΠ»ΡΡΠ΅Π½Π°, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ environment isEnabled:
@Environment(\.isEnabled) var isEnabled
func makeBody(configuration: Configuration) -> some View {
Β Β // ...
Β Β Β Β .saturation(isEnabled ? 1 : 0)
}

Β
Β
Π‘ΡΠΈΠ»ΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΡ view
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΡΠΈΠ»ΠΈ Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ view SwiftUI ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΡΠ΅Π½Ρ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ Π²ΡΠ³Π»ΡΠ΄ΡΡ Π½Π΅ ΡΠ°ΠΊ, ΠΊΠ°ΠΊ Π½Π°ΠΌ Π±Ρ ΡΠΎΠ³ΠΎ Ρ ΠΎΡΠ΅Π»ΠΎΡΡ, Π½ΠΎ, ΠΊ ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΡΠΈΠ»ΠΈ Π΄Π»Ρ Π²ΡΠ΅Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ view SwiftUI.
Π₯ΠΎΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΈΠ±Π΅Π³Π½ΡΡΡ ΠΊ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠ² view Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΡΠΈΠ»Ρ Π² ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΡ view ΠΈΠ»ΠΈ ΠΎΠ±ΠΎΠΉΡΠΈΡΡ ΡΠ΅ΠΌ, ΡΡΠΎ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ SwiftUI, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π΄ΠΎΠ±ΠΈΡΡΡΡ Π±ΠΎΠ»ΡΡΠ΅Π³ΠΎ ΡΡΠΏΠ΅Ρ Π°, ΡΠ΄Π΅Π»Π°Π² Π½Π°ΡΠΈ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌΡΠ΅ view ΡΡΠΈΠ»ΠΈΠ·ΡΠ΅ΠΌΡΠΌΠΈ. ΠΠ°Π²Π°ΠΉΡΠ΅ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΡΡΠΎ Π½Π° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ΅ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ RangeSlider:
struct RangeSlider
Β Β @Binding
Β Β var range: ClosedRange
Β Β var bounds: ClosedRange
Β Β var label: Label
Β Β init(value: Binding
Β Β Β Β self._value = value
Β Β Β Β self.bounds = bounds
Β Β Β Β self.label = label()
Β Β }
Β Β var body: some View {
Β Β Β Β LabeledContent {
Β Β Β Β Β Β // ...
Β Β Β Β } label: {
Β Β Β Β Β Β Label
Β Β Β Β }
Β Β }
}

ΠΡΠ°ΠΊ, ΡΡΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΡΠΈ, ΡΡΠΎΠ±Ρ ΡΡΠΎ view ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΡΡΠΈΠ»ΠΈΠ·ΠΎΠ²Π°ΡΡ?
ΠΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΡ ΠΊ API ΡΡΠΈΠ»Ρ SwiftUI Π΄Π»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ, ΠΌΡ Π²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ Ρ Π½Π΅Π³ΠΎ Π΅ΡΡΡ Π΄Π²Π° ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π° Π΄Π»Ρ ΠΎΡΠΎΡΠΌΠ»Π΅Π½ΠΈΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ.
ButtonStyle ΡΠΏΡΠΎΡΠ°Π΅Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΡΡ ΡΡΠΈΠ»Π΅ΠΉ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Button ΠΏΠΎΠ·Π°Π±ΠΎΡΠΈΡΡΡΡ ΠΎΠ± ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ΅ ΠΆΠ΅ΡΡΠΎΠ², Π° PrimitiveButtonStyle Π΄Π°ΡΡ ΡΡΠΈΠ»Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ Π½Π°Π΄ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠ΅ΠΉ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ Ρ ΠΊΠ½ΠΎΠΏΠΊΠΎΠΉ.
ΠΡΡΠ³ΠΈΠ΅ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Ρ ΡΡΠΈΠ»Π΅ΠΉ Π² SwiftUI Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°ΡΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» PrimitiveButtonStyle ΡΠ΅ΠΌ, ΡΡΠΎ ΠΎΠ½ΠΈ ΡΠ°ΠΊΠΆΠ΅ Π΄Π°ΡΡ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ Π½Π°Π΄ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ΠΌ ΡΠΎ ΡΡΠΈΠ»Π΅ΠΌ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΈ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ToggleStyle view Toggle Π½Π΅ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΆΠ΅ΡΡ Π·Π° Π½Π°Ρ. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΎΠ½ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΡΠΈΠ²ΡΠ·ΠΊΡ Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΠ²ΠΎΠΈΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΡΡΠΈΠ»Ρ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΊΠ°ΡΠ°Π΅ΡΡΡ view.
Π§ΡΠΎΠ±Ρ Π΄Π°ΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ Π½Π°Π΄ ΡΡΠΈΠ»ΡΠΌΠΈ ΠΏΠΎΠ»Π·ΡΠ½ΠΊΠ° Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ, ΠΊΠ°ΠΊΠΈΠΌ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΠ½ΠΎΠ²ΡΠ²Π°ΡΡ Π½Π°Ρ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» ΡΡΠΈΠ»Π΅ΠΉ Π½Π° ΠΏΡΠΈΠΌΠΈΡΠΈΠ²Π½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ API ΡΡΠΈΠ»Π΅ΠΉ ΠΊΠ½ΠΎΠΏΠΎΠΊ SwiftUI.
API-ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ ΡΡΠΈΠ»Π΅ΠΉ ΡΠΎΡΡΠΎΡΡ ΠΈΠ· ΡΡΠ΅Ρ ΡΠ°ΡΡΠ΅ΠΉ β ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° view, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠ³ΠΎ Π΄Π»Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΡΠΈΠ»Ρ, ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π° ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΡΡΠΈΠ»Ρ:
extension View {
Β Β public func buttonStyle(_ style: S) -> some View where S : PrimitiveButtonStyle
}
Β
public protocol PrimitiveButtonStyle {
Β Β associatedtype Body : View
Β Β @ViewBuilder func makeBody(configuration: Self.Configuration) -> Self.Body
Β Β typealias Configuration = PrimitiveButtonStyleConfiguration
}
Β
public struct PrimitiveButtonStyleConfiguration {
Β Β // ...
Β Β public let role: ButtonRole?
Β Β public let label: PrimitiveButtonStyleConfiguration.Label
Β Β public func trigger()
}
Β
Π§ΡΠΎΠ±Ρ ΡΡΠΈΠ»ΠΈΠ·ΠΎΠ²Π°ΡΡ RangeSlider ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ view, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ Π±ΠΎΠ»ΡΡΡΡ ΡΠ°ΡΡΡ ΠΊΠΎΠ΄Π° Π²ΡΡΠ΅.
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΡΠ°ΡΡ Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ Π½Π°ΡΠ΅Π³ΠΎ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΡΡΠΈΠ»Ρ.
Π‘Π²ΠΎΠΉΡΡΠ²Π° PrimitiveButtonStyleConfiguration ΠΌΠΎΠ³ΡΡ ΠΏΠΎΠΊΠ°Π·Π°ΡΡΡΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π·Π½Π°ΠΊΠΎΠΌΡΠΌΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ΠΈ ΠΏΠΎΡΡΠΈ Π½Π°ΠΏΡΡΠΌΡΡ ΡΠΎΠΏΠΎΡΡΠ°Π²Π»ΡΡΡΡΡ Ρ ΡΠΈΠΏΠ°ΠΌΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΎΡΠΎΠ² Button:
public init(
Β Β role: ButtonRole?,
Β Β action: @escaping () -> Void,
Β Β @ViewBuilder label: () -> Label
)
Β
role ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ βΠΊΠ°ΠΊ Π΅ΡΡΡβ, action ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΎ ΠΊΠ°ΠΊ ΡΡΠΈΠ³Π³Π΅ΡΠ½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ, Π° label ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ view ΡΠΎ ΡΡΡΡΡΡΠΌ ΡΠΈΠΏΠΎΠΌ.
Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π΄Π»Ρ Π½Π°ΡΠ΅Π³ΠΎ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΡ ΠΆΠ΅ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΈ ΡΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ ΡΠΈΠΏΡ ΠΈΠ· Π½Π°ΡΠ΅Π³ΠΎ view Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ:
struct RangeSliderStyleConfiguration {
Β Β @Binding
Β Β let range: ClosedRange
Β Β let bounds: ClosedRange
Β Β let label: Label
}
Β
ΠΠ°ΠΊ ΠΌΡ Π²ΠΈΠ΄Π΅Π»ΠΈ Π² ΡΠ»ΡΡΠ°Π΅ Ρ ΠΎΡΠΊΠ»ΡΡΠ΅Π½Π½ΡΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ΠΌ Π΄Π»Ρ ΠΊΠ½ΠΎΠΏΠΊΠΈ, Ρ Π½Π°Ρ Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ Π² environment, Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΡΠΈΠ»Ρ. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΡΡΠΈΠ»ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΠΌΠ΅ΡΡ ΠΏΡΡΠΌΠΎΠΉ Π΄ΠΎΡΡΡΠΏ ΠΊ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌ environment.
ΠΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΉ Π²ΡΡΠ΅ ΠΊΠΎΠ΄ ΠΏΡΠΎΡΡ Π΄Π»Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΈ Π³ΡΠ°Π½ΠΈΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΎΡΡΠΎ ΡΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ ΠΈΡ ΠΊΠ°ΠΊ Π΅ΡΡΡ. ΠΠ΄Π½Π°ΠΊΠΎ Π΄Π»Ρ ΠΌΠ΅ΡΠΊΠΈ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ-ΡΠΎ Π΄ΡΡΠ³ΠΎΠ΅, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎΡ ΡΠΈΠΏ ΡΠ΅ΠΏΠ΅ΡΡ ΠΎΡΠ½ΠΎΡΠΈΡΡΡ ΠΊ ΡΠΈΠΏΡ ΠΌΠ΅ΡΠΊΠΈ SwiftUI, Π° Π½Π΅ ΠΊ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΠΎΠΌΡ ΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠΉ RangeSlider ΠΈΠΌΠ΅Π΅Ρ Π΄Π»Ρ ΡΠ²ΠΎΠ΅ΠΉ ΠΌΠ΅ΡΠΊΠΈ.
ΠΠ½ΠΎΠΏΠΊΠ° ΡΠ°ΠΊΠΆΠ΅ ΠΈΠΌΠ΅Π΅Ρ ΠΎΠ±ΡΠΈΠΉ ΡΠΈΠΏ Π΄Π»Ρ ΡΠ²ΠΎΠ΅ΠΉ ΠΌΠ΅ΡΠΊΠΈ, ΡΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΊΠ½ΠΎΠΏΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΡΠ°Π·Π½ΡΠ΅ ΡΠΈΠΏΡ view Π΄Π»Ρ ΡΠ²ΠΎΠΈΡ ΠΌΠ΅ΡΠΎΠΊ. ΠΠ΅ΡΠΊΠ° ΠΊΠ½ΠΎΠΏΠΊΠΈ ΡΠ°ΡΡΠΎ ΠΈΠΌΠ΅Π΅Ρ ΡΠΈΠΏ Text, Label ΠΈΠ»ΠΈ HStack, Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π»ΡΠ±ΠΎΠ³ΠΎ ΡΠΈΠΏΠ°.
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π½Π΅ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ ΡΠΈΠΏΠΎΠ² ΠΊΠ½ΠΎΠΏΠΎΠΊ, SwiftUI ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΡΠΈΡΠ°Π½ΠΈΠ΅ ΡΠΈΠΏΠΎΠ², ΡΡΠΎΠ±Ρ ΡΠΊΡΡΡΡ ΠΈΡ Π²ΡΠ΅ Π·Π° Π½Π΅ΠΏΡΠΎΠ·ΡΠ°ΡΠ½ΡΠΌ view ButtonConfiguration.Label. ΠΡΠΎ ΠΈΠ·ΠΎΠ»ΠΈΡΡΠ΅Ρ ΡΡΠΈΠ»Ρ ΠΎΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ Π΅Π΄ΠΈΠ½ΡΠΉ ΡΡΠΈΠ»Ρ ΠΊ Π»ΡΠ±ΠΎΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ ΠΊΠ½ΠΎΠΏΠΊΠ΅.
ΠΡ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΡ ΠΆΠ΅ ΡΠ°Π±Π»ΠΎΠ½, ΡΡΠΎΠ±Ρ ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΎΠ±ΡΠΈΠΉ RangeSlider Π½Π°Π΄ ΡΠ²ΠΎΠ΅ΠΉ ΠΌΠ΅ΡΠΊΠΎΠΉ, ΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ API ΡΡΠΈΠ»Ρ Π½Π΅ Π½ΡΠΆΠ½ΠΎ Π·Π½Π°ΡΡ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠ΅ ΠΌΠ΅ΡΠΊΠΈ Π±ΡΠ΄ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ:
/// A type-erased label of a button.
public struct Label : View {
Β Β public typealias Body = Never
}
Β
SwiftUI ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΡΠΈΠΏ Body ΠΊΠ°ΠΊ Never, ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΡΡΠ½ΡΠ΅ API Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ view ΠΌΠ΅ΡΠΊΠΈ.
ΠΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠΎ, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ Π·Π΄Π΅ΡΡ SwiftUI, Π½ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ AnyView Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΎΠ³ΠΎ ΠΆΠ΅ ΡΡΡΠ΅ΠΊΡΠ°:
/// A type-erased label of a range slider.
struct Label: View {
Β Β let underlyingLabel: AnyView
Β Β init(_ label: some View) {
Β Β Β Β self.underlyingLabel = AnyView(label)
Β Β }
Β Β var body: some View {
Β Β Β Β underlyingLabel
Β Β }
}
Β
Π₯ΠΎΡΡ ΠΌΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ AnyView Π½Π°ΠΏΡΡΠΌΡΡ, ΡΡΠΎ Π΄Π°Π΅Ρ Π½Π°ΠΌ ΡΠΈΠΏ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΠΉ ΡΡΠΈΠ»ΡΠΌ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Ρ Π½Π°Ρ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Π΄Π»Ρ ΡΠ΅ΠΊΡΡΠ°-Π·Π°ΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»Ρ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ ΡΠΎ ΡΡΡΡΡΡΠΌ ΡΡΠΈΡΡΠΎΠΌ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΡΡΠΈΠ»Π΅ ΠΏΠ»Π°Π²Π°ΡΡΠ΅ΠΉ ΠΌΠ΅ΡΠΊΠΈ.
ΠΠ»Ρ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π° ΡΡΠΈΠ»Π΅ΠΉ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ ΡΠΎ, ΡΡΠΎ Π΄Π΅Π»Π°Π΅Ρ SwiftUI:
protocol RangeSliderStyle {
Β Β associatedtype Body: View
Β Β @ViewBuilder func makeBody(configuration: Configuration) -> Body
Β Β typealias Configuration = RangeSliderStyleConfiguration
}
Β
ΠΠΌΠ΅Ρ ΠΏΡΠΎΡΠΎΠΊΠΎΠ», ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΏΠ΅ΡΠ²ΡΠΉ ΡΡΠΈΠ»Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΈΠ· ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΡΡΠΈΠ»Ρ:
struct DefaultRangeSliderStyle: RangeSliderStyle {
Β Β func makeBody(configuration: Configuration) -> some View {
Β Β Β Β GeometryReader { proxy in
Β Β Β Β Β Β ZStack {
Β Β Β Β Β Β Β Β Capsule()
Β Β Β Β Β Β Β Β Β Β .fill(.regularMaterial)
Β Β Β Β Β Β Β Β Β Β .frame(height: 4)
Β Β Β Β Β Β Β Β Capsule()
Β Β Β Β Β Β Β Β Β Β .fill(.tint)
Β Β Β Β Β Β Β Β Β Β .frame(height: 4)
Β Β Β Β Β Β Β Β Β Β // Width and position...
Β Β Β Β Β Β Β Β Circle()
Β Β Β Β Β Β Β Β Β Β .frame(width: 27, height: 27)
Β Β Β Β Β Β Β Β Β Β // Gesture handling and positioning...
Β Β Β Β Β Β Β Β Circle()
Β Β Β Β Β Β Β Β Β Β .frame(width: 27, height: 27)
Β Β Β Β Β Β Β Β Β Β // Gesture handling and positioning...
Β Β Β Β Β Β }
Β Β Β Β }
Β Β Β Β .frame(height: 27)
Β Β }
}
Β
Π§ΡΠΎΠ±Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΡΠΈΠ»Ρ Π΄Π»Ρ ΠΈΠ΅ΡΠ°ΡΡ ΠΈΠΈ view, ΠΌΡ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ ΠΊ View, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΡΠΈΠ³Π½Π°ΡΡΡΠ΅ buttonStyle(_:), Π½ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ some, ΡΡΠΎΠ±Ρ ΡΠ΄Π΅Π»Π°ΡΡ Π΅Π³ΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΊΡΠ°ΡΠΊΠΈΠΌ:
extension View {
Β Β func rangeSliderStyle(_ style: some RangeSliderStyle) -> some View {
Β Β Β Β environment(\.rangeSliderStyle, style)
Β Β }
}
Β
ΠΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ ΡΡΠΈΠ»ΠΈ ΡΠΏΡΡΠΊΠ°ΡΡΡΡ Π²Π½ΠΈΠ· ΠΏΠΎ ΠΈΠ΅ΡΠ°ΡΡ
ΠΈΠΈ view, ΠΊΠ°ΠΊ ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡ environment. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ environment Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ ΡΡΠΈΠ»Ρ ΡΠ΅ΡΠ΅Π· ΠΈΠ΅ΡΠ°ΡΡ
ΠΈΡ view Π²ΠΎ view, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΠΎΡΠΎΡΠΌΠ»Π΅Π½ΠΎ. ΠΡΠΈ ΡΡΠΎΠΌ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠΎ ΠΆΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½Π΅Π½ΠΈΡ ΡΡΠΈΠ»Ρ, ΡΡΠΎ ΠΈ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ ΡΡΠΈΠ»ΠΈ.
Π§ΡΠΎΠ±Ρ ΠΈΠΌΠ΅ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΡ Π»ΡΠ±ΠΎΠΉ ΡΠΈΠΏ ΡΡΠΈΠ»Ρ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ Π½Π°ΡΠ΅ΠΌΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Ρ, Π² ΡΡΠ΅Π΄Ρ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΡΠΈΠΏ Π·Π½Π°ΡΠ΅Π½ΠΈΡ environment Π»ΡΠ±ΡΠΌ RangeSliderStyle.
ΠΠ»Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ environment ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. Π‘ΡΠΈΠ»ΡΠ½ΡΠ΅ view SwiftUI Π²ΡΠ΅Π³Π΄Π° ΠΈΠΌΠ΅ΡΡ ΡΡΠΈΠ»Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ Π΄Π»Ρ view Π·Π΄Π΅ΡΡ:
struct RangeSliderStyleKey: EnvironmentKey {
Β Β static var defaultValue: any RangeSliderStyle = DefaultRangeSliderStyle()
}
extension EnvironmentValues {
Β Β var rangeSliderStyle: any RangeSliderStyle {
Β Β Β Β get { self[RangeSliderStyleKey.self] }
Β Β Β Β set { self[RangeSliderStyleKey.self] = newValue }
Β Β }
}
Β
ΠΠΌΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ environment, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ body Π½Π°ΡΠ΅Π³ΠΎ view, ΡΠΎΠ·Π΄Π°Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΡΠΈΠ»Ρ Ρ Π²Ρ ΠΎΠ΄Π½ΡΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ ΠΈΠ· Π½Π°ΡΠ΅Π³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°, Π° Π·Π°ΡΠ΅ΠΌ Π²ΡΠ·Π²Π°Π² ΠΌΠ΅ΡΠΎΠ΄ makeBody Π΄Π»Ρ ΡΡΠΈΠ»Ρ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΈΠ· environment:
struct RangeSlider
Β Β // ...
Β Β @Environment(\.rangeSliderStyle) var style
Β Β var body: some View {
Β Β Β Β let configuration = RangeSliderStyleConfiguration(
Β Β Β Β Β Β range: $range,
Β Β Β Β Β Β bounds: bounds,
Β Β Β Β Β Β label: .init(label)
Β Β Β Β )
Β Β Β Β style.makeBody(configuration: configuration)
Β Β }
}
ΠΠ΄Π½Π°ΠΊΠΎ, Π΅ΡΠ»ΠΈ ΠΌΡ ΠΏΠΎΠΏΡΡΠ°Π΅ΠΌΡΡ Π·Π°ΠΏΡΡΡΠΈΡΡ ΡΡΠΎΡ ΠΊΠΎΠ΄, ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΎΡΠΈΠ±ΠΊΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ°.

Β
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ body ΠΎΠΆΠΈΠ΄Π°Π΅Ρ, ΡΡΠΎ ΠΌΡ Π²Π΅ΡΠ½ΡΠΌ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΉ ΡΠΈΠΏ view, Π° style, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΈΠ· ΡΡΠ΅Π΄Ρ, ΠΈΠΌΠ΅Π΅Ρ ΡΠΈΠΏ any RangeSliderStyle, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±Π΅ΡΠ½ΡΡΡ view, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΎΡ Π²ΡΠ·ΠΎΠ²Π° makeBody, Π² AnyView:
AnyView(style.makeBody(configuration: configuration))
Β
ΠΡΠΎ Π·Π°ΡΡΠ°Π²Π»ΡΠ΅Ρ Π΅Π³ΠΎ ΡΠ½ΠΎΠ²Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡΡΡ. Π’Π΅ΠΏΠ΅ΡΡ, ΠΊΠΎΠ³Π΄Π° Π²ΡΡ Π½Π° ΡΠ²ΠΎΠΈΡ ΠΌΠ΅ΡΡΠ°Ρ , Ρ Π½Π°Ρ Π΅ΡΡΡ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌΡΠΉ Π²ΠΈΠ΄ ΠΏΠΎΠ»Π·ΡΠ½ΠΊΠ° Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°, ΡΡΠΈΠ»Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΡΠΎΡΠΌΠ»Π΅Π½ ΡΠΈΠΏΠΎΠΌ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Ρ ΡΡΠΈΠ»Π΅ΠΉ, ΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ, ΠΊΠ°ΠΊΠΎΠΉ ΡΡΠΈΠ»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ, ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΌΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠ»ΠΈ Π±Ρ ΡΡΠΈΠ»Ρ Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ view SwiftUI:
Form {
Β Β // ...
Β Β RangeSlider(range: $sizeRange, in: minSize...maxSize) {
Β Β Β Β Text("Size Range")
Β Β }
Β Β // ...
}.rangeSliderStyle(VerticalRangeSliderStyle())

Π ΡΠΎΡΠ½ΠΎ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΌΠΈ ΡΡΠΈΠ»ΡΠΌΠΈ Π΄Π»Ρ ΡΡΠΈΠ»Π΅ΠΉ SwiftUI, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠ»Π΅Π½ Π² ΠΏΡΠΎΡΠΎΠΊΠΎΠ» ΡΡΠΈΠ»Π΅ΠΉ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΡΠΈΠ»Ρ Ρ ΡΠ΅ΠΌ ΠΆΠ΅ ΡΠΎΠΊΡΠ°ΡΡΠ½Π½ΡΠΌ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠΎΠΌ, ΡΡΠΎ ΠΈ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ ΡΡΠΈΠ»ΠΈ, Π±Π»Π°Π³ΠΎΠ΄Π°ΡΡ ΡΠ΅ΠΌΡ Π½Π°ΡΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠ΅ view ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌ view:
extension RangeSliderStyle where Self == VerticalRangeSliderStyle {
Β Β static var vertical: Self { .init() }
}
.rangeSliderStyle(.vertical)
Β
Β
ΠΠΎΡΡΡΠΏΠ½ΠΎΡΡΡ
ΠΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΡ view Π²Π°ΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΡΠ΄Π΅Π»Π°ΡΡ ΠΈΡ Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌΠΈ. ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ, Π΄ΠΎΠ±Π°Π²ΠΈΠ² ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ view, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ»ΡΡΡΠ°ΡΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ view, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Ρ VoiceOver:
struct MySlider: View {
Β Β // ...
Β Β var body: some View {
Β Β Β Β // ...
Β Β Β Β AnyView(style.makeBody(configuration: configuration))
Β Β Β Β Β Β .accessibilityElement(children: .combine)
Β Β Β Β Β Β .accessibilityValue(valueText)
Β Β Β Β Β Β .accessibilityAdjustableAction { direction in
Β Β Β Β Β Β Β Β switch direction {
Β Β Β Β Β Β Β Β case .increment: increment()
Β Β Β Β Β Β Β Β case .decrement: decrement()
Β Β Β Β Β Β Β Β @unknown default:
Β Β Β Β Β Β Β Β Β Β break
Β Β Β Β Β Β Β Β }
Β Β Β Β Β Β }
Β Β }
Β Β var valueText: Text {
Β Β Β Β if bounds == 0.0...1.0 {
Β Β Β Β Β Β Β return Text(value.wrappedValue, format: .percent)
Β Β Β Β Β } else {
Β Β Β Β Β Β Β return Text(value.wrappedValue, format: .number)
Β Β Β Β Β }
Β Β }
}
Β 
βΠΡΠΎΠΌΠΊΠΎΡΡΡ 50%, ΡΠ΅Π³ΡΠ»ΠΈΡΡΠ΅ΠΌΠ°Ρ. ΠΡΠΎΠ²Π΅Π΄ΠΈΡΠ΅ Π²Π²Π΅ΡΡ ΠΈΠ»ΠΈ Π²Π½ΠΈΠ· ΠΎΠ΄Π½ΠΈΠΌ ΠΏΠ°Π»ΡΡΠ΅ΠΌ, ΡΡΠΎΠ±Ρ ΠΎΡΡΠ΅Π³ΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅β.
- ΠΠΎΠ»ΠΎΡ Π·Π° ΠΊΠ°Π΄ΡΠΎΠΌ
ΠΠ΄Π΅ΡΡ ΠΌΡ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌ, ΡΡΠΎ Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΠΏΠΎΠ»Π·ΡΠ½ΠΊΠΎΠ² Π·Π°Ρ ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ accessibilityAdjustableAction(_:), ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΡΠΎΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π²ΠΎ view ΠΏΠΎΠ»Π·ΡΠ½ΠΊΠ°. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ, ΡΠ°Π±ΠΎΡΠ°ΡΡΠΈΠΌ Π½Π°Π΄ ΡΡΠΈΠ»ΡΠΌΠΈ, Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ Π±Π΅ΡΠΏΠΎΠΊΠΎΠΈΡΡΡΡ ΠΎ ΡΠΎΠΌ, ΡΡΠΎΠ±Ρ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΈΠ»Ρ Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ view ΡΠΆΠ΅ Π΄ΠΎΡΡΡΠΏΠ΅Π½.

Β
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Environment Π² ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠΌ ΡΡΠΈΠ»Π΅
ΠΠ»Ρ ΠΌΠ½ΠΎΠ³ΠΈΡ view Π²Π°ΠΆΠ½ΠΎ ΠΈΠΌΠ΅ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π°Π΄Π°ΠΏΡΠΈΡΠΎΠ²Π°ΡΡ ΠΈΡ ΠΊ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌ environment. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ ΠΎΡΠΊΠ»ΡΡΠ΅Π½. ΠΠ»Ρ ΡΡΡΠ΅ΠΊΡΠ° ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΊΠΈ Π΄Π»Ρ Π½Π°ΠΆΠΈΠΌΠ°Π΅ΠΌΠΎΠ³ΠΎ view ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡΡΡ Π΄ΡΡΠ³ΠΎΠΉ ΡΠ²Π΅Ρ, Π΅ΡΠ»ΠΈ ΡΠ²Π΅ΡΠΎΠ²Π°Ρ ΡΡ Π΅ΠΌΠ° ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π° Π½Π° ΡΡΠΌΠ½ΡΡ, ΠΈΠ»ΠΈ Π°Π½ΠΈΠΌΠ°ΡΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΏΡΠΈΠ΄ΡΡΡΡ ΠΏΡΠΎΠΏΡΡΡΠΈΡΡ, Π΅ΡΠ»ΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ ΡΠΌΠ΅Π½ΡΡΠ΅Π½ΠΈΡ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΡ.
Π’Π°ΠΊΠΆΠ΅ Π²Π°ΠΆΠ½ΠΎ ΠΈΠΌΠ΅ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΈΠ»Ρ ΠΎΡΡΠ΅Π½ΠΊΠ° ΠΈΠ»ΠΈ ΡΠ°Π·ΠΌΠ΅Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ, Π΅ΡΠ»ΠΈ ΠΎΠ½ ΡΠΊΠ°Π·Π°Π½.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π² ΠΏΠΎΡΠΎΠΊΠ΅ Π°Π΄Π°ΠΏΡΠ°ΡΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π±ΠΎΠ»ΡΡΠ΅, ΡΠ΅ΠΌ Π² Π΄ΡΡΠ³ΠΈΡ ΠΌΠ΅ΡΡΠ°Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡΠ»ΠΈ ΡΡΠΈΠ»ΠΈ view Π½Π°ΡΡΡΠ°ΠΈΠ²Π°ΡΡΡΡ, ΠΊΠΎΠ³Π΄Π° controlSize Π±ΠΎΠ»ΡΡΠΎΠΉ, ΠΌΡ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ environment controlSize Π΄Π»Ρ ΡΡΠΎΠΉ ΡΠ°ΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΎΠ²Π΅ΡΡΠ΅Π½Π½ΠΎ Π½ΠΎΠ²ΡΡ ΡΡΠΈΠ»Π΅ΠΉ ΠΈΠ»ΠΈ view, ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΡΡ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° Π°Π΄Π°ΠΏΡΠ°ΡΠΈΠΈ.
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ environment Π² ΡΡΠΈΠ»Π΅ Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ view SwiftUI ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠ°ΠΊ, ΠΊΠ°ΠΊ ΠΌΡ ΠΈ ΠΎΠΆΠΈΠ΄Π°Π»ΠΈ, Π½ΠΎ Π΅ΡΠ»ΠΈ ΠΌΡ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΡΠΎ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ΅ Π² ΡΡΠΈΠ»Π΅ Π΄Π»Ρ view, Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΌΡ ΡΠΎΠ·Π΄Π°Π»ΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» ΡΡΠΈΠ»Ρ, ΡΡΠΎ Π½Π΅ ΡΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π΄ΠΎΠ»ΠΆΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
struct CheckboxMultipleChoiceStyle: MultipleChoiceStyle {
Β Β @Environment(\.isEnabled) var isEnabled
Β Β func makeBody(configuration: Configuration) -> some View {
Β Β Β Β /* ... */
Β Β Β Β Β Β .saturation(isEnabled ? 1 : 0)
Β Β Β Β Β Β .brightness(isEnabled ? 0 : -0.2)
Β Β }
}
Β
MultipleChoice(selection: $extras) {
Β Β ForEach(Extra.allCases) { extra in
Β Β Β Β Text(extra.name).tag(extra)
Β Β }
}
.disabled(isOutOfStock)
.multipleChoiceStyle(.checkbox)

Β ΠΠΊΠ»ΡΡΠ΅Π½Ρ
ΠΡΠΊΠ»ΡΡΠ΅Π½Ρ, Π½ΠΎ Π²ΡΠ³Π»ΡΠ΄ΡΡ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ ΠΏΡΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΈ
Π Π°Π½ΡΡΠ΅ ΡΡΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ±ΠΈΠ²Π°Π»ΠΎ Ρ ΡΠΎΠ»ΠΊΡ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π½Π΅ Π±ΡΠ»ΠΎ ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΠΎ, ΠΏΠΎΡΠ΅ΠΌΡ ΡΡΠΎ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ. ΠΠ΄Π½Π°ΠΊΠΎ, Π½Π°ΡΠΈΠ½Π°Ρ Ρ Xcode 14.1, Π·Π°ΠΏΡΡΠΊ ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π²ΡΠ·ΠΎΠ²Π΅Ρ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ΅ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ Π²ΠΎ Π²ΡΠ΅ΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ, ΠΎΠ±ΡΡΡΠ½ΡΡΡΠ΅Π΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ:

Β
CheckboxMultipleChoiceStyle Π½Π΅ ΡΠ²Π»ΡΠ΅ΡΡΡ View, ΠΏΠΎΡΡΠΎΠΌΡ, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ environment, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠΌΠ΅ΡΡΠΈΡΡ ΡΡΠΎ Π²ΠΎ view ΠΈΠ»ΠΈ ΠΊΠ°ΠΊ-ΡΠΎ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ environment Π² ΡΡΠΈΠ»Π΅.
ΠΠ΄ΠΈΠ½ ΠΈΠ· ΡΠΏΠΎΡΠΎΠ±ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ environment ΠΈΠ· ΡΡΠΈΠ»Ρ β ΡΡΠΎ ΠΎΠ±Π΅ΡΠ½ΡΡΡ body Π½Π°ΡΠ΅Π³ΠΎ ΡΡΠΈΠ»Ρ Π² Π½ΠΎΠ²ΠΎΠ΅ view:
struct CheckboxMultipleChoice: View {
Β Β var configuration: MultipleChoiceStyleConfiguration
Β Β @Environment(\.isEnabled) var isEnabled
Β Β var body: some View {
Β Β Β Β /* ... */
Β Β Β Β Β Β .saturation(isEnabled ? 1 : 0)
Β Β Β Β Β Β .brightness(isEnabled ? 0 : -0.2)
Β Β }
}
struct CheckboxMultipleChoiceStyle: MultipleChoiceStyle {
Β Β func makeBody(configuration: Configuration) -> some View {
Β Β Β Β CheckboxMultipleChoice(configuration: configuration)
Β Β }
}
ΠΠΊΠ»ΡΡΠ΅Π½Ρ
ΠΡΠΊΠ»ΡΡΠ΅Π½Ρ
Π₯ΠΎΡΡ ΡΠ΅Ρ Π½ΠΈΠΊΠ°, ΠΎΠΏΠΈΡΠ°Π½Π½Π°Ρ Π²ΡΡΠ΅, ΡΠ°Π±ΠΎΡΠ°Π΅Ρ, ΠΊ ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡΠ½ΠΎΡΠΈΡΡΡΡ ΠΊ ΡΡΠΈΠ»ΡΠΌ Π΄Π»Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΡ view ΠΈΠ½Π°ΡΠ΅, ΡΠ΅ΠΌ ΠΊ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌ ΡΡΠΈΠ»ΡΠΌ view, ΠΈ Π½Π΅ Π·Π°Π±ΡΠ²Π°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΡ ΡΠ΅Ρ Π½ΠΈΠΊΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·, ΠΊΠΎΠ³Π΄Π° ΠΌΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΡΡΠΈΠ»Ρ Π΄Π»Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ view.
Β
Dynamic Property (Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ)
ΠΡ Π±ΡΠ»ΠΈ Π½Π΅ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΌΠΈ, ΠΊΡΠΎ ΡΠ°ΠΊ Π΄ΡΠΌΠ°Π»: Π½Π° SwiftUI Digital Lounges WWDC 2022 ΠΊΡΠΎ-ΡΠΎ ΡΠΏΡΠΎΡΠΈΠ» ΠΎΠ± ΡΡΠΎΠΌ ΠΈ ΠΏΠΎΠ»ΡΡΠΈΠ» ΠΎΡΠ²Π΅Ρ, ΡΡΠΎ SwiftUI ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΡΠ΅Π΄Ρ Π΄Π»Ρ ΡΠ»Π΅Π½ΠΎΠ², ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΡ DynamicProperty, ΠΈ Π΄Π΅Π»Π°Π΅Ρ ΡΡΠΎ ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΠΎ.
ΠΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ Π΄Π»Ρ DynamicProperty Π½Π΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠ΅ΠΉ, Π½ΠΎ ΡΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅:
βView ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΡΠΈΠΌ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌ Π΄ΠΎ ΠΏΠ΅ΡΠ΅ΡΡΡΡΠ° viewβs bodyβ.
Π’Π΅ΠΏΠ΅ΡΡ Π½Π΅ ΡΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, Π½ΠΎ ΠΏΠΎΡ ΠΎΠΆΠ΅, ΡΡΠΎ ΡΡΠΎ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΡΠ΅, ΠΊΠ°ΠΊ ΠΌΡ ΠΏΠΎΠ»Π°Π³Π°Π΅ΠΌ, Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ @State ΠΈΠ»ΠΈ @Environment.
Π’Π°ΠΊ ΠΌΠΎΠΆΠ΅ΠΌ Π»ΠΈ ΠΌΡ ΠΏΡΠΎΡΡΠΎ ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°ΡΡ Π½Π°Ρ ΡΡΠΈΠ»Ρ Ρ DynamicProperty?
protocol RangeSliderStyle: DynamicProperty {
Β Β // ...
}
Β
ΠΠΎΠΊΠ° ΡΡΠΈΠ»Ρ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π²ΠΎ view, Π° ΠΎΠ±ΠΎΠ»ΠΎΡΠΊΠ° ΡΠ²ΠΎΠΉΡΡΠ²Π° @Environment ΡΠ°ΠΊΠΆΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ DynamicProperty, ΡΡΠΎ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ.
ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΏΡΡΠ°ΡΡΡΡ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΡΡΠΈΠ»Ρ ΠΊ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠΌΡ view:
struct ResolvedRangeSliderStyle: View {
Β Β var configuration: RangeSliderStyleConfiguration
Β Β var style: any RangeSliderStyle
Β Β var body: some View {
Β Β Β Β AnyView(style.makeBody(configuration: configuration))
Β Β }
}
Β
ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ ΡΡΠΈΠ»Ρ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠΌΡ view Π² Π½Π°ΡΠ΅ΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅:
var body: some View {
Β Β let configuration = RangeSliderStyleConfiguration(range: $range, bounds: bounds, label: .init(label))
Β Β ResolvedRangeSliderStyle(configuration: configuration, style: style)
}
Β
ΠΠΎ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°Π² ΡΡΠΎ, ΠΌΡ Π²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ ΡΡΠΎ Π²ΡΡ Π΅ΡΡ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ.
Π Π½Π°ΡΠΈΡ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠ°Ρ ΠΌΡ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ»ΠΈ, ΡΡΠΎ SwiftUI ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ environment Π΄Π»Ρ ΡΡΠΈΠ»Ρ, Π΅ΡΠ»ΠΈ Ρ Π½Π°Ρ Π΅ΡΡΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΉ ΡΠΈΠΏ ΡΡΠΈΠ»Ρ Π² ΡΡΠ΅Π΄Π΅.
ΠΠΎΡΡΠΎΠΌΡ Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΡ ΠΏΠΈΡΠ΅ΠΌ ΠΎΠ±ΡΡΡΠΊΡ view, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΡΠ΅ΠΉ Π΄Π»Ρ ΡΡΠΈΠ»Ρ:
struct ResolvedRangeSliderStyle
Β Β var configuration: RangeSliderStyleConfiguration
Β Β var style: Style
Β Β var body: some View {
Β Β Β Β style.makeBody(configuration: configuration)
Β Β }
}
Β
Β ΠΡΠΎΡ ΠΏΠΎΠ»Π·ΡΠ½ΠΎΠΊ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΡΠ³Π»ΡΠ΄Π΅ΡΡ ΠΎΡΠΊΠ»ΡΡΠ΅Π½Π½ΡΠΌ.
ΠΠ΄Π½Π°ΠΊΠΎ ΡΠ΅ΠΏΠ΅ΡΡ, Π΅ΡΠ»ΠΈ ΠΌΡ ΠΏΠΎΠΏΡΡΠ°Π΅ΠΌΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΡΡΠΈΠ»Ρ ΠΈΠ· environment, ΠΌΡ ΡΡΠΎΠ»ΠΊΠ½ΡΠΌΡΡ Ρ ΡΡΠΎΠΉ ΠΎΡΠΈΠ±ΠΊΠΎΠΉ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ°:

Β
ΠΠΎΠΆΠ΅Ρ ΠΏΠΎΠΊΠ°Π·Π°ΡΡΡΡ, ΡΡΠΎ ΠΌΡ Π·Π°ΡΡΡΡΠ»ΠΈ Π·Π΄Π΅ΡΡ, Π½ΠΎ ΠΌΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ°Π΅ΠΌ ΡΡΠΎ Π² ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π° ΡΡΠΈΠ»Π΅ΠΉ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π΄Π°ΡΡ Π½Π°ΠΌ Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΌΡ ΡΠΈΠΏΡ ΡΠ΅ΡΠ΅Π· self:
extension RangeSliderStyle {
Β Β func resolve(configuration: Configuration) -> some View {
Β Β Β Β ResolvedRangeSliderStyle(configuration: configuration, style: self)
Β Β }
}
Β
ΠΠ΅ΡΠ½ΡΠ²ΡΠΈΡΡ Π² body Π½Π°ΡΠ΅Π³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°, ΠΌΡ ΡΠ΅ΠΏΠ΅ΡΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ Π²ΡΠ·Π²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ resolve Π΄Π»Ρ ΡΡΠΈΠ»Ρ:
var body: some View {
Β Β let configuration = RangeSliderStyleConfiguration(range: $range, bounds: bounds, label: .init(label))
Β Β AnyView(style.resolve(configuration: configuration))
}
Β
ΠΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΡΠΉ Π²ΡΡΠ΅ ΠΊΠΎΠ΄ ΡΠ½ΠΎΠ²Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅ΡΡΡ. Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡ ΡΡΠΈΠ»Ρ DynamicProperty ΠΈ ΠΏΠΎΠΌΠ΅ΡΠ°Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΉ ΡΡΠΈΠ»Ρ Π² ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠ΅ view Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠ° Π² ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π΅ ΡΡΠΈΠ»Ρ, ΡΡΠΈΠ»ΠΈ ΡΠ΅ΠΏΠ΅ΡΡ ΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ @Environment ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΠΎΠ±ΡΡΡΠΊΠΈ ΡΠ²ΠΎΠΉΡΡΠ², ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ DynamicProperty, Π±Π΅Π· Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ±Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡΡΠΈΠ»Π΅.

ΠΡΠΎΡ ΠΏΠΎΠ»Π·ΡΠ½ΠΎΠΊ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°, Π½Π°ΠΊΠΎΠ½Π΅Ρ, Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΎΡΠΊΠ»ΡΡΠ΅Π½Π½ΡΠΌ.
Β
Style Propagation
ΠΠ΄Π½ΠΈΠΌ ΠΈΠ· ΠΏΡΠ΅ΠΈΠΌΡΡΠ΅ΡΡΠ² ΡΡΠΈΠ»ΡΠ½ΡΡ view ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎ, ΡΡΠΎ Π½Π°ΠΌ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π·Π°Π΄Π°Π²Π°ΡΡ ΡΡΠΈΠ»Ρ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ view Π² Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΡΠΈΠ»Ρ Π²ΠΎ view ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° Π΄Π»Ρ ΡΠΊΡΠ°Π½Π° ΠΈΠ»ΠΈ Π² ΠΊΠΎΡΠ½Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΡΡΠΈΠ»Ρ Π²ΠΎ Π²ΡΠ΅ΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ:
WindowGroup {
Β Β ContentView()
Β Β Β Β .buttonStyle(.borderedProminent)
Β Β Β Β .toggleStyle(.checkbox)
Β Β Β Β .rangeSliderStyle(.rounded)
Β Β Β Β // ...
}
Β
Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, Π² Π½Π΅ΠΊΠΎΡΠΎΡΡΡ ΡΠ»ΡΡΠ°ΡΡ ΡΡΠΈΠ»ΠΈ Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ view SwiftUI, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ButtonStyle ΠΈ ToggleStyle, Π½Π΅ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΡΡΡΡ Π½Π° view, ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΠΌΡΠ΅ Π² ΠΌΠΎΠ΄Π°Π»ΡΠ½ΠΎΠΉ ΠΏΡΠ΅Π·Π΅Π½ΡΠ°ΡΠΈΠΈ.
Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π΅ΡΠ»ΠΈ ΠΌΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅ΠΌ view Π² ΠΌΠΎΠ΄Π°Π»ΡΠ½ΠΎΠΉ ΠΏΡΠ΅Π·Π΅Π½ΡΠ°ΡΠΈΠΈ, ΡΠ°ΠΊΠΎΠΉ ΠΊΠ°ΠΊ sheet, fullscreenCover ΠΈΠ»ΠΈ popover, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΠ±ΡΠΎΡΠΈΡΡ ΡΡΠΈΠ»ΠΈ Π² ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π½ΠΎΠΌ view, Π΅ΡΠ»ΠΈ ΠΌΡ Ρ ΠΎΡΠΈΠΌ, ΡΡΠΎΠ±Ρ ΡΡΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈΡΡ ΠΈ ΡΠ°ΠΌ.
ΠΡΠ±ΠΎΠΏΡΡΠ½ΠΎ, ΡΡΠΎ ΡΡΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΠΊΠΎΠ½ΡΠ΅Π½ΡΡ Π²ΠΎ Π²ΡΠΏΠ»ΡΠ²Π°ΡΡΠΈΡ ΠΎΠΊΠ½Π°Ρ , Π΅ΡΠ»ΠΈ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π²Π½ΡΡΡΠΈ NavigationStack, Π° Π΅ΡΠ»ΠΈ Ρ Π½Π°Ρ Π΅ΡΡΡ NavigationStack Π²Π½ΡΡΡΠΈ TabView, ΡΡΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ Π²ΡΠ΅ΠΌ ΡΠΈΠΏΠ°ΠΌ ΠΌΠΎΠ΄Π°Π»ΡΠ½ΡΡ ΠΏΡΠ΅Π·Π΅Π½ΡΠ°ΡΠΈΠΉ.
ΠΠ°ΠΌΠ΅ΡΠΊΠ°Β
ΠΠ½Π°ΡΠ΅Π½ΠΈΡ environment ΡΠ°ΠΊΠΆΠ΅ Π½Π΅ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΡΡΡΡ Π½Π° view Π² ΠΌΠΎΠ΄Π°Π»ΡΠ½ΡΡ ΠΏΡΠ΅Π·Π΅Π½ΡΠ°ΡΠΈΡΡ Π² iOS 13 ΠΈ ΡΠ΄Π°Π»ΡΡΡΡΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΈΠ½ΡΠ΅ΡΠ°ΠΊΡΠΈΠ²Π½ΠΎΠ³ΠΎ Π·Π°ΠΊΡΡΡΠΈΡ Π² iOS 14.
ΠΡΠ΄Π΅ΠΌ Π½Π°Π΄Π΅ΡΡΡΡΡ, ΡΡΠΎ ΡΡΠΎ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½ΠΎ Π² Π±ΡΠ΄ΡΡΠΈΡ Π²Π΅ΡΡΠΈΡΡ SwiftUI, Π½ΠΎ ΠΏΠΎΠΊΠ° Π΅ΡΡΡ ΡΠΏΠΎΡΠΎΠ± Π·Π°ΡΡΠ°Π²ΠΈΡΡ ΡΡΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ.
ΠΡΠ»ΠΈ ΠΌΡ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡΠ°Π½ΡΡΠ΅ΠΌ Ρ UIKit, ΠΎΠ±Π΅ΡΠ½ΡΠ² view Ρ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ sheet Π² UIViewControllerRepresentable, ΠΊΠΎΡΠΎΡΡΠΉ, Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ UIHostingController Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΡΠΎΠ³ΠΎ view, ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΠΈΡΡ sheets ΠΈ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΠΈΡΡ ΡΡΠΈΠ»ΠΈ:
struct UIKitDanceView
Β Β var content: Content
Β Β init(@ViewBuilder content: @escaping () -> Content) {
Β Β Β Β self.content = content()
Β Β }
Β Β func makeUIViewController(context: Context) -> UIHostingController
Β Β Β Β return UIHostingController(rootView: content)
Β Β }
Β Β func updateUIViewController(_ uiViewController: UIHostingController
Β Β }
}
Β
extension View {
Β Β func preserveStylesInSheets() -> some View {
Β Β Β Β UIKitDanceView {
Β Β Β Β Β Β Self
Β Β Β Β }
Β Β }
}
Β
ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ Π²ΡΠ΅ Π½Π°ΡΠΈ ΡΡΠΈΠ»ΠΈ Π² ΠΊΠΎΡΠ½Π΅ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ preserveStylesInSheets(), ΡΡΠΎΠ±Ρ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ ΡΡΠΈ ΡΡΠΈΠ»ΠΈ ΡΠ°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π² Π»ΡΠ±ΡΡ ΠΌΠΎΠ΄Π°Π»ΡΠ½ΡΡ ΠΏΡΠ΅Π·Π΅Π½ΡΠ°ΡΠΈΡΡ .
ΠΠ°ΠΌΠ΅ΡΠΊΠ°Β
ΠΡΠΎΡ ΡΡΡΠΊ Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π² iOS 13, Π½ΠΎ ΡΠ°ΠΌ Π½Π°ΠΌ ΡΠ°ΠΊΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΡΠΈΡΡΠ²Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ environment, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΡΡΡΡ Π½Π° view Π² ΠΌΠΎΠ΄Π°Π»ΡΠ½ΡΡ ΠΏΡΠ΅Π·Π΅Π½ΡΠ°ΡΠΈΡΡ .
WindowGroup {
Β Β ContentView()
Β Β Β Β .preserveStylesInSheets()
Β Β Β Β .buttonStyle(.borderedProminent)
Β Β Β Β .toggleStyle(.checkbox)
Β Β Β Β .rangeSliderStyle(.rounded)
Β Β Β Β // ...
}

Β
Β
ΠΠΎΠ΄Π²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΈΡΠΎΠ³ΠΎΠ²
Π‘ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΡΠΎΠ·Π΄Π°Π½Π½ΡΠΌ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΡΠΈΠ»Π΅Π²ΡΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΡΠΈΡΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ ΡΡΠΈΠ»Ρ ΠΈΠ· Π½Π°ΡΠΈΡ view Π² ΡΡΠΈΠ»ΠΈ ΠΈ ΠΈΠΌΠ΅ΡΡ ΡΡΡΠΊΠΎΠ΅ ΡΠ°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠΈΠ»Π΅ΠΌ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ view ΡΡΠ°Π½ΠΎΠ²ΡΡΡΡ Π±ΠΎΠ»Π΅Π΅ Π»Π°ΠΊΠΎΠ½ΠΈΡΠ½ΡΠΌΠΈ ΠΈ ΠΏΡΠΎΡΡΡΠΌΠΈ Π² ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π½ΠΈΠΈ, ΠΈ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΡΠΎ ΡΡΠΈΠ»Π΅ΠΌ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ Π½Π΅ ΡΠ°ΠΊ ΡΠΈΠ»ΡΠ½ΠΎ ΠΏΠ΅ΡΠ΅ΠΏΠ»Π΅ΡΠ°Π΅ΡΡΡ Ρ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡΡ:
@main
struct MyApp: App {
Β Β var body: some Scene {
Β Β Β Β WindowGroup {
Β Β Β Β Β Β ContentView()
Β Β Β Β Β Β Β Β .theme(.springSummer2023)
Β Β Β Β }
Β Β }
}
Π Π°Π·ΠΌΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Ρ
Π½Π°ΡΠΈΡ
ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠ² ΡΡΠΈΠ»Ρ view Π² ΡΠ΄ΠΎΠ±Π½ΠΎΠΉ theme(_:), ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ ΡΡΠΎΠΌΡ, ΡΠ°ΠΊΠΆΠ΅ ΡΠ΄ΠΎΠ±Π½ΠΎ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΡ
ΠΏΡΠΎΡΠΌΠΎΡΡΠΎΠ² Xcode Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΡΠΊΡΠ°Π½ΠΎΠΌ ΠΈΠ»ΠΈ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ.
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΠΈΡΠ°ΡΡ view, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΡΠΈΠ»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, ΠΈΠΌΠ΅Π΅Ρ ΡΠ΅ΡΠ°ΡΡΠ΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ ΡΠΈΡΡΠ΅ΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² ΠΌΠ°ΡΡΡΠ°Π±Π΅, ΠΈ ΠΌΡ Π½Π°Π΄Π΅Π΅ΠΌΡΡ, ΡΡΠΎ Apple Π² Π±ΡΠ΄ΡΡΠ΅ΠΌ ΡΠ΄Π΅Π»Π°Π΅Ρ Π±ΠΎΠ»ΡΡΠ΅ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ view SwiftUI ΡΡΠΈΠ»ΠΈΠ·ΡΠ΅ΠΌΡΠΌΠΈ.
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ ΡΡΠΎ ΡΠ°ΠΌΠΈ, Π·Π°Π³ΡΡΠ·ΠΈΠ² ΡΡΡ Β Xcode Playground Π½Π° Π½Π°ΡΠ΅ΠΉ ΡΡΡΠ°Π½ΠΈΡΠ΅ GitHub, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΈΠΌΠ΅Π΅Ρ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌΠΎΠ΅ view Ρ API ΡΡΠΈΠ»Π΅ΠΉ.
Π ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΠΏΠΎΡΡΠ΅ ΠΌΡ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΡ
Π²Π°ΡΠΈΠ°Π½ΡΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ. ΠΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ ΡΠ»Π΅Π΄ΠΈΡΡ Π·Π° Π½Π°ΡΠ΅ΠΉ ΡΠ°Π±ΠΎΡΠΎΠΉ ΠΈ Π±ΡΡΡ Π² ΠΊΡΡΡΠ΅ Π±ΡΠ΄ΡΡΠΈΡ
ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΉ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΡ
ΡΡΠΎΠΉ, ΡΠ°ΡΡΠΌΠΎΡΡΠΈΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°ΡΡΡΡ Π½Π° Π½Π°Ρ Π² Mastodon ΠΈΠ»ΠΈ Twitter ΠΈΠ»ΠΈ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡΡΡΡ ΠΊ Π½Π°ΡΠ΅ΠΌΡ ΡΠΏΠΈΡΠΊΡ ΡΠ°ΡΡΡΠ»ΠΊΠΈ.
Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ Chris Eidhof ΠΈ Eric Horacek Π·Π° ΠΎΡΠ·ΡΠ²Ρ ΠΎ ΡΠ΅ΡΠ½ΠΎΠ²ΠΈΠΊΠ΅ ΡΡΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ° ΠΈ Natalye Childress Π·Π° ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ°.
Β