如何在 Button 边缘上制作 cornerRadius,以便边缘不会在 swiftUI 中被剪裁
How to make cornerRadius on Button edges so that edges are not clipped in swiftUI
我正在试验 SwiftUI。我不知道如何获得带有 borderWidth 的圆形按钮。下面是我试过的代码。
这是我的代码
struct ArrowButton : View {
var body: some View {
return Button(action: {}) {
HStack {
Text("SEE ALL")
.font(.headline)
.color(Color.init(red: 0.627, green: 0.776, blue: 0.965))
Image(systemName: "arrow.right")
.font(Font.title.weight(.bold))
}
}
.padding(.all, 9.0)
.border(Color.init(red: 0.627, green: 0.776, blue: 0.965))
.cornerRadius(5.0)
}
}
这是我的观点
我应该使用什么修饰符
- 增加边框宽度?
- 去掉下图的剪裁效果?
指定边框的宽度和圆角半径:
.border(Color.init(red: 0.627, green: 0.776, blue: 0.965),
width: 6.0,
cornerRadius: 12.0))
例如这段代码:
struct ContentView : View {
var body: some View {
return Button(action: {}) {
HStack {
Text("SEE ALL")
.font(.headline)
.color(Color.init(red: 0.627, green: 0.776, blue: 0.965))
Image(systemName: "arrow.right")
.font(Font.title.weight(.bold))
}
}
.padding(.all, 20.0)
.border(Color.init(red: 0.627, green: 0.776, blue: 0.965),
width: 6.0,
cornerRadius: 40.0)
}
}
此视图中的结果:
针对 Swift 5 和 iOS 13.4+ 进行了更新,其中包含 Press States!
None 的示例适用于具有深色和白色背景颜色的按钮以及 none 具有按下状态更新的按钮,所以我构建了这个 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)
}
}
View.border(:width:cornerRadius)
方法在最终的 Xcode 11 版本中不可用,但您可以通过同时应用 cornerRadius
和 overlay
修饰符来获得相同的结果:
Button(action: {}) {
VStack {
Image(systemName: "star.fill")
Text("Hello world!")
}
.padding()
.accentColor(Color(.systemRed))
.background(Color(UIColor.systemRed.withAlphaComponent(0.4)))
.cornerRadius(4.0)
.overlay(
RoundedRectangle(cornerRadius: 4).stroke(Color(.systemRed), lineWidth: 2)
)
}
结果:
我正在试验 SwiftUI。我不知道如何获得带有 borderWidth 的圆形按钮。下面是我试过的代码。
这是我的代码
struct ArrowButton : View {
var body: some View {
return Button(action: {}) {
HStack {
Text("SEE ALL")
.font(.headline)
.color(Color.init(red: 0.627, green: 0.776, blue: 0.965))
Image(systemName: "arrow.right")
.font(Font.title.weight(.bold))
}
}
.padding(.all, 9.0)
.border(Color.init(red: 0.627, green: 0.776, blue: 0.965))
.cornerRadius(5.0)
}
}
这是我的观点
我应该使用什么修饰符
- 增加边框宽度?
- 去掉下图的剪裁效果?
指定边框的宽度和圆角半径:
.border(Color.init(red: 0.627, green: 0.776, blue: 0.965),
width: 6.0,
cornerRadius: 12.0))
例如这段代码:
struct ContentView : View {
var body: some View {
return Button(action: {}) {
HStack {
Text("SEE ALL")
.font(.headline)
.color(Color.init(red: 0.627, green: 0.776, blue: 0.965))
Image(systemName: "arrow.right")
.font(Font.title.weight(.bold))
}
}
.padding(.all, 20.0)
.border(Color.init(red: 0.627, green: 0.776, blue: 0.965),
width: 6.0,
cornerRadius: 40.0)
}
}
此视图中的结果:
针对 Swift 5 和 iOS 13.4+ 进行了更新,其中包含 Press States!
None 的示例适用于具有深色和白色背景颜色的按钮以及 none 具有按下状态更新的按钮,所以我构建了这个 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)
}
}
View.border(:width:cornerRadius)
方法在最终的 Xcode 11 版本中不可用,但您可以通过同时应用 cornerRadius
和 overlay
修饰符来获得相同的结果:
Button(action: {}) {
VStack {
Image(systemName: "star.fill")
Text("Hello world!")
}
.padding()
.accentColor(Color(.systemRed))
.background(Color(UIColor.systemRed.withAlphaComponent(0.4)))
.cornerRadius(4.0)
.overlay(
RoundedRectangle(cornerRadius: 4).stroke(Color(.systemRed), lineWidth: 2)
)
}
结果: