如何使用 SwiftUI 在我的圆段中插入 UIImages?

How can i insert UIImages in my circle segments with SwiftUI?

我在 SwiftUI 中制作了一个 circle/wheel,有 7 个片段,现在我想在每个片段(在片段的中心)中插入图像(它们在一个数组中),我该怎么做?

代码:

struct WheelShape: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        
        let pieSections = 7
        let lineWidth: CGFloat = 0.0
        
        let smaller = rect.insetBy(dx: lineWidth / 2.0, dy: lineWidth / 2.0)
        let radius = smaller.width / 2.0

        let segmentAngle = 2.0 / CGFloat(pieSections) * CGFloat(Double.pi)
        
        let imageArray: [UIImage] = [
            UIImage(systemName: "house.fill")!,
            UIImage(systemName: "paintpalette.fill")!,
            UIImage(systemName: "airplane")!,
            UIImage(systemName: "cloud.fill")!,
            UIImage(systemName: "dollarsign.circle.fill")!,
            UIImage(systemName: "book.fill")!,
            UIImage(systemName: "bicycle")!
        ]
        
        // Draw segment dividers
        for index in 1...pieSections {
            let drawAngle = segmentAngle * CGFloat(index) + (360 / 7 / 2 * π / 180)
            let x = radius * cos(drawAngle) + rect.width / 2.0
            let y = radius * sin(drawAngle) + rect.height / 2.0
            let cgpoint = CGPoint(x: rect.width / 2, y: rect.height / 2)
            path.move(to: cgpoint)
            let cgPointLine = CGPoint(x: x, y: y)
            path.addLine(to: cgPointLine)
        }
        
        return path
    }
}


这是一种将圆圈放在背景中并将 SF 符号放在叠加层中的方法。

WWDC 2019 的演示文稿展示了一圈带有动画的楔形物。这是来源: Building Custom Views in SwiftUI

struct ContentView: View {
    let symbols = ["house.fill", "paintpalette.fill", "airplane", "cloud.fill", "dollarsign.circle.fill", "book.fill", "bicycle"]
    
    var body: some View {
        WheelShape(symbols)
            .stroke(
                Color(.blue), lineWidth: 3.0)
            .background(
                Circle().stroke(Color(.blue), lineWidth: 6.0))
            .overlay(
                annotations.foregroundColor(.purple))
    }
    
    var annotations : some View {
        ZStack {
            let theta = CGFloat(2) * .pi / CGFloat(symbols.count)
            GeometryReader { geo in
                let center = CGPoint(x: geo.size.width / 2, y: geo.size.height / 2)
                let radius = min(geo.size.width / 2, geo.size.height / 2) / 1.5
                ForEach(0..<symbols.count, id: \.self) { index in
                    let offset = theta * CGFloat(index) + theta / 2
                    // place SF Symbol, offset to center, then the radius
                    Image(systemName: symbols[index])
                        .offset(x: center.x, y: center.y)
                        .offset(x: radius * cos(offset), y: radius * sin(offset))
                        .frame(alignment: .center)
                        .offset(x: -10, y: -10) // fudge factor to center symbol in wedge
                }
            }
        }
    }

    struct WheelShape: Shape {
        let symbols : [String]
        
        init(_ symbols: [String]) {
            self.symbols = symbols
        }
        
        func path(in rect: CGRect) -> Path {
            // center of the shape we are drawing in
            let center = CGPoint(x: rect.size.width / 2, y: rect.size.height / 2)
            let radius = min(rect.size.width / 2, rect.size.height / 2)
            // each angle offset in radians
            let theta = CGFloat(2) * .pi / CGFloat(symbols.count)
            var path = Path()
            
            // enumerate the array so index is available
            symbols.enumerated().forEach({ (index, symbol) in
                let offset = theta * CGFloat(index)
                path.move(to: center)
                path.addLine(to: CGPoint(x: radius * cos(offset) + center.x, y: radius * sin(offset) + center.y))
            })
            
            return path
        }
    }
}

Symbols centered in wedge