如何知道在SwiftUI中选择了哪个按钮?

oknwwptz  于 2023-02-21  发布在  Swift
关注(0)|答案(2)|浏览(111)

我想创建3个按钮。当我按下一个按钮时,我想用x按钮展开它。但是没有这样做,什么也没有发生。我做错了什么?我将粘贴下面的代码。
这是我创建的可重复使用的按钮。

struct RCHChipView: View {
    var rchChip: RCHChip
    var action: () -> Void

    init(
        rchChip: RCHChip,
         action: @escaping () -> Void) {
        self.rchChip = rchChip
        self.action = action
    }

    var body: some View {
        HStack(spacing: 0) {
            Button {
                action()
            } label: {
                Text(rchChip.title)
            }
            if rchChip.isSelected {
                Button {
                    rchChip.isSelected = false
                } label: {
                        Image("NavigationCloseIcon")
                            .resizable()
                }
            }
        }
    }
}

struct RCHChip: Identifiable {
    var id: String
    var title: String
    @Binding var isSelected: Bool
    init(id: String = UUID().uuidString, title: String, isSelected: Binding<Bool> = .constant(false)) {
        self.id = id
        self.title = title
        self._isSelected = isSelected
    }
}

在这里,我将向您展示如何尝试显示按钮。

@State private var rchChip: [RCHChip] = [RCHChip(title: "Datum"), RCHChip(title: "Person")]
                        HStack {
                            ForEach(rchChip) { chip in
                                RCHChipView(rchChip: rchChip.first(where: {$0.id == chip.id}) ?? RCHChip(id: "", title: "", isSelected: .constant(false))) {
                                    chip.isSelected = true
                                }
                            }
                        }

我该如何解决这个问题?

2uluyalo

2uluyalo1#

你的代码很奇怪,我不是很理解,但这里有一个解决方案,似乎工作
首先,您不能在视图之外使用@Binding,因此我将结构体更改为

struct RCHChip: Identifiable {
    var id: String
    var title: String
    var isSelected: Bool
    init(id: String = UUID().uuidString, title: String, isSelected: Bool = false) {
        self.id = id
        self.title = title
        self.isSelected = isSelected
    }
}

RCHChipView中,我发现action的定义很奇怪,因为它既不接受任何输入,也不返回任何结果。

var action: (RCHChip) -> RCHChip

为了能够从视图外部修改视图属性,它需要是@Bindning,因此我将rchChip更改为

@Binding var rchChip: RCHChip

action属性的执行随后更改为

Button {
    self.rchChip = action(rchChip)
}

对于调用视图,我使用了以下代码

@State private var rchChips: [RCHChip] = [RCHChip(title: "Datum"), RCHChip(title: "Person")]

var body: some View {
    HStack {
        ForEach($rchChips) { chip in
            RCHChipView(rchChip: chip, action: { chip in
                var copy = chip
                copy.isSelected = true
                return copy
            })
        }
    }
}

我相信这是可以改进的,但与您当前的解决方案相比,它应该是向前迈出的一步,而且它确实可以编译和运行:)

w8rqjzmb

w8rqjzmb2#

我认为这与Binding变量的行为有关。
试试看:

struct RCHChipView: View {
    var rchChip: RCHChip
    var action: () -> Void

    init(
        rchChip: RCHChip,
         action: @escaping () -> Void) {
        self.rchChip = rchChip
        self.action = action
    }

    var body: some View {
        HStack(spacing: 0) {
            Button {
                action()
            } label: {
                Text(rchChip.title)
            }
            if rchChip.isSelected {
                Button {
                    rchChip.isSelected.wrappedValue = false
                } label: {
                        Image("NavigationCloseIcon")
                            .resizable()
                }
            }
        }
    }
}

唯一的区别是使用.wrappedValue作为Binding变量。下面是对ForEach的一个细微更改:

ForEach($rchChip) { $chip in
    RCHChipView(
        rchChip: chip,
        action: { $chip.wrappedValue.isSelected = true }
    )
}

$是您引用Binding变量的方式。

相关问题