繁体   English   中英

Swift UI 中具有圆角半径的按钮边框

[英]Button border with corner radius in Swift UI

我正在尝试为按钮设置圆角边框,但按钮的边框不正确。

代码:

Button(action: {
        print("sign up bin tapped")          
}) {
    Text("SIGN UP")
      .frame(minWidth: 0, maxWidth: .infinity)
      .font(.system(size: 18))
      .padding()
      .foregroundColor(.white)
 }
  .border(Color.white, width: 2)
  .cornerRadius(25)

Output:

在此处输入图像描述

如您所见,拐角处的边界被切断。

任何建议我做错了什么?

像这样尝试:不要将cornerRadius设置为Button,而是使用内部视图的叠加层:

编辑:如果您有按钮的背景,您还需要将cornerRadius 应用于背景。

    Button(action: {
        print("sign up bin tapped")
    }) {
        Text("SIGN UP")
            .frame(minWidth: 0, maxWidth: .infinity)
            .font(.system(size: 18))
            .padding()
            .foregroundColor(.white)
            .overlay(
                RoundedRectangle(cornerRadius: 25)
                    .stroke(Color.white, lineWidth: 2)
        )
    }
    .background(Color.yellow) // If you have this
    .cornerRadius(25)         // You also need the cornerRadius here
    

为我工作。 让我知道它是否有帮助!

更新了 Swift 5 和 iOS 13.4+ 与新闻状态!

这些示例都不适用于同时具有深色和白色背景 colors 的按钮,而且它们都没有按 state 更新,所以我构建了这个您可以在下面看到的LargeButton视图。 希望这会有所帮助,应该很容易使用!

示例照片

在此处输入图像描述

示例使用

// White button with green border.
LargeButton(title: "Invite a Friend", 
            backgroundColor: Color.white, 
            foregroundColor: Color.green) {
                        print("Hello World")
                    }

// Yellow button without a border
LargeButton(title: "Invite a Friend", 
            backgroundColor: Color.yellow) {
                        print("Hello World")
                    }

代码

struct LargeButtonStyle: ButtonStyle {
    
    let backgroundColor: Color
    let foregroundColor: Color
    let isDisabled: Bool
    
    func makeBody(configuration: Self.Configuration) -> some View {
        let currentForegroundColor = isDisabled || configuration.isPressed ? foregroundColor.opacity(0.3) : foregroundColor
        return configuration.label
            .padding()
            .foregroundColor(currentForegroundColor)
            .background(isDisabled || configuration.isPressed ? backgroundColor.opacity(0.3) : backgroundColor)
            // This is the key part, we are using both an overlay as well as cornerRadius
            .cornerRadius(6)
            .overlay(
                RoundedRectangle(cornerRadius: 6)
                    .stroke(currentForegroundColor, lineWidth: 1)
        )
            .padding([.top, .bottom], 10)
            .font(Font.system(size: 19, weight: .semibold))
    }
}

struct LargeButton: View {
    
    private static let buttonHorizontalMargins: CGFloat = 20
    
    var backgroundColor: Color
    var foregroundColor: Color
    
    private let title: String
    private let action: () -> Void
    
    // It would be nice to make this into a binding.
    private let disabled: Bool
    
    init(title: String,
         disabled: Bool = false,
         backgroundColor: Color = Color.green,
         foregroundColor: Color = Color.white,
         action: @escaping () -> Void) {
        self.backgroundColor = backgroundColor
        self.foregroundColor = foregroundColor
        self.title = title
        self.action = action
        self.disabled = disabled
    }
    
    var body: some View {
        HStack {
            Spacer(minLength: LargeButton.buttonHorizontalMargins)
            Button(action:self.action) {
                Text(self.title)
                    .frame(maxWidth:.infinity)
            }
            .buttonStyle(LargeButtonStyle(backgroundColor: backgroundColor,
                                          foregroundColor: foregroundColor,
                                          isDisabled: disabled))
                .disabled(self.disabled)
            Spacer(minLength: LargeButton.buttonHorizontalMargins)
        }
        .frame(maxWidth:.infinity)
    }
}

iOS 15+ 中的官方.bordered修饰符支持

Button现在已经使用.buttonStyle(.bordered)修饰符获得了边框样式支持。 我建议使用 Apple 为这些按钮提供的圆角半径,以获得最佳的特定于平台的样式。 我们可以将颜色更改为与系统 styles 的按钮一致,并使用.tint修饰符为背景和文本着色:

Button("Add") { ... }
.buttonStyle(.bordered)
.tint(.green)

绿色色调按钮

您可以使用.controlSize使色调颜色更加突出(更大胆)并使用.borderedProminent控制大小:

Button("food") { ... }
.tint(.red)
.controlSize(.small) // .large, .medium or .small
.buttonStyle(.borderedProminent)

小按钮

您还可以在Button的父View上使用此修饰符,并在子Button中使用.accentColor切换较浅的配色方案:

ScrollView {
    LazyVStack {
        Button("Test Button 1") { ... }
        .buttonStyle(.borderedProminent)
        .keyboardShortcut(.defaultAction) // Tapping `Return` key actions this button

        Button("Test Button 2") { ... }
        .tint(.accentColor)
    }
}
.buttonStyle(.bordered)
.controlSize(.large)

大按钮样式

建议

Apple 出于某种原因不喜欢单线边框按钮,这就是为什么.border()修饰符在 Xcode 12 中被弃用的原因。通过此更改,我建议开发人员避免创建单线边框按钮,因为它们现在在 Apple 的人机界面指南。 在任何地方使用突出的按钮也违反了 HIG。

