SwiftUI中Symbol协议绘制问题:Oval返回UIBezierPath而非Path的解决
解决SwiftUI中Symbol协议Oval实现的类型不匹配问题
你定义了继承自Shape的Symbol协议,要求drawing方法返回SwiftUI的Path类型,Rectangle和Diamond都正常实现,但Oval里用UIBezierPath创建图形导致类型不匹配,以下是可行的解决办法:
方法1:将UIBezierPath转换为SwiftUI Path
SwiftUI的Path支持直接通过UIBezierPath实例初始化,你可以先创建UIBezierPath,再转成Path,同时把椭圆移动到指定的center位置:
struct Oval: Symbol { var numberOfSymbols: SetGame.Card.Number func drawing(_ path: Path, center: CGPoint, width: CGFloat, height: CGFloat) -> Path { // 创建基于原点的椭圆UIBezierPath let bezierPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: width, height: height)) // 转换为SwiftUI Path var ovalPath = Path(bezierPath.cgPath) // 将路径偏移到目标center位置 ovalPath = ovalPath.offsetBy(dx: center.x - width/2, dy: center.y - height/2) // 合并传入的原始路径 var combinedPath = path combinedPath.addPath(ovalPath) return combinedPath } }
方法2:直接用SwiftUI Path创建椭圆(更推荐)
没必要依赖UIKit的UIBezierPath,SwiftUI的Path本身提供了创建椭圆的方法,直接用addEllipse(in:)更贴合SwiftUI生态:
struct Oval: Symbol { var numberOfSymbols: SetGame.Card.Number func drawing(_ path: Path, center: CGPoint, width: CGFloat, height: CGFloat) -> Path { var combinedPath = path // 计算基于center居中的椭圆矩形范围 let ovalRect = CGRect( x: center.x - width/2, y: center.y - height/2, width: width, height: height ) combinedPath.addEllipse(in: ovalRect) return combinedPath } }
关于你考虑的函数重载
其实完全没必要用函数重载,协议明确要求drawing方法返回Path,重载会增加不必要的复杂度,上面两种方法都能直接满足协议要求,代码更简洁易懂。
内容的提问来源于stack exchange,提问作者cs-moushuai
相关产品推荐
相关产品推荐

