SwiftUI按钮选择

时间:2019-08-22 22:33:21

标签: swift button uibutton swiftui selected

我正在尝试掌握SwiftUI概念(完成了Apple的SwiftUI教程),但是在UIKit十年之后,对我来说似乎很难。

我需要通过单击它们(UIKit的isSelected)来切换HStack中多个按钮的状态,并更改其字体和文本(在UIKit的世界中,我会在{{1}中使用attributedText属性}语句exekinig if属性,全部位于isSelected的{​​{1}}中。

我的第一个想法是在其操作块中获得Button的“引用”,但感觉这不是SwiftUI的方式(甚至是不可能的)。我找到了使用Configurator及其isPressed属性(不是我要搜索的属性)的解决方案,但是我需要Button的行为实际上类似于切换。 SwiftUI中是否有任何内置的isSelected替代方法,或者我必须使用@State或@BindableObject创建自己的View实现,以封装一些手势识别器(看起来很丑陋)。预先感谢!

2 个答案:

答案 0 :(得分:2)

我有一个简单的方法。

    @State var selected = false

    func createButton() -> some View {
        Button(action: {
            self.selected.toggle()
        }, label: {
            Text("Hello World")
                .padding(.all, 5)
                .background(selected ? Color.blue : Color.white)
                .foregroundColor(selected ? Color.white : Color.blue)
        })
            .overlay(
                RoundedRectangle(cornerRadius: 4)
                    .stroke(Color.blue, lineWidth: 1)
        )
    }

答案 1 :(得分:1)

我想出了自定义视图,它封装了这样的Button:

    import SwiftUI

struct SelectableButtonStyle: ButtonStyle {

    var isSelected = false

    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .frame(width: 60.0, height: 60.0, alignment: .center)
            .padding()
            .background(Color(#colorLiteral(red: 1, green: 0.8980392157, blue: 0.7058823529, alpha: 1)))
            .clipShape(RoundedRectangle(cornerRadius: isSelected ? 16.0 : 0.0))
            .overlay(RoundedRectangle(cornerRadius: isSelected ? 16.0 : 0.0).stroke(lineWidth: isSelected ? 2.0 : 0.0).foregroundColor(Color.pink))
            .animation(.linear)
    }
}


struct StatedButton<Label>: View where Label: View {


    private let action: (() -> ())?

    private let label: (() -> Label)?

    @State var buttonStyle = SelectableButtonStyle()

    init(action: (() -> ())? = nil, label: (() -> Label)? = nil) {
        self.action = action
        self.label = label
    }

    var body: some View {
        Button(action: {
            self.buttonStyle.isSelected = !self.buttonStyle.isSelected
            self.action?()
            print("isSelected now is \(self.buttonStyle.isSelected ? "true" : "false")")
        }) {
            label?()
        }
        .buttonStyle(buttonStyle)
    }    
}

请让我知道该解决方案是否不好,为什么,我非常感谢。而且,我还在一个非常琐碎的问题上苦苦挣扎:如何将模型的数组元素映射到按钮上(即如何检测确切地点击了哪个按钮),但是我认为我必须为此创建另一个问题。