SwiftUI:长按填充按钮显示进度?

SwiftUI: Long Press fills button to show progress?

提问人:GarySabo 提问时间:11/6/2023 更新时间:11/6/2023 访问量:39

问:

我为手表应用程序拼凑了这段代码,它有点工作,但并不完美。(1)填充不完全匹配,它从按钮视图的边界之外开始,但我无法弄清楚如何准确匹配按钮的大小。(2) 我无法将可点击区域扩展到视图的左侧和右侧。即使我添加或唯一可点击的部分是图像和文本所在的中间。有没有更好的方法可以做到这一点?.contentShape(rectangle).frame(maxWidth: .infinity)

struct ContentView2: View {
    
    @State var isComplete: Bool = false
    @State var isSuccess: Bool = false
    
    var body: some View {
        VStack {
            ZStack {
                RoundedRectangle(cornerRadius: 12.0)
                    .fill(isSuccess ? Color.clear : Color.red.opacity(0.50))
                    .frame(maxWidth: isComplete ? .infinity : 0)
                    .frame(height: 55) //How to now hard code this? 
                    .frame(maxWidth: .infinity, alignment: .leading)
                Button(action: {}, label: {
                    VStack  {
                        Image(systemName: "multiply.circle.fill")
                            .font(.system(size: 24, weight: .regular))
                            .foregroundColor(.red)
                        Text("Hold to End")
                            .font(.footnote)
                    }
                    .onLongPressGesture(minimumDuration: 1.0, maximumDistance: 50) {
                        withAnimation(.easeInOut) {
                            isSuccess = true
                            //perform action
                        }
                        
                    } onPressingChanged: { isPressing in
                        if isPressing {
                            withAnimation(.easeIn(duration: 1.0)) {
                                isComplete = true
                            }
                        } else {
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                                if !isSuccess {
                                    withAnimation(.easeInOut) {
                                        isComplete = false
                                    }
                                }
                            }
                        }
                    }
                })
                .tint(.pink)
                
            }
        }
    }
}

#Preview {
    ContentView2()
}
iOS Swift SwiftUI Apple-Watch SwiftUI 按钮

评论


答:

1赞 jrturton 11/6/2023 #1

(1)填充不完全匹配,它从按钮视图的边界之外开始,但我无法弄清楚如何准确匹配按钮的大小。

将圆角矩形作为按钮标签的背景,然后它会自动获得相同的大小:

Button(action: {}, label: {
    VStack  {
        ...
    }
    .background {
        RoundedRectangle(cornerRadius: 12.0)
            .fill(isSuccess ? Color.clear : Color.red.opacity(0.50))
            .frame(maxWidth: isComplete ? .infinity : 0)
            .frame(maxWidth: .infinity, alignment: .leading)
    }

(2) 我无法将可点击区域扩展到视图的左侧和右侧。

您可能将框架修饰符添加到错误的位置。它本身实际上并没有在这里做任何事情,删除它可能会使图片对你来说更清晰,但你希望按钮的标签是最大宽度的东西,如果你想让背景填满整个宽度,这必须在背景之前,或者如果你想让背景与可见内容的宽度相匹配,则必须在背景之后:Button

Button(action: {}, label: {
    VStack  {
        ...
    }
    .frame(maxWidth: .infinity)
    .background {
        ...
    }
    .contentShape(Rectangle())
    .onLongPressGesture ....

评论

0赞 GarySabo 11/6/2023
谢谢,这很有帮助!整个区域现在都是可点击的,唯一的问题是填充现在没有垂直填充按钮的胶囊形状......无论如何要让它完全填满?🤔
0赞 jrturton 11/7/2023
这是watchOS的事情吗?我只在iOS上测试过
0赞 GarySabo 11/7/2023
是的,我在手表应用程序中使用,但我不明白为什么 SwiftUI 中的行为会有所不同?
0赞 jrturton 11/7/2023
iOS中的按钮上没有“胶囊形状”
1赞 jrturton 11/7/2023
要使其与手表按钮匹配,您可能需要制作自己的按钮样式,或者使用普通按钮样式并绘制自己的背景。正如我在回答中提到的,您实际上并没有在这里使用按钮,而只是一个可以长按的视图,因此您可以随心所欲地使用它。