让两个按钮充当一个 SwiftUI

Posted

技术标签:

【中文标题】让两个按钮充当一个 SwiftUI【英文标题】:Make two buttons acting as one SwiftUI 【发布时间】:2020-09-12 19:29:38 【问题描述】:

我想让两个按钮作为一个按钮,或者只有一个按钮,但触摸区域只有图片中的红色区域。一个普通的按钮也会在触摸区域有我放置 x-es 的空白区域,这是我不想要的。

struct ContentView: View 
    var body: some View 
        HStack(spacing: 0) 
            Spacer()
            
            Button(action: ) 
                Text("This is button 1")
                    .frame(width: 100, height: 200)
                    .background(Color.red)
            
            
            Button(action: ) 
                Text("This is button 2")
                    .frame(height: 100)
                    .background(Color.red)
            
            
            Spacer()
        
    

【问题讨论】:

【参考方案1】:

这是可以做到的一种方法。有一个带有两个重叠白色矩形的按钮。只有红色区域可以点击:

struct ContentView: View 
    var body: some View 
        HStack(spacing: 0) 
            Spacer()
            
            Button(action: ) 
                Text("This is one big button")
                .frame(width: 200, height: 200)
                .background(Color.red)
            
            .overlay(
                HStack 
                    Spacer()
                    VStack 
                        Rectangle()
                            .frame(width: 100, height: 50)
                            .foregroundColor(.white)
                        Spacer()
                        Rectangle()
                            .frame(width: 100, height: 50)
                            .foregroundColor(.white)
                    
                
            )
        
            Spacer()
        
    


使用自定义形状的解决方案

另一种方法是为Button 创建一个自定义Shape,然后用它来绘制和设置它的contentShape()

struct ButtonShape: Shape 
    func path(in rect: CGRect) -> Path 
        var path = Path()
        let width = rect.width
        let height = rect.height
        
        path.move(to: CGPoint(x: 0, y: 0))
        path.addLine(to: CGPoint(x: width/2, y: 0))
        path.addLine(to: CGPoint(x: width/2, y: height/4))
        path.addLine(to: CGPoint(x: width, y: height/4))
        path.addLine(to: CGPoint(x: width, y: 3 * height/4))
        path.addLine(to: CGPoint(x: width/2, y: 3 * height/4))
        path.addLine(to: CGPoint(x: width/2, y: height))
        path.addLine(to: CGPoint(x: 0, y: height))
        path.closeSubpath()
        
        return path
    


struct ContentView: View 
    var body: some View 
        HStack(spacing: 0) 
            Spacer()
            
            Button(action: ) 
                Color.red
                    .clipShape(ButtonShape())
                    .overlay(
                        Text("This is one big button")
                    )
            
            .contentShape(ButtonShape())
            .frame(width: 200, height: 200)
        
            Spacer()
        
    

此解决方案总体上效果更好,因为没有绘制剪切区域,因此更容易将此按钮放在彩色背景上。

【讨论】:

我修复了第一个解决方案。 我对第一个解决方案有一个问题/观察,似乎不知何故矩形宽度并不是真正的 100 点(即使它们在视觉上是)。在矩形的左边距,即使按钮被矩形覆盖,按钮仍然会对触摸做出反应 你是对的,在第一个解决方案中,按钮的所有侧面的触摸边界都更宽。在第二种情况下,触摸边界正是绘制的内容。我不能说这是为什么。 第二个似乎也是同样的问题,无论如何,干得好,非常感谢!

以上是关于让两个按钮充当一个 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

如何使 UIView 充当操作表?

播放/暂停音频按钮 Swift

一个按钮和两个不同的视图

可点击的 div 充当按钮功能 react js

使用 jQuery 对充当 Radio 的按钮进行 Bootstrap3 表单验证

HTML 语义 - 充当锚点的按钮