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

huangapple go评论61阅读模式
英文:

How to know which button is selected in SwiftUI?

问题

这是您的翻译内容:

"I want to create 3 buttons. When I press on one button, I want that to be expand it with the x button. But instead of that, nothing happens. What am I doing wrong ? I will paste the code below.

This is the reutilizabile button I've created."

"我想创建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
    }
}

"Here, I will show you how I'm trying to display the buttons."

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

@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
        }
    }
}

"How can I solve this issue?"

"我该如何解决这个问题?"

英文:

I want to create 3 buttons. When I press on one button, I want that to be expand it with the x button. But instead of that, nothing happens. What am I doing wrong ? I will paste the code below.

This is the reutilizabile button I've created.

struct RCHChipView: View {
    var rchChip: RCHChip
    var action: () -&gt; Void

    init(
        rchChip: RCHChip,
         action: @escaping () -&gt; 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(&quot;NavigationCloseIcon&quot;)
                            .resizable()
                }
            }
        }
    }
}

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

Here, I will show you how I'm trying to display the buttons.

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

How can I solve this issue ?

答案1

得分: 1

你的代码有点奇怪,我并不完全理解它,但这里有一个看起来能够运行的解决方案:

首先,你不能在视图之外使用 @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

为了能够从视图之外修改视图属性,它需要是一个 @Binding,所以我将 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
            })
        }
    }
}

我相信这个解决方案还有改进的空间,但与你当前的解决方案相比,它应该是一个进步,并且可以编译和运行。 如何在SwiftUI中知道哪个按钮被选中?

英文:

Your code is quite strange and I didn't really understand all of it but here is a solution that seems to work

First of all, you cannot use @Binding outside a View so I changed the struct to

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
    }
}

In the RCHChipView I found the definition of action strange since it didn't take any input nor returned anything. I changed it to the have the following signature

var action: (RCHChip) -&gt; RCHChip

and to be able to modify a view property from outside of the view it needs to be a @Bindning so I changed rchChip to

@Binding var rchChip: RCHChip

the execution of the action property was then changed to

Button {
    self.rchChip = action(rchChip)
}

And for the calling view I used the following code

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

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

I am sure this can be improved upon but it should be a step forward compared to your current solution and it does compile and run 如何在SwiftUI中知道哪个按钮被选中?

答案2

得分: 0

我认为这与“绑定”变量的行为有关。

尝试:

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()
                }
            }
        }
    }
}

唯一的区别是对ForEach进行了轻微更改:

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

$符号是用来表示“绑定”变量的方式。

英文:

I think this is to do with the behaviour of Binding variables.

Try:

struct RCHChipView: View {
    var rchChip: RCHChip
    var action: () -&gt; Void

    init(
        rchChip: RCHChip,
         action: @escaping () -&gt; 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(&quot;NavigationCloseIcon&quot;)
                            .resizable()
                }
            }
        }
    }
}

The only difference being using the .wrappedValue for the Binding variable. Here's a slight change to the ForEach:

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

$ is how you refer to Binding variables.

huangapple
  • 本文由 发表于 2023年2月14日 22:36:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75449364.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定