如何设置SwiftUI按钮的自定义突出显示状态

如何设置SwiftUI按钮的自定义突出显示状态,swiftui,Swiftui,我有一个钮扣。我想为高亮显示状态设置自定义背景色。我如何在SwiftUI中完成它 据我所知,到目前为止,还没有官方支持的方法可以做到这一点。这里有一个您可以使用的小解决方法。这将产生与UIKit中相同的行为,在UIKit中,点击按钮并将手指从按钮上拖下来将保持按钮高亮显示 struct hover按钮:视图,其中标签:视图{ 私人出租行为:()->() 私有出租标签:()->标签 初始化(操作:@escaping()->(),标签:@escaping()->label){ 行动 self.la

我有一个钮扣。我想为高亮显示状态设置自定义背景色。我如何在SwiftUI中完成它


据我所知,到目前为止,还没有官方支持的方法可以做到这一点。这里有一个您可以使用的小解决方法。这将产生与UIKit中相同的行为,在UIKit中,点击按钮并将手指从按钮上拖下来将保持按钮高亮显示

struct hover按钮:视图,其中标签:视图{
私人出租行为:()->()
私有出租标签:()->标签
初始化(操作:@escaping()->(),标签:@escaping()->label){
行动
self.label=标签
}
@按下状态私有变量:Bool=false
var body:一些观点{
按钮(操作:操作){
标签()
.foregroundColor(按下?.red:.蓝色)
.手势(牵引力(最小距离:0.0)
.onChanged{in self.pressed=true}
.onEnded{inself.pressed=false})
}    
}
}
为SwiftUI beta 5更新 SwiftUI实际上是这样做的:
按钮样式

struct MyButtonStyle:ButtonStyle{
func makeBody(配置:Self.configuration)->一些视图{
配置标签
.padding()
.foregroundColor(.白色)
.background(configuration.isPressed?Color.red:Color.blue)
.转弯半径(8.0)
}
}
//使用它
按钮(操作:{}){
文本(“你好,世界”)
}
.buttonStyle(MyButtonStyle())

我正在寻找一个类似的功能,我用以下方法实现了它

我创建了一个特殊的视图结构,以我需要的样式返回一个按钮,在这个结构中我添加了一个状态属性selected。我有一个名为“table”的变量,它是一个Int,因为我的按钮是圆形的,上面有数字

struct TableButton: View {
    @State private var selected = false

    var table: Int

    var body: some View {
        Button("\(table)") {
            self.selected.toggle()
        }
        .frame(width: 50, height: 50)
        .background(selected ? Color.blue : Color.red)
        .foregroundColor(.white)
        .clipShape(Circle())
    }
}
然后在我的内容视图中使用代码

HStack(spacing: 10) {
  ForEach((1...6), id: \.self) { table in
    TableButton(table: table)
  }
}
这将创建一个水平堆栈,其中有6个按钮,选中时为蓝色,取消选中时为红色


我不是一个有经验的开发人员,但我只是尝试了所有可能的方法,直到我发现这对我是有效的,希望它对其他人也有用

这适用于对上述解决方案不满意的人,因为他们会提出其他问题,例如手势重叠(例如,现在很难在scrollview中使用此解决方案)。另一个关键是创建这样的自定义按钮样式

struct CustomButtonStyle<Content>: ButtonStyle where Content: View {
    
    var change: (Bool) -> Content
    
    func makeBody(configuration: Self.Configuration) -> some View {
        return change(configuration.isPressed)
    }
}
struct CustomButtonStyle:ButtonStyle其中Content:View{
变量更改:(Bool)->内容
func makeBody(配置:Self.configuration)->一些视图{
返回更改(configuration.isPressed)
}
}
因此,我们应该只传递闭包,它将返回按钮的状态,并基于此参数创建按钮。它的使用方式如下:

struct CustomButton<Content>: View where Content: View {
    var content:  Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    var body: some View {
        Button(action: { }, label: {
            EmptyView()
        })
            .buttonStyle(CustomButtonStyle(change: { bool in
                Text("\(bool ? "yo" : "yo2")")
            }))
   }
} 
struct CustomButton:视图,其中内容:视图{
var-content:content
init(@ViewBuilder内容:()->content){
self.content=content()
}
var body:一些观点{
按钮(操作:{},标签:{
EmptyView()
})
.buttonStyle(CustomButtonStyle)(更改:{bool in
文本(\(bool?“yo”:“yo2”))
}))
}
} 

好的,让我再把一切都清理一遍。这是确切的答案

  • 创建下面的按钮修改器
  • struct StateableButton:ButtonStyle其中Content:View{
    变量更改:(Bool)->内容
    func makeBody(配置:配置)->一些视图{
    返回更改(configuration.isPressed)
    }
    }
    
  • 然后像下面一样使用它
  • 按钮(操作:{
    打印(“做某事”)
    },标签:{
    //不要在此处创建按钮视图
    EmptyView()
    })
    .buttonStyle(statableButton(更改:{state in
    //在此处创建按钮视图
    回钉{
    图像(系统名称:“clock.arrow.circlepath”)
    文本(项目)
    垫片()
    图像(系统名称:“箭头。向上。向后”)
    }
    .padding(.卧式)
    .框架(高度:50)
    .背景(状态?颜色。黑色:颜色。清晰)
    }))
    
    真是个好发现!也可以使用
    .longPressAction(最小持续时间:0,最大距离:{}){pressed in self.pressed=pressed}}
    完成。但是,这不会产生动画,是吗?:嗯:@thisIsTheFoxe使用
    和动画{}
    。如果按钮位于滚动视图中的某个位置,则此操作是否有效?否@DavidAnderson我将切换回正常按钮,因为我得到以下信息:
    dyld:Symbol未找到:\uu$s7swiftui11按钮样式413配置9ispressed4bodyqzaa0c0vyaa0cd5labelvu SbtFTq
    这没有配置按钮的标签而不是按钮本身?我看到的行为暗示了configuration.label会影响子视图,比如说,如果要在样式中设置一个角半径,但在按钮上的
    .buttonStyle(…)
    后面设置一个背景,有什么方法可以创建自定义禁用样式?与
    .disabled(true)
    ?@PavelAlexeev一起应用的选项,请参阅以获取问题的解决方案。这仅适用于未选择的已按下状态,这只是一种瞬时状态:“一个布尔值,指示用户当前是否正在按下按钮。”能否显示使用CustomButton的示例?
    struct CustomButton<Content>: View where Content: View {
        var content:  Content
        
        init(@ViewBuilder content: () -> Content) {
            self.content = content()
        }
        var body: some View {
            Button(action: { }, label: {
                EmptyView()
            })
                .buttonStyle(CustomButtonStyle(change: { bool in
                    Text("\(bool ? "yo" : "yo2")")
                }))
       }
    }