SwiftUI自定义toolbar修饰符使用ToolbarItem时buildBlock要求符合View协议报错如何解决
错误原因
你封装的myToolbar修饰器当前要求传入的闭包返回值遵守View协议,但ToolbarItem是专门用于工具栏的元素,仅遵守ToolbarContent协议,不遵守View协议,二者类型不匹配,因此触发编译报错。
修复步骤
- 将
MyToolbar结构体的泛型约束从T: View调整为T: ToolbarContent,匹配系统toolbar修饰器的入参类型要求 - 补全修饰器
body方法的低版本返回分支,避免iOS 13下返回值缺失的隐含问题 - 调整
View扩展中myToolbar方法的泛型约束,和修饰器保持一致
完整可运行代码
import SwiftUI struct MyToolbar<T>: ViewModifier where T: ToolbarContent { let toolbarContent: () -> T func body(content: Content) -> some View { if #available(iOS 14.0, *) { content .toolbar(content: self.toolbarContent) } else { // iOS13 不支持toolbar,直接返回原视图 content } } } extension View { // 泛型约束同步修改为ToolbarContent func myToolbar<T: ToolbarContent>(@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 { // 这里可以直接写ToolbarItem,不需要额外加版本判断,修饰器内部已经做了兼容处理 ToolbarItem(placement: .bottomBar) { Text("Hello, world!") } } } } }
调用时闭包内可以直接写任意ToolbarItem、ToolbarItemGroup等遵守ToolbarContent协议的元素,不需要额外包裹版本判断逻辑,修饰器内部已经做了系统版本兼容,iOS13下会自动忽略toolbar配置,不会产生崩溃。
内容的提问来源于stack exchange,提问作者Bart van Kuik
相关产品推荐
相关产品推荐

