4

所以我有一个视图,我正在计算一个音频文件的振幅,然后将它传递给一个视图来绘制它,它会实时变化。问题是图表在几秒钟后变得如此滞后,并且 CPU 使用率最大化,并且几乎所有类型的东西都冻结了。有没有办法在 SwiftUI macOS 中使用 GPU 而不是 CPU 来渲染视图?

我正在更新 a 中的振幅值DispatchQueue.main.async并发送一个NSNotification.

SwiftUI 图形实时更新

这是我想显示图表时调用的文件

struct TimeDomain: View {
    
    @Binding var manager: AVManager
    @State var pub = DSPNotification().publisherPath()
    @State var amps =  [Double]()
    
    var body: some View {

        AmplitudeVisualizer(amplitudes: $amps).frame(height: 300)
            .onReceive(pub) { (output) in
                self.amps = manager.amplitudes
            }
            .onAppear {
                self.amps = manager.amplitudes
            }
            .drawingGroup()
    }
}

和文件AmplitudeVisualizer.swift

struct AmplitudeVisualizer: View {
    
    @Binding var amplitudes: [Double]
    
    var body: some View {
        HStack(spacing: 0.0){
            ForEach(0..<self.amplitudes.count, id: \.self) { number in
                VerticalBar(amplitude: self.$amplitudes[number])
            }
            .drawingGroup()
        }
    }
    
}

VerticalBar.swift

/// Single bar of Amplitude Visualizer
struct VerticalBar: View {
    
    @Binding var amplitude: Double
    
        var body: some View {
            GeometryReader
                { geometry in
                ZStack(alignment: .bottom){
    
                    // Colored rectangle in back of ZStack
                    Rectangle()
                        .fill(LinearGradient(gradient: Gradient(colors: [.red, .yellow, .green]), startPoint: .top, endPoint: .center))
    
                        // blue/purple bar style - try switching this out with the .fill statement above
                        //.fill(LinearGradient(gradient: Gradient(colors: [Color.init(red: 0.0, green: 1.0, blue: 1.0), .blue, .purple]), startPoint: .top, endPoint: .bottom))
    
                    // Dynamic black mask padded from bottom in relation to the amplitude
                    Rectangle()
                        .fill(Color.black)
                        .mask(Rectangle().padding(.bottom, geometry.size.height * CGFloat(self.amplitude)))
                        .animation(.easeOut(duration: 0.05))
    
                    // White bar with slower animation for floating effect
                    Rectangle()
                        .fill(Color.white)
                        .frame(height: geometry.size.height * 0.005)
                        .offset(x: 0.0, y: -geometry.size.height * CGFloat(self.amplitude) - geometry.size.height * 0.02)
                        .animation(.easeOut(duration: 0.6))
    
                }
                .padding(geometry.size.width * 0.1)
                .border(Color.black, width: geometry.size.width * 0.1)
            }.drawingGroup()
        }
}
4

0 回答 0