在 SwiftUI 中创建 BaseView class
Creating BaseView class in SwiftUI
最近开始使用 Swiftlearning/developing 应用程序UI,构建 UI 组件似乎很容易。然而,在 SwiftUI 中努力创建一个 BaseView。我的想法是在 BaseView 中使用常见的 UI 控件,如 background 、 navigation 等,并将其他 SwiftUI 视图子类化以自动拥有基本组件。
通常您希望拥有共同的行为或共同的风格。
1) 具有共同的行为:与泛型组合
假设我们需要创建一个 BgView
,它是一个 View
,以全屏图像作为背景。我们想随时重用 BgView
。你可以这样设计这个场景:
struct BgView<Content>: View where Content: View {
private let bgImage = Image.init(systemName: "m.circle.fill")
let content: Content
var body : some View {
ZStack {
bgImage
.resizable()
.opacity(0.2)
content
}
}
}
你可以在任何需要的地方使用BgView
,你可以传递任何你想要的内容。
//1
struct ContentView: View {
var body: some View {
BgView(content: Text("Hello!"))
}
}
//2
struct ContentView: View {
var body: some View {
BgView(content:
VStack {
Text("Hello!")
Button(action: {
print("Clicked")
}) {
Text("Click me")
}
}
)
}
}
2) 有一个共同的行为:组合 @ViewBuilder 闭包
考虑到所有 SwiftUI API,这可能是 Apple 首选的处理方式。让我们尝试以这种不同的方式设计上面的示例
struct BgView<Content>: View where Content: View {
private let bgImage = Image.init(systemName: "m.circle.fill")
private let content: Content
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body : some View {
ZStack {
bgImage
.resizable()
.opacity(0.2)
content
}
}
}
struct ContentView: View {
var body: some View {
BgView {
Text("Hello!")
}
}
}
通过这种方式,您可以像使用 VStack
或 List
或其他任何方式一样使用 BgView
。
3) 要有共同的风格:创建视图修改器
struct MyButtonStyle: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color.red)
.foregroundColor(Color.white)
.font(.largeTitle)
.cornerRadius(10)
.shadow(radius: 3)
}
}
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Button(action: {
print("Button1 clicked")
}) {
Text("Button 1")
}
.modifier(MyButtonStyle())
Button(action: {
print("Button2 clicked")
}) {
Text("Button 2")
}
.modifier(MyButtonStyle())
Button(action: {
print("Button3 clicked")
}) {
Text("Button 3")
}
.modifier(MyButtonStyle())
}
}
}
这些只是示例,但通常您会发现自己使用上述设计风格之一来做事。
编辑:一个非常有用的link关于@functionBuilder(因此关于@ViewBuilder)https://blog.vihan.org/swift-function-builders/
我想到了如何在 SwiftUI 中创建一个 BaseView 以便在其他屏幕中常用
顺便说一下
步骤 .1 创建 ViewModifier
struct BaseScene: ViewModifier {
/// Scene Title
var screenTitle: String
func body(content: Content) -> some View {
VStack {
HStack {
Spacer()
Text(screenTitle)
.font(.title)
.foregroundColor(.white)
Spacer()
}.padding()
.background(Color.blue.opacity(0.8))
content
}
}
}
步骤 .2 在视图中使用该 ViewModifer
struct BaseSceneView: View {
var body: some View {
VStack {
Spacer()
Text("Home screen")
.font(.title)
Spacer()
}
.modifier(BaseScene(screenTitle: "Screen Title"))
}
}
struct BaseSceneView_Previews: PreviewProvider {
static var previews: some View {
Group {
BaseSceneView()
}
}
}
您的输出如下:
最近开始使用 Swiftlearning/developing 应用程序UI,构建 UI 组件似乎很容易。然而,在 SwiftUI 中努力创建一个 BaseView。我的想法是在 BaseView 中使用常见的 UI 控件,如 background 、 navigation 等,并将其他 SwiftUI 视图子类化以自动拥有基本组件。
通常您希望拥有共同的行为或共同的风格。
1) 具有共同的行为:与泛型组合
假设我们需要创建一个 BgView
,它是一个 View
,以全屏图像作为背景。我们想随时重用 BgView
。你可以这样设计这个场景:
struct BgView<Content>: View where Content: View {
private let bgImage = Image.init(systemName: "m.circle.fill")
let content: Content
var body : some View {
ZStack {
bgImage
.resizable()
.opacity(0.2)
content
}
}
}
你可以在任何需要的地方使用BgView
,你可以传递任何你想要的内容。
//1
struct ContentView: View {
var body: some View {
BgView(content: Text("Hello!"))
}
}
//2
struct ContentView: View {
var body: some View {
BgView(content:
VStack {
Text("Hello!")
Button(action: {
print("Clicked")
}) {
Text("Click me")
}
}
)
}
}
2) 有一个共同的行为:组合 @ViewBuilder 闭包
考虑到所有 SwiftUI API,这可能是 Apple 首选的处理方式。让我们尝试以这种不同的方式设计上面的示例
struct BgView<Content>: View where Content: View {
private let bgImage = Image.init(systemName: "m.circle.fill")
private let content: Content
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body : some View {
ZStack {
bgImage
.resizable()
.opacity(0.2)
content
}
}
}
struct ContentView: View {
var body: some View {
BgView {
Text("Hello!")
}
}
}
通过这种方式,您可以像使用 VStack
或 List
或其他任何方式一样使用 BgView
。
3) 要有共同的风格:创建视图修改器
struct MyButtonStyle: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color.red)
.foregroundColor(Color.white)
.font(.largeTitle)
.cornerRadius(10)
.shadow(radius: 3)
}
}
struct ContentView: View {
var body: some View {
VStack(spacing: 20) {
Button(action: {
print("Button1 clicked")
}) {
Text("Button 1")
}
.modifier(MyButtonStyle())
Button(action: {
print("Button2 clicked")
}) {
Text("Button 2")
}
.modifier(MyButtonStyle())
Button(action: {
print("Button3 clicked")
}) {
Text("Button 3")
}
.modifier(MyButtonStyle())
}
}
}
这些只是示例,但通常您会发现自己使用上述设计风格之一来做事。
编辑:一个非常有用的link关于@functionBuilder(因此关于@ViewBuilder)https://blog.vihan.org/swift-function-builders/
我想到了如何在 SwiftUI 中创建一个 BaseView 以便在其他屏幕中常用
顺便说一下 步骤 .1 创建 ViewModifier
struct BaseScene: ViewModifier {
/// Scene Title
var screenTitle: String
func body(content: Content) -> some View {
VStack {
HStack {
Spacer()
Text(screenTitle)
.font(.title)
.foregroundColor(.white)
Spacer()
}.padding()
.background(Color.blue.opacity(0.8))
content
}
}
}
步骤 .2 在视图中使用该 ViewModifer
struct BaseSceneView: View {
var body: some View {
VStack {
Spacer()
Text("Home screen")
.font(.title)
Spacer()
}
.modifier(BaseScene(screenTitle: "Screen Title"))
}
}
struct BaseSceneView_Previews: PreviewProvider {
static var previews: some View {
Group {
BaseSceneView()
}
}
}
您的输出如下: