SwiftUI:可重用 Cross-Platform(iOS 和 macOS)视图中的导航栏标题
SwiftUI: Navigation Bar Title in Reusable Cross-Platform (iOS & macOS) View
我正在尝试为框架创建可重用的 SwiftUI View
,然后可以在 iOS/iPadOS 和 macOS 上使用它。
这通常可以正常工作;但是,由于 macOS 视图没有导航栏,因此当视图包含在 macOS 目标中时,包括导航栏标题(对 iOS 很重要)会导致错误:
.navigationBarTitle(Text("Page Title"))
Value of type '...' has no member 'navigationBarTitle'
对于允许为两个平台构建相同视图的条件编译(或任何其他)方法有什么建议吗?
我最接近的如下。包括额外的 Text
视图很容易,但是因为栏标题是修饰符,在条件编译中仅包装该部分会产生其他错误:
public struct ExampleView: View {
private let pageTitle = "Page Title"
public var body: some View {
VStack(alignment: .center) {
#if os(macOS)
Text(pageTitle)
.font(.title)
#endif
Spacer()
Text("This is the view content")
Spacer()
}
#if !os(macOS)
.navigationBarTitle(Text(pageTitle))
#endif
}
}
Unexpected platform condition (expected 'os', 'arch', or 'swift')
Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
我建立了一种方法:将主要内容移动到另一个 View
属性,然后修改它以添加导航栏标题(如果需要),然后将其作为 body
返回。这样分开的时候,就可以使用条件编译了。
这有点不雅,但很管用。它还可以用于设置 macOS-specific 东西,例如视图的整体框架大小。欢迎就更好的方法提出建议!
Swift v5.1
public struct ExampleView: View {
private let pageTitle = "Page Title"
#if !os(macOS)
public var body: some View {
main.navigationBarTitle(Text(pageTitle))
}
#else
public var body: some View {
main.frame(
minWidth: 500,
minHeight: 500
)
}
#endif
public var main: some View {
VStack(alignment: .center) {
#if os(macOS)
Text(pageTitle)
.font(.title)
#endif
Spacer()
Text("This is the view content")
Spacer()
}
}
}
您可以向视图结构添加扩展。它会将条件编译放在块之外并按您预期的方式工作
#if os(macOS)
extension View {
func navigationBarTitle(_ title: Text) -> some View {
return self
}
}
#endif
我正在尝试为框架创建可重用的 SwiftUI View
,然后可以在 iOS/iPadOS 和 macOS 上使用它。
这通常可以正常工作;但是,由于 macOS 视图没有导航栏,因此当视图包含在 macOS 目标中时,包括导航栏标题(对 iOS 很重要)会导致错误:
.navigationBarTitle(Text("Page Title"))
Value of type '...' has no member 'navigationBarTitle'
对于允许为两个平台构建相同视图的条件编译(或任何其他)方法有什么建议吗?
我最接近的如下。包括额外的 Text
视图很容易,但是因为栏标题是修饰符,在条件编译中仅包装该部分会产生其他错误:
public struct ExampleView: View {
private let pageTitle = "Page Title"
public var body: some View {
VStack(alignment: .center) {
#if os(macOS)
Text(pageTitle)
.font(.title)
#endif
Spacer()
Text("This is the view content")
Spacer()
}
#if !os(macOS)
.navigationBarTitle(Text(pageTitle))
#endif
}
}
Unexpected platform condition (expected 'os', 'arch', or 'swift')
Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
我建立了一种方法:将主要内容移动到另一个 View
属性,然后修改它以添加导航栏标题(如果需要),然后将其作为 body
返回。这样分开的时候,就可以使用条件编译了。
这有点不雅,但很管用。它还可以用于设置 macOS-specific 东西,例如视图的整体框架大小。欢迎就更好的方法提出建议!
Swift v5.1
public struct ExampleView: View {
private let pageTitle = "Page Title"
#if !os(macOS)
public var body: some View {
main.navigationBarTitle(Text(pageTitle))
}
#else
public var body: some View {
main.frame(
minWidth: 500,
minHeight: 500
)
}
#endif
public var main: some View {
VStack(alignment: .center) {
#if os(macOS)
Text(pageTitle)
.font(.title)
#endif
Spacer()
Text("This is the view content")
Spacer()
}
}
}
您可以向视图结构添加扩展。它会将条件编译放在块之外并按您预期的方式工作
#if os(macOS)
extension View {
func navigationBarTitle(_ title: Text) -> some View {
return self
}
}
#endif