1、SWiftUI更新UIKit 上的数据

实现场景: 我要通过SWiftUI上的一个列表的三个框框里面实现动画,并且他们之间有相互转换的场景动销

  1. 涉及到动效播放, 这里使用了qvga 播放器

  2. 因为qvga,目前是UIkit实现的第三方库, 而我们要实现这个功能,就需要将SWiftUI上的数据变化传递到UIkit中,这里就使用到了SWiftUI和UIKit之间的桥接Representable

  3. 因为有数据更新: 通过SWiftUI的数据更新到UIkit,因为SWiftUI是声明式,而UIkit常间的过程式,所以,需要使用Coordinantor来更新数据出发方法

代码如下

SwiftUI 端口

class WARankDataViewModel: ObservableObject {
    @Published var lefts: [String] = []
    @Published var rightTops: [String] = []
    @Published var rightBottoms: [String] = []
    @Published var currentState: Bool = false

    private var vm: WAMainRoomViewModel
    private var timer: Timer?

    init(vm: WAMainRoomViewModel) {
        self.vm = vm
        setupInitialData()
        startTimer()
    }

    private func setupInitialData() {
        if let rankData = vm.rankData {
            lefts.append(contentsOf: rankData.wealthRatingingUtilizerPictureList ?? [])
            lefts.append(contentsOf: rankData.charmRatingingUtilizerPictureList ?? [])

            rightTops.append(contentsOf: rankData.charmRatingingUtilizerPictureList ?? [])
            rightTops.append(contentsOf: rankData.spaceRatingingBgList ?? [])

            rightBottoms.append(contentsOf: rankData.spaceRatingingBgList ?? [])
            rightBottoms.append(contentsOf: rankData.wealthRatingingUtilizerPictureList ?? [])
        }
    }

    private func startTimer() {
        if timer == nil {
            timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { [weak self] _ in
                self?.updateData()
            }
        }
    }

// 通过定时器更新数据
    private func updateData() {
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            let tempLeft = self.lefts
            let tmpRightTop = self.rightTops
            let tmpRightBottom = self.rightBottoms
            
            self.lefts = Array(tmpRightTop)
            self.rightTops = Array(tmpRightBottom)
            self.rightBottoms = Array(tempLeft)

//            print("Updated data on main thread: \(self.lefts), \(self.rightTops), \(self.rightBottoms)")
//            print("Updated data on main thread: left first \(self.lefts.first!) ")
//            print("Updated data on main thread: top first \(self.rightTops.first!) ")
//            print("Updated data on main thread: bottom first \(self.rightBottoms.first!) ")
            self.currentState = !self.currentState
        }
    }

    deinit {
        timer?.invalidate()
        timer = nil
    }
}

struct WAKingKongView: View {
    
    @ObservedObject var vm: WAMainRoomViewModel
    @StateObject private var animateVM: WARankDataViewModel
    @State private var currentState: Bool = false // 主要通过这个来更新,因为数据可能会不变
    
    init(vm: WAMainRoomViewModel) {
        self.vm = vm
       _animateVM = StateObject(wrappedValue: WARankDataViewModel(vm: vm))
    }

    var body: some View {
        GeometryReader { proxy in
            HStack(spacing: 12~){
                WAHWDMP4PlayerView(sources: animateVM.lefts, currentState: animateVM.currentState)
                    .frame(width: (proxy.size.width - 12~)/2.0, height: proxy.size.height)
                    .background(Color.randomColor())
                    .cornerRadius(8~)
                VStack(spacing: 12~) {
                    WAHWDMP4PlayerView(
                        sources: animateVM.rightTops,
                        currentState: animateVM.currentState
                    )
                        .frame(width: (proxy.size.width - 12~)/2.0, height: (proxy.size.height - 12~)/2.0)
                        .background(Color.randomColor())
                        .cornerRadius(8~)
                    WAHWDMP4PlayerView(
                        sources: animateVM.rightBottoms,
                        currentState: animateVM.currentState
                    )
                        .frame(width: (proxy.size.width - 12~)/2.0, height: (proxy.size.height - 12~)/2.0)
                        .background(Color.randomColor())
                        .cornerRadius(8~)
                }
            }
        }
    }
}

Last updated