我支持iOS 13及以上版本。我希望在使用iOS 14及更高版本的设备中使用新的.toolbar
修饰符作为可选功能。我使用的是Xcode 13.0 RC 1,构建13A233,但问题也发生在Xcode 12.5.1。我创建了以下代码:
import SwiftUI
struct MyToolbar<T>: ViewModifier where T: View {
let toolbarContent: () -> T
func body(content: Content) -> some View {
if #available(iOS 14.0, *) {
content
.toolbar(content: self.toolbarContent)
}
}
}
extension View {
func myToolbar<T: View>(@ViewBuilder content: @escaping () -> T) -> some View {
self.modifier(MyToolbar(toolbarContent: content))
}
}
struct MyToolbar_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
Text("Hello, world")
.myToolbar {
if #available(iOS 14.0, *) {
Text("Hello, world!")
// ToolbarItem(placement: .bottomBar) {
// Text("Hello, world!")
// }
} else {
EmptyView()
}
}
}
}
}
我已经包含了预览位,所以上面的内容可以粘贴到任何Xcode SwiftUI项目的空文件中。它的工作原理。当我取消注释ToolbarItem
语句时,我得到以下错误:
Static method 'buildBlock' requires that 'ToolbarItem<Void, Text>' conform to 'View'
Static method 'buildLimitedAvailability' requires that 'ToolbarItem<Void, Text>' conform to 'View'
如何修复这些错误?
我认为主要问题是.toolbar
修饰符的块被定义为返回符合ToolbarContent
协议的东西。来自文档:
func toolbar<Content>(content: () -> Content) -> some View where Content : ToolbarContent
因此,在视图修饰符
中func body(content: Content) -> some View {
if #available(iOS 14.0, *) {
content
.toolbar(content: self.toolbarContent)
}
}
…你需要确保self.toolbarContent
与() -> ToolbarContent
类型签名匹配。
仅仅从扫一眼你的代码,我倾向于首先尝试将T
的一致性从T: View
更改为T: ToolbarContent
。从肉眼上看,这似乎已经足够了,但你可能需要做更多的工作来整理所有的东西。