绘制图标,圆形,渐变等
如何使用图像视图绘制图像?
使用图像视图在 SwiftUI 布局中呈现图像。 这些可以从您的包(bundle),系统图标,UIImage 等加载图像,但是这三个是最常见的。
要从 bundle 中加载图片并将其显示在图片视图中,只需使用以下方法:
Image("dog")
需要在 Assets.xcassets 里面添加 dog 的图片。
如果要使用 Apple 的 SF Symbols 图标集,则应使用 Image(systemName:) 初始化程序,如下所示
Image(systemName: "cloud.heavyrain.fill")
.font(.largeTitle)
请注意,如何使用 font() 修饰符来调整 SF Symbols,就好像它们是文本一样。
如何调整图像适合其空间的展示方式?
SwiftUI 的图片视图可以以不同的方式缩放,就像 UIImageView 的内容模式一样。
默认情况下,图像视图会自动调整其大小以适应其内容,这可能会使它们超出屏幕范围。 如果添加 resizable() 修饰符,则图像将自动调整大小,以使其填满所有可用空间,无论是在您指定的帧内还是在屏幕上可用的任何空间:
Image("rome")
.resizable()
.frame(height: 200)
但是,这也可能导致图像的原始长宽比失真,因为它将在所有尺寸上拉伸所需的任何量以使其填充空间。
如果要保持其宽高比,则应使用 .fill 或 .fit 添加一个 AspectRatio 修饰符,如下所示:
Image("rome")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 250)
如何平铺图像?
如果要求 SwiftUI 使图片视图占用比图片设计的空间更多的空间,则默认行为是拉伸图片以使其适合您所需的空间。 但是,并不需要那样做:它还可以平铺图像,即水平和垂直重复图像,从而完全填充空间。
关键是将 resizable() 修饰符与其 resizingMode 参数一起使用。 该名称可以是 .stretch(默认设置)或 .tile,其中 .tile 是您要查找的内容。
Image("logo")
.resizable(resizingMode: .tile)
如果您只希望平铺图像的一部分(将一个或多个边缘固定在图像视图的边缘),则可以为第一个参数提供边缘插图,如下所示:
Image("logo")
.resizable(capInsets: EdgeInsets(top: 20, leading: 20, bottom: 20, trailing: 20), resizingMode: .tile)
如何使用SF符号渲染图像?
SwiftUI 的 Image 视图使我们可以从 SF Symbols 中加载任何 2400+ 图标,其中许多图标也可以使用多色。
要从 Apple 的 SF Symbols 集中加载图标,请使用 Image(systemName:)初始化程序,并传入要加载的图标字符串,如下所示:
Image(systemName: "cloud.heavyrain.fill")
您获得的图像是可缩放的且可着色的,这意味着您可以要求 SwiftUI 放大图像以匹配其随附的任何“动态类型”文本样式(如果有):
Image(systemName: "cloud.heavyrain.fill")
.font(.largeTitle)
而且这还意味着您可以使用与您已经看到的相同的 frontantColor() 修饰符为图像着色:
Image(systemName: "cloud.heavyrain.fill")
.font(.largeTitle)
.foregroundColor(.red)
如果您使用的图像包含色彩元素,则可以使用 .renderingMode().original) 激活多色模式,如下所示:
Image(systemName: "cloud.sun.rain.fill")
.renderingMode(.original)
.font(.largeTitle)
.padding()
.background(Color.black)
.clipShape(Circle())
您可以选择将 foregroundColor() 修改器应用于多色 SF符号,这将使部分符号重新着色。 例如,这将使图标的一部分变为蓝色,而部分变为绿色:
Image(systemName: "person.crop.circle.fill.badge.plus")
.renderingMode(.original)
.foregroundColor(.blue)
.font(.largeTitle)
通过 Apple 提供的应用 SF Symbols 2 查看 SF Symbols 所有的图标名称。
如何渲染渐变?
SwiftUI 为我们提供了各种渐变选项,所有这些选项都可以以多种方式使用。 例如,您可以使用白色到黑色的线性渐变来渲染文本视图,如下所示:
Text("Hello World")
.padding()
.foregroundColor(.white)
.font(.largeTitle)
.background(
LinearGradient(gradient: Gradient(colors: [.white, .black]), startPoint: .top, endPoint: .bottom)
)
颜色被指定为一个数组,您可以根据需要设置任意多个颜色–默认情况下,SwiftUI 会将它们均匀地隔开。 因此,我们可以像这样从白色变成红色再变成黑色:
Text("Hello World")
.padding()
.foregroundColor(.white)
.font(.largeTitle)
.background(
LinearGradient(gradient: Gradient(colors: [.white, .red, .black]), startPoint: .top, endPoint: .bottom)
)
要制作水平渐变而不是垂直渐变,请使用 .lead 和 .trailing 作为起点和终点:
Text("Hello World")
.padding()
.foregroundColor(.white)
.font(.largeTitle)
.background(
LinearGradient(gradient: Gradient(colors: [.white, .red, .black]), startPoint: .leading, endPoint: .trailing)
)
对于其他渐变样式,请尝试 RadialGradient 或 AngularGradient。 例如,这将创建一个从圆心开始到边缘的各种颜色的径向渐变:
Circle()
.fill(
RadialGradient(gradient: Gradient(colors: [.red, .yellow, .green, .blue, .purple]), center: .center, startRadius: 50, endRadius: 200)
)
.frame(width: 200, height: 200)
这将创建一个角度渐变(通常称为圆锥渐变),循环显示各种颜色,然后返回到起点:
Circle()
.fill(
AngularGradient(gradient: Gradient(colors: [.red, .yellow, .green, .blue, .purple, .red]), center: .center)
)
.frame(width: 200, height: 200)
由于所有三种渐变类型均符合 ShapeStyle 协议,因此可以将它们用于背景,填充和笔触。 例如,这使用我们的彩虹圆锥形渐变作为圆的粗内部笔画:
Circle()
.strokeBorder(
AngularGradient(gradient: Gradient(colors: [.red, .yellow, .green, .blue, .purple, .red]), center: .center, startAngle: .zero, endAngle: .degrees(360)),
lineWidth: 50
)
.frame(width: 200, height: 200)
如何使用图像和其他视图作为背景?
SwiftUI 没有专用的修饰符来显示背景颜色或图像,而是使用其 background() 修饰符指定任何类型的背景视图。
例如,这将创建一个具有大字体的文本视图,然后在其后放置一个 100x100 的图像:
Text("Hacking with Swift")
.font(.system(size: 48))
.padding(50)
.background(
Image("singapore")
.resizable()
)
但是,它不必是图像。 例如,这将创建相同的文本视图,然后在其后放置一个 50x50 的红色圆圈:
Text("Hacking with Swift")
.font(.largeTitle)
.padding()
.background(Circle()
.fill(Color.red)
.frame(width: 50, height: 50))
默认情况下,背景视图会自动占用需要完全可见的空间,但是如果您愿意,可以使用 clipped() 修饰符将其裁剪为其父视图的大小:
Text("Hacking with Swift")
.font(.largeTitle)
.padding()
.background(
Circle()
.fill(Color.red)
.frame(width: 100, height: 100)
)
.clipped()
如何显示实体形状?
SwiftUI 具有多种内置形状,例如矩形,圆形和胶囊形,可以根据需要创建,着色和定位每种形状。
例如,如果您想要一个 200x200 的红色矩形,则可以使用以下代码:
Rectangle()
.fill(Color.red)
.frame(width: 200, height: 200)
同样,如果您想要一个 100x100 的蓝色圆圈,则可以使用以下方法:
Circle()
.fill(Color.blue)
.frame(width: 100, height: 100)
圆角矩形有专用的形状,可让您自定义应应用的圆角程度,并完全控制圆角的类型。 例如,这将创建一个圆角矩形,每个角上有 25 个舍入点:
RoundedRectangle(cornerRadius: 25)
.fill(Color.green)
.frame(width: 150, height: 100)
最后,SwiftUI 提供 Capsule() 形状作为圆角矩形的一种特殊形式,其中矩形的最短边始终是完全圆角的。 这是带有按钮的流行样式,因为只需几行代码就可以得到胶囊形的按钮:
Capsule()
.fill(Color.green)
.frame(width: 150, height: 100)
如何同时填充和描边形状?
SwiftUI 提供了 fill(),stroke() 和 strokeBorder() 修饰符,用于调整绘制图形的方式,但它并未提供内置的填充和描边方式。 但是,我们可以通过两种不同的方式获得相同的效果,在这里我将向大家展示。
第一种选择是使用 strokeBorder() 在形状周围添加边框,然后使用 background() 在背景中放置填充的形状。 例如,这将创建一个带有黑色笔划和蓝色填充的圆:
Circle()
.strokeBorder(Color.black, lineWidth: 20)
.background(Circle().fill(Color.blue))
.frame(width: 150, height: 150)
使用 background() 可确保蓝色圆圈始终与红色圆圈的大小匹配。
第二个选择是使用ZStack手动将两个圆圈分层:
ZStack {
Circle()
.fill(Color.red)
Circle()
.strokeBorder(Color.black, lineWidth: 20)
}
.frame(width: 150, height: 150)
如何使用 trim() 绘制实体形状的一部分?
SwiftUI 允许我们使用其 trim() 修饰符仅绘制笔触的一部分或填充形状,该修饰符采用两个参数:起始值和终止值,都存储为 0 到 1 之间的 CGFloat。
例如,如果您想要一个半圆,则可以这样写:
Circle()
.trim(from: 0, to: 0.5)
.frame(width: 200, height: 200)
SwiftUI 绘制其形状,以使 0 度直接位于右侧,因此,如果要更改为使其直接向上0度,则应应用 rotationEffect() 修饰符。
例如,它使用计时器来调整传递给 trim() 的值,以使矩形的笔触随着时间的推移而增长,例如进度指示器:
struct ContentView: View {
@State private var completionAmount: CGFloat = 0.0
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
Rectangle()
.trim(from: 0, to: completionAmount)
.stroke(Color.red, lineWidth: 20)
.frame(width: 200, height: 200)
.rotationEffect(.degrees(-90))
.onReceive(timer) { _ in
withAnimation {
if completionAmount == 1 {
completionAmount = 0
} else {
completionAmount += 0.2
}
}
}
}
}
如何使用 VideoPlayer 播放电影?
SwiftUI 的 VideoPlayer 视图使我们可以从本地或远程的任何URL播放电影。 它来自 AVKit 框架,因此在尝试之前,请确保并添加导入 AVKit。
例如,如果您的应用程序包中包含 video.mp4 并想播放,请使用以下命令:
VideoPlayer(player: AVPlayer(url: Bundle.main.url(forResource: "video", withExtension: "mp4")!))
.frame(height: 400)
提醒:您需要将导入 AVKit 添加到 Swift 文件中才能使用它。
如果要播放远程视频,请改用其远程URL:
VideoPlayer(player: AVPlayer(url: URL(string: "https://media.w3.org/2010/05/sintel/trailer.mp4")!))
.frame(height: 400)
如果需要,可以向 VideoPlayer 初始化程序提供第二个参数,该参数添加要在视频上绘制的内容。 此内容将绘制在系统视频控件下方,但可以响应那些控件未捕获的任何事件。
例如,这会将文本“水印(Watermark)”放置在视频区域的顶部:
VideoPlayer(player: AVPlayer(url: URL(string: "https://media.w3.org/2010/05/sintel/trailer.mp4")!)) {
VStack {
Text("Watermark")
.foregroundColor(.black)
.background(Color.white.opacity(0.7))
Spacer()
}
.frame(width: 400, height: 300)
}
如何从 URL 加载远程图像?
SwiftUI 有一个专用的 AsyncImage 用于从互联网下载和显示远程图像。 以最简单的形式,您可以只传递一个 URL,如下所示:
if #available(iOS 15.0, *) {
AsyncImage(url: URL(string: "https://avatars.githubusercontent.com/u/1680273?v=4"))
} else {
// Fallback on earlier versions
}
请注意 URL 是如何可选的——如果 URL 字符串无效,AsyncImage 将只显示一个默认的灰色占位符。 如果由于某种原因无法加载图像 —— 如果用户离线,或者图像不存在——那么系统将继续显示相同的占位符图像。