额外注意:Apple 的.bordered样式提供跨设备类型的标准平台样式。 此外, Button动态响应暗模式并使用动态类型(本机可访问性支持)缩放其大小。

Swift 5 & iOS 14 – 按下时边框也会反应

struct PrimaryButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding(5)
            .foregroundColor(configuration.isPressed ? Color.red.opacity(0.5) : .red)
            .overlay(
                RoundedRectangle(cornerRadius: 8)
                    .stroke(configuration.isPressed ? Color.red.opacity(0.5) : .red, lineWidth: 1.5)
            )
     }
}

如何使用

Button("Hide") {
    print("tapped")
}.buttonStyle(PrimaryButtonStyle())

边框在按下时也会做出反应

只需添加cornerRadius参数:

.border(Color.white, width: 2, cornerRadius: 25)

使用这个简单的扩展

extension View {
    func border(_ color: Color, width: CGFloat, cornerRadius: CGFloat) -> some View {
        overlay(RoundedRectangle(cornerRadius: cornerRadius).stroke(color, lineWidth: width))
    }
}

预习

Xcode 11.4.1

                            Button(action: self.action) {
                                Text("Button Name")
                                    .font(.system(size: 15))
                                    .fontWeight(.bold)
                                    .foregroundColor(.white)
                                    .padding(10)
                                    .background(Color.darkGray)
                                    .cornerRadius(10)
                            }
                            .buttonStyle(PlainButtonStyle())

无需添加叠加层。 您可以用帧修饰符替换填充修饰符。 该操作是主体变量之外的非返回方法。

专门针对@MinonWeerasinghe:

Button(action: self.action) {
            Text("Button Name")
                .font(.system(size: 15))
                .fontWeight(.bold)
                .foregroundColor(.black)
                .padding(10)
                .background(RoundedRectangle(cornerRadius: 10).stroke().foregroundColor(Color.red))
                .cornerRadius(10)
        }
        .buttonStyle(PlainButtonStyle())

你可以试试这个:

var body: some View {
        ZStack {
            Color.green
            .edgesIgnoringSafeArea(.all)

            HStack {
            Button(action: {
                    print("sign up bin tapped")
            }){
                HStack {
                    Text("SIGN UP")
                        .font(.system(size: 18))
                    }
                .frame(minWidth: 0, maxWidth: 300)
                .padding()
                .foregroundColor(.white)
                .overlay(
                    RoundedRectangle(cornerRadius: 40)
                        .stroke(Color.white, lineWidth: 2)
                )

                }
            }
        }
    }

我也没有将 maxWidth 设置为.infinity,因为这意味着按钮将填充容器视图的宽度。

结果将是:

在此处输入图像描述

希望能帮助到你:)

这对我有用

Button(action: {
  print("Exit the onboarding")
}) {
HStack (spacing: 8) {
  Text("NEXT")
  .foregroundColor(Color("ColorAccentOppBlack"))
}
.padding(.horizontal, 16)
.padding(.vertical, 10)
.foregroundColor(Color("ColorYellowButton"))
.background(
   Capsule().strokeBorder(Color("ColorYellowButton"), lineWidth: 1.25)
 )
} 
.accentColor(Color("ColorYellowButton"))

你应该使用胶囊。 这是内置在 SwiftUI 中的。 它照顾圆角。 完整的实现在这里https://redflowerinc.com/how-to-implement-rounded-corners-for-buttons-in-swiftui/

public struct ButtonStyling : ButtonStyle {
    public var type: ButtonType
    public init(type: ButtonType = .light) {
        self.type = type
    }
    public func makeBody(configuration: Configuration) -> some View {
        configuration.label.foregroundColor(Color.white)
            .padding(EdgeInsets(top: 12,
                                   leading: 12,
                                   bottom: 12,
                                   trailing: 12))
               .background(AnyView(Capsule().fill(Color.purple)))
               .overlay(RoundedRectangle(cornerRadius: 0).stroke(Color.gray, lineWidth: 0))
    }
}

在此处输入图像描述

要创建带圆角的边框,您可以绘制一个圆角矩形并覆盖在按钮上,如下所示:

  Button(action: {
        print("Hello button tapped!")
    }) {
        Text("Hello World")
            .fontWeight(.bold)
            .font(.title)
            .foregroundColor(.purple)
            .padding()
            .overlay(
                RoundedRectangle(cornerRadius: 20)
                    .stroke(Color.purple, lineWidth: 5)
            )
    }

在此处输入图像描述

Swift 5.6 版您可以使用按钮属性,例如

       Button(action: {
            //define action
        }) {
            Image(systemName: "arrow.triangle.2.circlepath.circle.fill")
                .imageScale(.large)
            Text("Restart")
                .font(.system(.title2))
        }
        .buttonStyle(.borderedProminent)
        .buttonBorderShape(.capsule)
        .controlSize(.large)

在此处输入图像描述

        .buttonBorderShape(.roundedRectangle) //change bordershape see below

在此处输入图像描述

        .buttonBorderShape(.roundedRectangle(radius: 4)) // see below

在此处输入图像描述

同样,您可以更改buttonSytlecontrolSize

想知道如何使用颜色渐变和角半径添加按钮边框这是如何..

  Button(action: {self.isCreateAccountTapped = true},label: {Text("Create an Account")
.foregroundColor(Color("TextThemeColor36"))}
 )
.frame(height: 44)
.frame(width: 166)
.background(Color.clear)
.cornerRadius(8)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(LinearGradient(gradient: Gradient(colors: [Color("BtnGradientClr1"),Color("BtnGradientClr2"),Color("BtnGradientClr3")]), startPoint: .leading, endPoint: .trailing)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM