带有圆角和边框的 SwiftUI 视图

sol*_*eil 64 swift swiftui viewmodifier

            ZStack {
                VStack {
                    Text("some text")
                    Button("Ok") {}
                     .foregroundColor(.cyan)
                     .padding()
                }
                .padding()
            }
            .background(.red)
            .border(.blue, width: 5)
            .cornerRadius(20)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我希望整个视图具有带圆角的蓝色边框(而不是与圆形蓝色边框重叠的红色正方形。如何实现?我似乎已经尝试了排序修改器的所有变体。

ahe*_*eze 125

无论您应用什么角半径,SwiftUI 边框都有直边(.cornerRadius只需将视图剪辑为圆形蒙版,并且不调整边框的外观)。

如果你想要一个圆角边框,你需要覆盖和.stroke一个圆角矩形:

VStack {
    Text("some text")
    Button("Ok") {}
        .foregroundColor(.cyan)
        .padding()
}
.padding()
.background(.red)
.cornerRadius(20) /// make the background rounded
.overlay( /// apply a rounded border
    RoundedRectangle(cornerRadius: 20)
        .stroke(.blue, lineWidth: 5)
)
Run Code Online (Sandbox Code Playgroud)

结果:

蓝色圆形边框

  • 使用 StrokeBorder() 更好。它不会防止边缘插入的任何问题。 (14认同)
  • `StrokeBorder()` 是一个至关重要的修饰符!否则它看起来就像用 MS Paint 制作的边框 (2认同)

Lev*_*dze 23

有时仅仅添加覆盖可能会产生不令人满意的结果(当使用的视图设计为无限宽度/高度时就是这种情况)

例如

所以我建议在尝试添加圆形边框时使用插图

.overlay(
    RoundedRectangle(cornerRadius: 20)
        .inset(by: 5) // inset value should be same as lineWidth in .stroke
        .stroke(.blue, lineWidth: 5)
)
Run Code Online (Sandbox Code Playgroud)


Rad*_*che 6

添加其他答案,这是您的SwiftUI应用程序的一个简洁的扩展:

fileprivate struct ModifierCornerRadiusWithBorder: ViewModifier {
    var radius: CGFloat
    var borderLineWidth: CGFloat = 1
    var borderColor: Color = .gray
    var antialiased: Bool = true
    
    func body(content: Content) -> some View {
        content
            .cornerRadius(self.radius, antialiased: self.antialiased)
            .overlay(
                RoundedRectangle(cornerRadius: self.radius)
                    .inset(by: self.borderLineWidth)
                    .strokeBorder(self.borderColor, lineWidth: self.borderLineWidth, antialiased: self.antialiased)
            )
    }
}

extension View {
    func cornerRadiusWithBorder(radius: CGFloat, borderLineWidth: CGFloat = 1, borderColor: Color = .gray, antialiased: Bool = true) -> some View {
        modifier(ModifierCornerRadiusWithBorder(radius: radius, borderLineWidth: borderLineWidth, borderColor: borderColor, antialiased: antialiased))
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以做

VStack {
    Text("some text")
    Button("Ok") {}
        .foregroundColor(.cyan)
        .padding()
}
.padding()
.background(.red)
.cornerRadiusWithBorder(radius: 20, borderLineWidth: 5, borderColor: . blue)
Run Code Online (Sandbox Code Playgroud)

为了达成这个

在此输入图像描述