SwiftUI中的状态变量未更新
我有structSwiftUI中的状态变量未更新,swift,swiftui,Swift,Swiftui,我有structDBScrollViewCellWrapper。那个显示器包含 struct DBScrollViewCellWrapper: View, Identifiable, Equatable { let id = UUID().uuidString let view: AnyView @State var showSelectionLine: Bool = false var body: some View { VStack(spacing: 0){ vi
DBScrollViewCellWrapper
。那个显示器包含
struct DBScrollViewCellWrapper: View, Identifiable, Equatable {
let id = UUID().uuidString
let view: AnyView
@State var showSelectionLine: Bool = false
var body: some View {
VStack(spacing: 0){
view
if self.showSelectionLine{
Rectangle()
.frame(width: 10, height: 1)
.foregroundColor(.red)
}
}
}
static func == (lhs: DBScrollViewCellWrapper, rhs: DBScrollViewCellWrapper) -> Bool { lhs.id == rhs.id }
}
然后生成DBScrollViewCellWrapper
单元格的数量。轻触单元格时,显示用线条选择的轻触单元格
struct DBScrollView: View {
let views: [DBScrollViewCellWrapper]
var showsIndicators = false
var completion:(DBScrollViewCellWrapper,Int)->Void = {x,index in}
var isHorizontal: Bool = false
var leadingSpacing: CGFloat = 0
var trailingSpacing: CGFloat = 0
var itemSpacing: CGFloat = 5
var isFixSize: Bool = false
var fixWidth: CGFloat = .infinity
var fixHeight: CGFloat = .infinity
@State var showSelectionLine: Bool = false
@State private var previousItem : DBScrollViewCellWrapper?
init(views: [DBScrollViewCellWrapper],
showsIndicators: Bool = false,
isHorizontal: Bool = false,
leadingSpacing: CGFloat = 0,
trailingSpacing: CGFloat = 0,
itemSpacing: CGFloat = 5,
isFixSize: Bool = false,
fixWidth: CGFloat = .infinity,
fixHeight: CGFloat = .infinity,
completion: @escaping (DBScrollViewCellWrapper,Int)->Void = {val,index in}) {
self.views = views.map { $0 } //DBScrollViewCellWrapper(view: $0)
self.showsIndicators = showsIndicators
self.completion = completion
self.isHorizontal = isHorizontal
self.leadingSpacing = leadingSpacing
self.trailingSpacing = trailingSpacing
self.itemSpacing = itemSpacing
self.isFixSize = isFixSize
self.fixWidth = fixWidth
self.fixHeight = fixHeight
}
var body: some View {
GeometryReader(content: { geometry in
ScrollView(isHorizontal ? .horizontal : .vertical, showsIndicators: showsIndicators, content: {
self.generateViews(in: geometry)
})
.padding(.leading, self.leadingSpacing)
.padding(.trailing, self.trailingSpacing)
})
}
private func generateViews(in geometry: GeometryProxy) -> some View{
return ZStack{
if isHorizontal{
HStack(spacing: itemSpacing){
ForEach(self.views) { item in
item
.padding(5)
.border(Color.black)
.onTapGesture(count: 1, perform: {
self.tapped(value: item)
})
}
Spacer()
}
}else{
VStack(spacing: itemSpacing){
ForEach(self.views, id: \.id) { item in
item
.padding(5)
.border(Color.clear)
.onTapGesture(count: 1, perform: {
self.tapped(value: item)
})
}
Spacer()
}
}
}
}
func tapped(value: DBScrollViewCellWrapper) {
guard let index = views.firstIndex(of: value) else { assert(false, "This should never happen"); return }
value.showSelectionLine = true
completion(value,index)
}
}
预览代码:
struct DBScrollView_Previews: PreviewProvider {
static var previews: some View {
let arr = Array(0...100)
let arrView = arr.map{DBScrollViewCellWrapper(view: AnyView(Text("\($0)")))}
DBScrollView(views: arrView, isHorizontal: false) { (cell, inx) in
cell.showSelectionLine = true
}
}
}
问题
点击单元格时,更改了单元格的值,但该值不会更新。重新设计了选择代码
struct DBScrollView: View {
private let views: [DBScrollViewCellWrapper]
var showsIndicators = false
var completion:(DBScrollViewCellWrapper,Int)->Void = {x,index in}
var isHorizontal: Bool = false
var leadingSpacing: CGFloat = 0
var trailingSpacing: CGFloat = 0
var itemSpacing: CGFloat = 5
var isFixSize: Bool = false
var fixWidth: CGFloat = .infinity
var fixHeight: CGFloat = .infinity
@State var selectedIndex: Int = -1
@State var showSelectionLine: Bool = false
@State private var previousItem : DBScrollViewCellWrapper?
init(views: [AnyView],
showsIndicators: Bool = false,
isHorizontal: Bool = false,
leadingSpacing: CGFloat = 0,
trailingSpacing: CGFloat = 0,
itemSpacing: CGFloat = 5,
isFixSize: Bool = false,
fixWidth: CGFloat = .infinity,
fixHeight: CGFloat = .infinity,
completion: @escaping (DBScrollViewCellWrapper,Int)->Void = {val,index in}) {
self.views = views.map { DBScrollViewCellWrapper(view: AnyView($0))}
self.showsIndicators = showsIndicators
self.completion = completion
self.isHorizontal = isHorizontal
self.leadingSpacing = leadingSpacing
self.trailingSpacing = trailingSpacing
self.itemSpacing = itemSpacing
self.isFixSize = isFixSize
self.fixWidth = fixWidth
self.fixHeight = fixHeight
}
var body: some View {
GeometryReader(content: { geometry in
ScrollView(isHorizontal ? .horizontal : .vertical, showsIndicators: showsIndicators, content: {
self.generateViews(in: geometry)
})
.padding(.leading, self.leadingSpacing)
.padding(.trailing, self.trailingSpacing)
})
}
private func generateViews(in geometry: GeometryProxy) -> some View{
return ZStack{
if isHorizontal{
HStack(alignment: .center, spacing: itemSpacing){
ForEach(self.views.indices, id:\.self) { index in
let item = self.views[index]
VStack(spacing: 0){
item.view
.foregroundColor(self.selectedIndex == index ? Color.yellow : Color.white)
.padding(5)
.onTapGesture(count: 1, perform: {
self.selectedIndex = index
self.tapped(value: item)
})
Rectangle()
.frame(width: self.selectedIndex == index ? 10 : 0, height: 1, alignment: .center)
.foregroundColor(Color.yellow)
}
}
Spacer()
}
}else{
VStack(spacing: itemSpacing){
ForEach(self.views.indices, id: \.self) { index in
let item = self.views[index]
VStack(spacing: 0){
item.view
.padding(5)
.border(Color.white)
.onTapGesture(count: 1, perform: {
self.selectedIndex = index
self.tapped(value: item)
})
Rectangle()
.frame(width: self.selectedIndex == index ? 10 : 0, height: 1, alignment: .center)
.foregroundColor(Color.yellow)
}
}
Spacer()
}
}
}
}
func tapped(value: DBScrollViewCellWrapper) {
guard let index = views.firstIndex(of: value) else { assert(false, "This should never happen"); return }
completion(value,index)
}
}
struct DBScrollViewCellWrapper: Identifiable, Equatable {
let id = UUID().uuidString
let view: AnyView
static func == (lhs: DBScrollViewCellWrapper, rhs: DBScrollViewCellWrapper) -> Bool { lhs.id == rhs.id } } struct DBScrollView_Previews: PreviewProvider {
static var previews: some View {
let arr = Array(0...100)
let arrView = arr.map{AnyView(Text("\($0)"))}
DBScrollView(views: arrView, isHorizontal: true) { (cell, inx) in
}
.background(Color.black)
}
}
可以更改视图的堆栈副本,但不能更改视图层次结构中的视图。重新阅读SwiftUI状态和数据流。大部分代码应该重新设计。如何选择单元格?请帮助@Asperi