在 Xcode 12 中,使用 LibraryContentProvider
协议将自定义的 View
和 Modifier
添加到 Library 中。在开发过程中直接拖拽即可。
OK, 我们来看下具体是如何实现的!
自定义视图
首先创建一个内阴影 InnerShadow.swift
的 SwiftUI
文件。
具体代码:
import SwiftUI
struct InnerShadow<Content: View>: View {
let color: Color
let cornerRadius: CGFloat
let content: Content
init(color: Color = .gray, cornerRadius: CGFloat = 10, @ViewBuilder content: @escaping () -> Content) {
self.color = color
self.cornerRadius = cornerRadius
self.content = content()
}
var body: some View {
content
.overlay(
RoundedRectangle(cornerRadius: cornerRadius)
.stroke(Color.clear, lineWidth: 4)
.shadow(color: color, radius: 4, x: 4, y: 4)
.clipShape(RoundedRectangle(cornerRadius: cornerRadius))
.shadow(color: color, radius: 3, x: -3, y: -3)
.clipShape(RoundedRectangle(cornerRadius: cornerRadius))
)
}
}
struct InnerShadow_Previews: PreviewProvider {
static var previews: some View {
InnerShadow {
Text("Hello SwiftUI").padding()
.previewLayout(.fixed(width: 300, height: 300))
}
}
}
通过阴影和裁剪的组合方式实现这种效果:
添加到 Xcode Library 中
Xcode 工具栏选择 Editor -> Create Library Item
此时,当前文件底部会自动生成一个结构体:
点击去 LibraryContentProvider
看看
public protocol LibraryContentProvider {
/// description...
associatedtype ModifierBase = Any
/// description...
@LibraryContentBuilder var views: [LibraryItem] { get }
/// description...
func modifiers(base: Self.ModifierBase) -> [LibraryItem]
}
由代码可以看得出来,分别可以添加 view
和 modifier
到 Library 中。
添加 views
先来实现以 views
struct InnerShadow_LibraryContent: LibraryContentProvider {
var views: [LibraryItem] {
LibraryItem(InnerShadow(content: { }))
}
}
编译成功后,用快捷键 Command + Shift + L
打开 Xcode Library
你也可以定义 Library 的标题和分类。
struct InnerShadow_LibraryContent: LibraryContentProvider {
var views: [LibraryItem] {
LibraryItem(InnerShadow(content: { }), title: "My Inner Shadow", category: .control)
}
}
添加 modifier
- 先给
View
添加一个分类,实现InnerShadow
方法
extension View {
func innerShadow(color: Color = .gray, cornerRadius: CGFloat = 10) -> some View {
InnerShadow(color: color, cornerRadius: cornerRadius) {
self
}
}
}
- 再给
InnerShadow_LibraryContent
实现方法modifiers(base:)
这里有个泛型ModifierBase
, 意思是想给谁添加 modifier, 就写谁。 比如你想给Text
添加,你就改为Text
, 给Image
就改为Image
。我打算给所有的View
添加,所以就用了AnyView
@LibraryContentBuilder
func modifiers(base: AnyView) -> [LibraryItem] {
LibraryItem(base.innerShadow(color: .gray, cornerRadius: 10), title: "My Inner Shadow", category: .effect)
}
@LibraryContentBuilder
modifier 和 views 返回的都是 [LibraryItem],添加上 @LibraryContentBuilder 后,就相当于返回单个或者多个 Library 对象,不需要用数组包括起来了
至于为啥上面的 views 不用添加也可以,emmm....
小结
经过上面的一系列操作,你就多了一种方式来实现自定义的 View
或 Modifier
了。当然,这样也仅仅是在当前的项目中实现了,换一个项目就没了。想要在其他项目中也显示的话,你可以通过以下方式实现:
把文件拖入到新的项目中(废话)- 使用 Swift Package Manager
你可以自定义一些常用的小组件并给他们创建自定义库,打包到 SMP,上传到
Github
、Gitee
、Gitlab
。或者是放到你本地都可以。在新项目开始的时候,作为依赖集成进去。这样不失为一个很不错的方法。