Swift 自定义切换样式冻结 UI
Swift custom toggle style freezes UI
我想创建一个包含复选框列表的视图,我可以独立 select 并在数组中跟踪这些更改。我已经实现了一些代码来尝试实现这一点,但是我遇到了奇怪的行为,因为这段代码导致屏幕冻结。我对 SwiftUI 和反应式编程还是个新手,所以我不确定我是否误用了反应式组件。
当 select 选中复选框时,屏幕冻结,从那以后我无法点击屏幕上的任何内容。
实体
class Entity: Identifiable, Codable, Equatable {
var id = UUID()
let name: String
var enabled: Bool
init(name: String, enabled: Bool) {
self.name = name
self.enabled = enabled
}
static func == (lhs: Entity, rhs: Entity) -> Bool {
lhs.id == rhs.id
}
}
MyToggleStyle1
struct MyToggleStyle1: ToggleStyle {
func makeBody(configuration: Configuration) -> some View {
return HStack {
configuration.label
Image(systemName: configuration.isOn ? "checkmark.square" : "square")
.resizable()
.foregroundColor(configuration.isOn ? .green : .red)
.frame(width: 22, height: 22)
.onTapGesture { configuration.isOn.toggle() }
}
}
}
EntitySelectorView
struct EntitySelectorView: View {
@State var customArray: [Entity] = [Entity(name: "All entities", enabled: false),
Entity(name: "Boston Merchandising", enabled: false),
Entity(name: "Canns & Co", enabled: false),
Entity(name: "Sterling Auto Spares", enabled: false),
Entity(name: "Compendia Bioscience Life Technologies", enabled: true),
Entity(name: "Boston Consulting Group", enabled: false)]
var body: some View {
VStack(spacing: 0) {
ScrollView(.vertical, showsIndicators: false) {
VStack{
ForEach($customArray) { $entity in
HStack {
Toggle(isOn: $entity.enabled) {
Text(entity.name)
.foregroundColor(Colors.darkTextColor.color)
.font(.system(size: 16, weight: entity.name == "All entities" ? .bold : .regular, design: .default))
}
.toggleStyle(MyToggleStyle1())
Spacer()
}.padding(.top, 12)
}
Spacer()
}
}
Spacer()
}.padding()
}
}
关于模型:1st - 它必须是值,2nd - equatable 应该取决于任何更改 属性。
这里是固定部分。使用 Xcode 13.2 / iOS 15.2
测试
struct Entity: Identifiable, Codable, Equatable { // << here !!
var id = UUID()
let name: String
var enabled: Bool
init(name: String, enabled: Bool) {
self.name = name
self.enabled = enabled
}
static func == (lhs: Entity, rhs: Entity) -> Bool {
lhs.id == rhs.id && lhs.enabled == rhs.enabled // << here !!
}
}
我想创建一个包含复选框列表的视图,我可以独立 select 并在数组中跟踪这些更改。我已经实现了一些代码来尝试实现这一点,但是我遇到了奇怪的行为,因为这段代码导致屏幕冻结。我对 SwiftUI 和反应式编程还是个新手,所以我不确定我是否误用了反应式组件。
当 select 选中复选框时,屏幕冻结,从那以后我无法点击屏幕上的任何内容。
实体
class Entity: Identifiable, Codable, Equatable {
var id = UUID()
let name: String
var enabled: Bool
init(name: String, enabled: Bool) {
self.name = name
self.enabled = enabled
}
static func == (lhs: Entity, rhs: Entity) -> Bool {
lhs.id == rhs.id
}
}
MyToggleStyle1
struct MyToggleStyle1: ToggleStyle {
func makeBody(configuration: Configuration) -> some View {
return HStack {
configuration.label
Image(systemName: configuration.isOn ? "checkmark.square" : "square")
.resizable()
.foregroundColor(configuration.isOn ? .green : .red)
.frame(width: 22, height: 22)
.onTapGesture { configuration.isOn.toggle() }
}
}
}
EntitySelectorView
struct EntitySelectorView: View {
@State var customArray: [Entity] = [Entity(name: "All entities", enabled: false),
Entity(name: "Boston Merchandising", enabled: false),
Entity(name: "Canns & Co", enabled: false),
Entity(name: "Sterling Auto Spares", enabled: false),
Entity(name: "Compendia Bioscience Life Technologies", enabled: true),
Entity(name: "Boston Consulting Group", enabled: false)]
var body: some View {
VStack(spacing: 0) {
ScrollView(.vertical, showsIndicators: false) {
VStack{
ForEach($customArray) { $entity in
HStack {
Toggle(isOn: $entity.enabled) {
Text(entity.name)
.foregroundColor(Colors.darkTextColor.color)
.font(.system(size: 16, weight: entity.name == "All entities" ? .bold : .regular, design: .default))
}
.toggleStyle(MyToggleStyle1())
Spacer()
}.padding(.top, 12)
}
Spacer()
}
}
Spacer()
}.padding()
}
}
关于模型:1st - 它必须是值,2nd - equatable 应该取决于任何更改 属性。
这里是固定部分。使用 Xcode 13.2 / iOS 15.2
测试struct Entity: Identifiable, Codable, Equatable { // << here !!
var id = UUID()
let name: String
var enabled: Bool
init(name: String, enabled: Bool) {
self.name = name
self.enabled = enabled
}
static func == (lhs: Entity, rhs: Entity) -> Bool {
lhs.id == rhs.id && lhs.enabled == rhs.enabled // << here !!
}
}