SwiftUI实现在子视图中改变父视图的背景色
Tue Feb 07 2023 12:09:14 GMT+0000 (Coordinated Universal Time)
Saved by @zelda #swift #swiftui
//
// SelectBackgroundColorView.swift
// ApiBox
//
// Created by shiyanjun on 2023/2/6.
//
import SwiftUI
// 视图模型类
class SelectColorViewModel: ObservableObject {
// 记录当前用户选中的颜色,默认值白色
@Published var selectColor: Color = .white
}
struct SelectBackgroundColorView: View {
// 是否显示滑窗,默认不显示
@State var showSheet: Bool = false
// 注入视图模型实例
@EnvironmentObject var vm: SelectColorViewModel
var body: some View {
ZStack {
// 用户设置的背景色
vm.selectColor
VStack {
Spacer()
Button {
// 点击按钮展示滑窗让用户选择颜色
showSheet.toggle()
} label: {
Text("设置背景色")
.frame(maxWidth: .infinity)
.frame(height: 45)
.foregroundColor(.white)
.background(.black)
.cornerRadius(10)
}
.sheet(isPresented: $showSheet) {
SheetView()
}
Spacer()
}
.padding()
}
.edgesIgnoringSafeArea(.all)
}
}
// 底部滑窗
struct SheetView: View {
// 注入视图模型实例
@EnvironmentObject var vm: SelectColorViewModel
// 用于关闭滑窗
@Environment(\.presentationMode) private var presentationMode
// 可供用户选择的颜色数组
private let colors: [Color] = [.red, .green, .blue, .purple, .orange, .pink, .brown, .cyan, .teal]
var body: some View {
VStack {
Text("请选择一种颜色")
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.frame(height: 100)
HStack {
// 循环展示所有颜色供用户选择
ForEach(colors, id: \.self) { color in
Button {
// 记住用户选中的颜色
vm.selectColor = color
// 关闭滑窗
presentationMode.wrappedValue.dismiss()
} label: {
Circle()
.frame(width: 30, height: 30)
.foregroundColor(color)
.overlay {
Circle()
// 用描边标识用户选中了该颜色
.stroke(.white, lineWidth: vm.selectColor == color ? 1 : 0)
// 用放大效果突出用户选的颜色
.scaleEffect(vm.selectColor == color ? 1.2 : 1)
}
}
}
}
Spacer()
}
.background(.black)
}
}
struct SelectBackgroundColorView_Previews: PreviewProvider {
static var previews: some View {
SelectBackgroundColorView()
.environmentObject(SelectColorViewModel())
}
}



Comments