import SwiftUI
// โญ๏ธ Shape is Sendable
struct MyAnyShape: Shape {
// โญ๏ธ properties must be Sendable too.
private let shape: (CGRect) -> Path // ๐ error
init<S: Shape>(_ wrapped: S) {
self.shape = { rect in
wrapped.path(in: rect)
}
}
func path(in rect: CGRect) -> Path {
shape(rect)
}
}
ๆนๆกไธ๏ผ็ดๆฅๅฒๅญ Shape ๅฏฆไพ(wrappedShape
)๏ผ่ไธๆฏ้ๅ
(closure)๏ผๅฎๅ
จ้ฟ้ Sendable ็ๅ้กใ้ๆจฃ็ๅฏซๆณๅ
ทๆ่ผๅคง็้ๆดปๆง๏ผๅฆๆไฝ ๆๅพๅค็จฎ้ก็ Shape๏ผๅปบ่ญฐ็จๆญคๅฏซๆณใ
import SwiftUI
struct MyAnyShape: Shape {
// โญ๏ธ ็ดๆฅๅฒๅญ Shape ๅฏฆไพ
private var wrappedShape: any Shape
init<S: Shape>(_ wrapped: S) {
self.wrappedShape = wrapped
}
func path(in rect: CGRect) -> Path {
wrappedShape.path(in: rect)
}
}
ๆนๆกไบ๏ผๅฆๆ Shape ้กๅๆ้๏ผๅฏ็จ enum ไพๅๅไธๅ็ๅฝข็๏ผ
import SwiftUI
// โญ๏ธ ็ดๆฅ็จ enum ็ฎก็ๅฝข็๏ผไธ้็จๆณๅๆ้ๅ
enum MyShape: Shape {
case circle
case roundedRectangle(cornerSize: CGSize)
// โญ๏ธ Shape requirement
func path(in rect: CGRect) -> Path {
switch self {
case .circle:
return Circle().path(in: rect)
case .roundedRectangle(let cornerSize):
return RoundedRectangle(cornerSize: cornerSize).path(in: rect)
}
}
}
๐ ๆ็จ๏ผ view.clipShape()
ๆนๆกไธ๏ผๅฐ MyAnyShape
ๆ็ขบๆจ่จ็บไธ้็ฌฆๅ Sendable
ใ้ฉๅ็ๆ Swift Concurrency๏ผไธ็ขบ่ช็จๅผ้่ผฏๆฏ thread-safe ๆไฝฟ็จใ
import SwiftUI
struct MyAnyShape: Shape {
// โญ๏ธ ไธ็ฌฆๅ Sendable ็ๅฑฌๆง
private let shape: (CGRect) -> Path
init<S: Shape>(_ wrapped: S) {
self.shape = { rect in
wrapped.path(in: rect)
}
}
func path(in rect: CGRect) -> Path {
shape(rect)
}
}
// โญ๏ธ ๆทปๅ @unchecked Sendable ไปฅ้ฟๅ
Sendable ้ฏ่ชค
extension MyAnyShape: @unchecked Sendable {}
๐
ฟ๏ธ Shape๏ผ must be Sendable.