SwiftUI如何存储Shape并在.contentShape中调用?
Swift 批量创建自定义点击区域按钮的问题及解决方案
问题背景
我需要创建大量点击逻辑一致,但点击区域(contentShape)不同的按钮,涵盖自定义形状和带修饰符的矩形。原本打算通过ForEach循环从外部文件传入属性批量生成按钮,其他功能都正常,唯独contentShape部分出现问题。
定义的按钮信息结构体
struct ObservableObjectButton { let tappableArea: any Shape let imageName: String let emoteName: String let message: String }
具体问题
全局的RootController类中存储了测试用的按钮实例,在视图中使用ForEach创建按钮时,调用.contentShape(button.tappableArea)会触发报错:
No exact matches in reference to static method 'buildExpression'
但如果将Shape直接定义在视图内部(类型声明为some Shape),代码就能正常运行。同时还存在以下类型相关的疑问:
- 无法将存储的Shape类型改为
some Shape或Shape,会报错:'any Shape' cannot be constructed because it has no accessible initializers - 不清楚
Shape、some Shape、any Shape、AnyShape之间的区别。
解决方案及踩坑修复
感谢timbre timbre提供的解决方案,实际实现时遇到错误:
Function declares an opaque return type 'some View', but the return statements in its body do not have matching underlying types
最终解决方法是给View扩展函数添加@ViewBuilder属性并移除return语句,修正后的代码如下:
extension View { @ViewBuilder func contentShape(_ tappableArea: TappableArea) -> some View { switch tappableArea { case let .rectangle(offset, size): self.contentShape( Rectangle() .offset(x: offset.x, y: offset.y) .size(width: size.width, height: size.height) ) // 为其他需要的形状添加对应的case分支 } } }
内容的提问来源于stack exchange,提问作者Juliana Nielson
相关产品推荐
相关产品推荐

