当前位置: 首页 > 知识库问答 >
问题:

SwuftUI性能很差,有许多矩形需要着色

周越泽
2023-03-14

我创建了一个像素一样的矩形的LazyVGrid。我想用一个延迟的颜色部分或全部,以便在填充期间执行一个simil动画,但性能非常糟糕,我认为它刷新所有的矩形每次更新。

守则

struct Pixel: Identifiable, Hashable {
    var id: Int
    var isColored: Bool
}


class Model: ObservableObject {
    
    @Published var pixels: [Pixel]
    
    init(totalPixels: Int) {
        pixels = (1...totalPixels).map{ Pixel(id: $0, isColored: false)}
    }
    
    func pixelsRange(num:Int, clusterDimension:Int) -> [Pixel]{
        return Array(pixels[(num-1)*clusterDimension..<clusterDimension*num])
    }

    func startFillingAllAnimated() {
        for idx in pixels.indices {
            let addTime = idx
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(addTime) * 0.1) {
                self.pixels[idx].isColored = true
            }
        }
    }
}
struct TotalView: View {
    
    static var totalPixels = 1280
    
    @StateObject var model = Model(totalPixels: totalPixels)
    
    var clusterDimension = 16
    
    static let bigSpacing:CGFloat = 2
    
    let bigColumns = [
        GridItem(.flexible(), spacing: bigSpacing),
        GridItem(.flexible(), spacing: bigSpacing),
        GridItem(.flexible(), spacing: bigSpacing),
        GridItem(.flexible(), spacing: bigSpacing),
        GridItem(.flexible(), spacing: bigSpacing),
        GridItem(.flexible(), spacing: bigSpacing),
        GridItem(.flexible(), spacing: bigSpacing),
        
        GridItem(.flexible(), spacing: bigSpacing)
    ]
    
    @State var numToBeColored: Int = 8
    
    var body: some View {
        
        VStack {

            Button("start") {
                model.startFillingAllAnimated()
            }
            ScrollView {
                LazyVGrid(columns: bigColumns, alignment: .center, spacing: 2){
                    ForEach(0..<TotalView.totalPixels/clusterDimension, id: \.self) { num in
                        ClusterView(pixels: $model.pixels, clusterNumber: num, clusterDimension: clusterDimension, color: .red)
                    }
                }
            }
            .padding(.horizontal, 4)
        }
        
    }
}





struct ClusterView: View {
    
    
    @Binding var pixels: [Pixel]
    let clusterNumber: Int
    let clusterDimension: Int
    let color: Color
    
    static let spacing:CGFloat = 2
    static let boxDimension:CGFloat = 9

    let columns = [
        GridItem(.fixed(boxDimension), spacing: spacing),
        GridItem(.fixed(boxDimension), spacing: spacing),
        GridItem(.fixed(boxDimension), spacing: spacing),
        GridItem(.fixed(boxDimension), spacing: spacing)
    ]

    var body: some View {
  
        LazyVGrid(columns: columns, alignment: .center, spacing: ClusterView.spacing) {
            ForEach(pixels[clusterNumber*clusterDimension..<clusterDimension*(clusterNumber+1)], id: \.self) { pixel in
                Rectangle()
                    .aspectRatio(1.0, contentMode: .fit)
                    .border(color)
                    .foregroundColor(pixel.isColored ? color:.clear)
            }
        }
        
    }
}

struct TotalView_Previews: PreviewProvider {
    static var previews: some View {
        TotalView()
    }
}

共有1个答案

常元章
2023-03-14

试着用这个来改变你的方法:

func startFillingAllAnimated() {
    DispatchQueue.global().async {
        for idx in self.pixels.indices {
            Thread.sleep(forTimeInterval: 0.03)
            DispatchQueue.main.async {
                self.pixels[idx].isColored = true
            }
        }
    }
}
 类似资料:
  • 对于我正在编写的游戏,我在非正方形地图上使用四叉树。四叉树用于查找给定最大半径(圆)内的相邻单位的冲突检测、要攻击的敌人、最近的基地等。 我想知道的是,如果将四边形树由矩形而不是正方形制成,是否存在性能问题?矩形地图不是将正方形地图划分为正方形,而是在四边形树中划分为大小相等的矩形。 矩形地图上的方形四叉树:将创建一个四叉树,填充整个地图,但左侧或底部有空白/未使用区域,具体取决于地图的方向(水平

  • 本文向大家介绍为什么Nginx的性能要比Apache高很多,包括了为什么Nginx的性能要比Apache高很多的使用技巧和注意事项,需要的朋友参考一下 为什么Nginx的性能要比Apache高很多? 这得益于Nginx使用了最新的epoll(Linux 2.6内核)和kqueue(freebsd)网络I/O模型,而Apache则使用的是传统的select模型。 目前Linux下能够承受高并发访问的

  • 问题内容: 我正在使用Hibernate 4.2,JPA 2.0和Postgres 9.2 代码卡在 在进一步调查中,我发现Hibernate调用了class 方法。此方法尝试加载有关每个数据库对象的元数据 的代码是Postgers的JDBC驱动程序的一部分,而确实是花费时间来执行该方法的驱动程序(我加载了驱动程序源并尝试了跟踪)。但是由于这个问题在Hibernate 3.3(我之前使用过)中没有

  • 我有一个Android应用程序。在启动屏幕的方法中,我添加了 因此,我希望在onCreate退出后100ms后执行该代码。 但我可以看到,我的应用程序在onCreate()之后花了3秒时间来执行延迟后的代码(在3秒之后还会出现UI): 有人能告诉我为什么一个应用程序可以在onCreate()之后花3秒来执行延迟后的代码和UI开始出现? 请建议我如何优化这一次的技巧? 还有一个问题,Handler.

  • 我有以下代码行: log4net。后勤经理。GetLogger(“m”)。调试(DateTime.Now.ToString(“hh:mm:ss.fff”)“Check-1”); 设置=会话。CreateQuery(“来自设置s”)。UniqueResult Log4net. LogManager. GetLogger("m"). Debug(DateTime. Now. ToString("hh: