在 SwiftUI Xcode beta 5 中向图像添加带有 cornerRadius 的边框
Add a border with cornerRadius to an Image in SwiftUI Xcode beta 5
如何为图像添加带 cornerRadius
的边框。我收到弃用警告,说我应该使用 RoundedRectange Shape,但我不知道如何使用它
测试版 4:
Image(uiImage: ...)
.border(Color.black, width: 2, cornerRadius: 10)
首先,请注意您的操作方式并不是裁剪图像。也许您没有注意到图像是否太小,或者它是否具有与您的 canvas 相同颜色的背景。但即使在使用 beta 4 语法时,您也需要添加 .clipShape()
.
回到您的问题,根据 Beta 5 发行说明:
Complex overloads for the background(:alignment:) and
border(:width:) modifiers are deprecated. Use shapes in a
background(:alignment:) or overlay(:alignment:) to draw these
instead. (53067530)
所以模式应该是这样的:
.overlay(RoundedRectangle(...).stroke(...).foregroundColor(...))
在您的具体情况下:
Image("mypic").resizable().frame(width: 300, height: 300)
.clipShape(RoundedRectangle(cornerRadius: 30))
.overlay(RoundedRectangle(cornerRadius: 30).stroke(lineWidth: 2).foregroundColor(Color.black))
我真的很喜欢 kontiki 的回答,但不喜欢它的长度,所以我写道:
import SwiftUI
func strokedRoundedRectangle(
cornerRadius r: CGFloat,
lineWidth w: CGFloat = 1,
color c: Color = .primary
) -> some View {
return RoundedRectangle(cornerRadius: r).stroke(lineWidth: w).foregroundColor(c)
}
SwiftUI 1.0
使用 cornerRadius 和叠加修改器
这是另一种方法,我们可以使用 cornerRadius 修改器(它会剪裁视图),然后用颜色覆盖描边。
VStack(spacing: 40) {
Text("Image Border").font(.largeTitle)
Text("Using cornerRadius & overlay").font(.title).foregroundColor(.gray)
Text("Using cornerRadius will also clip the image. Then overlay a border.")
.frame(minWidth: 0, maxWidth: .infinity)
.font(.title)
.padding()
.background(Color.orange)
.foregroundColor(.black)
Image("profile")
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.orange, lineWidth: 4))
.shadow(radius: 10)
}
结果
考虑一下:向视图添加修饰符将 return 一个新的 View
实例来包装先前的实例。这也是添加修饰符的顺序很重要的原因。
我们可以利用这一点:通过添加填充,然后向我们的新视图添加背景,我们可以创建自己的附加层:
Image("cat")
.cornerRadius(7) // Inner corner radius
.padding(5) // Width of the border
.background(Color.primary) // Color of the border
.cornerRadius(10) // Outer corner radius
结果:
您甚至可以在 ViewModifier 中将其转换为更容易重用:
struct RoundedEdge: ViewModifier {
let width: CGFloat
let color: Color
let cornerRadius: CGFloat
func body(content: Content) -> some View {
content.cornerRadius(cornerRadius - width)
.padding(width)
.background(color)
.cornerRadius(cornerRadius)
}
}
使用它会变成:
Image("cat").modifier(RoundedEdge(width: 5, color: .black, cornerRadius: 20))
这适用于任何 SwiftUI 视图,例如 Text
:
Text("Some text")
.padding(15)
.background(Color.red)
.modifier(RoundedEdge(width: 5, color: .black, cornerRadius: 20))
结果:
写一个和ImageView一样的圆形文本view
struct RoundedTextView: View {
var body: some View {
Text("Rounded Text View")
.frame(width: 200, height: 200, alignment: .center)
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(16)
.overlay(
RoundedRectangle(cornerRadius: 16).stroke(Color.yellow, lineWidth: 8)
)
}
}
像这张图片一样预览:
在此代码中,我们将在两个具有不同边框的图像视图中显示资产中的图像。
第一张图片的边框为黑色,宽度为 5,第二张图片的边框为橙色,宽度为 10。
struct ContentView: View {
var body: some View {
Image("sunrise")
.resizable()
.cornerRadius(16)
.aspectRatio(contentMode: .fit)
.border(Color.black, width: 5)
.padding(.all, 50)
Image("sunrise")
.resizable()
.cornerRadius(16)
.aspectRatio(contentMode: .fit)
.border(Color.orange, width: 10)
.padding(.all, 50)
}
}
完成;
如何为图像添加带 cornerRadius
的边框。我收到弃用警告,说我应该使用 RoundedRectange Shape,但我不知道如何使用它
测试版 4:
Image(uiImage: ...)
.border(Color.black, width: 2, cornerRadius: 10)
首先,请注意您的操作方式并不是裁剪图像。也许您没有注意到图像是否太小,或者它是否具有与您的 canvas 相同颜色的背景。但即使在使用 beta 4 语法时,您也需要添加 .clipShape()
.
回到您的问题,根据 Beta 5 发行说明:
Complex overloads for the background(:alignment:) and border(:width:) modifiers are deprecated. Use shapes in a background(:alignment:) or overlay(:alignment:) to draw these instead. (53067530)
所以模式应该是这样的:
.overlay(RoundedRectangle(...).stroke(...).foregroundColor(...))
在您的具体情况下:
Image("mypic").resizable().frame(width: 300, height: 300)
.clipShape(RoundedRectangle(cornerRadius: 30))
.overlay(RoundedRectangle(cornerRadius: 30).stroke(lineWidth: 2).foregroundColor(Color.black))
我真的很喜欢 kontiki 的回答,但不喜欢它的长度,所以我写道:
import SwiftUI
func strokedRoundedRectangle(
cornerRadius r: CGFloat,
lineWidth w: CGFloat = 1,
color c: Color = .primary
) -> some View {
return RoundedRectangle(cornerRadius: r).stroke(lineWidth: w).foregroundColor(c)
}
SwiftUI 1.0
使用 cornerRadius 和叠加修改器
这是另一种方法,我们可以使用 cornerRadius 修改器(它会剪裁视图),然后用颜色覆盖描边。
VStack(spacing: 40) {
Text("Image Border").font(.largeTitle)
Text("Using cornerRadius & overlay").font(.title).foregroundColor(.gray)
Text("Using cornerRadius will also clip the image. Then overlay a border.")
.frame(minWidth: 0, maxWidth: .infinity)
.font(.title)
.padding()
.background(Color.orange)
.foregroundColor(.black)
Image("profile")
.cornerRadius(10)
.overlay(RoundedRectangle(cornerRadius: 10)
.stroke(Color.orange, lineWidth: 4))
.shadow(radius: 10)
}
结果
考虑一下:向视图添加修饰符将 return 一个新的 View
实例来包装先前的实例。这也是添加修饰符的顺序很重要的原因。
我们可以利用这一点:通过添加填充,然后向我们的新视图添加背景,我们可以创建自己的附加层:
Image("cat")
.cornerRadius(7) // Inner corner radius
.padding(5) // Width of the border
.background(Color.primary) // Color of the border
.cornerRadius(10) // Outer corner radius
结果:
您甚至可以在 ViewModifier 中将其转换为更容易重用:
struct RoundedEdge: ViewModifier {
let width: CGFloat
let color: Color
let cornerRadius: CGFloat
func body(content: Content) -> some View {
content.cornerRadius(cornerRadius - width)
.padding(width)
.background(color)
.cornerRadius(cornerRadius)
}
}
使用它会变成:
Image("cat").modifier(RoundedEdge(width: 5, color: .black, cornerRadius: 20))
这适用于任何 SwiftUI 视图,例如 Text
:
Text("Some text")
.padding(15)
.background(Color.red)
.modifier(RoundedEdge(width: 5, color: .black, cornerRadius: 20))
结果:
写一个和ImageView一样的圆形文本view
struct RoundedTextView: View {
var body: some View {
Text("Rounded Text View")
.frame(width: 200, height: 200, alignment: .center)
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(16)
.overlay(
RoundedRectangle(cornerRadius: 16).stroke(Color.yellow, lineWidth: 8)
)
}
}
像这张图片一样预览:
在此代码中,我们将在两个具有不同边框的图像视图中显示资产中的图像。
第一张图片的边框为黑色,宽度为 5,第二张图片的边框为橙色,宽度为 10。
struct ContentView: View {
var body: some View {
Image("sunrise")
.resizable()
.cornerRadius(16)
.aspectRatio(contentMode: .fit)
.border(Color.black, width: 5)
.padding(.all, 50)
Image("sunrise")
.resizable()
.cornerRadius(16)
.aspectRatio(contentMode: .fit)
.border(Color.orange, width: 10)
.padding(.all, 50)
}
}
完成;