-
Notifications
You must be signed in to change notification settings - Fork 87
Description
当我第一次初始化的时候点击确定会报错并崩溃,但是当我切换了changeStateMachine过后再点击确定就不会崩溃
Can't show file for stack frame : <DBGLLDBStackFrame: 0x10c767ca0> - stackNumber:7 - name:RiveView.advance(delta:). The file path does not exist on the file system: /Users/admin/actions-runner/_work/rive-ios/rive-ios/Source/RiveView.swift
Can't show file for stack frame : <DBGLLDBStackFrame: 0x3daeb9c70> - stackNumber:7 - name:RiveView.advance(delta:). The file path does not exist on the file system: /Users/admin/actions-runner/_work/rive-ios/rive-ios/Source/RiveView.swiftCan't show file for stack frame : <DBGLLDBStackFrame: 0x3daeb9c70> - stackNumber:7 - name:RiveView.advance(delta:). The file path does not exist on the file system: /Users/admin/actions-runner/_work/rive-ios/rive-ios/Source/RiveView.swiftMessage from debugger: killed
以下是我的代码,请问是我的初始化问题了
import Foundation
import UIKit
import RiveRuntime
class vc: UIViewController {
private lazy var creatBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .green
btn.setTitle("创建", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var cleanBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .red
btn.setTitle("清除", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var changeStateMachineBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .orange
btn.setTitle("更换stateMachine", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var changeTriggerBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .purple
btn.setTitle("更换trigger", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var triggerGoOnBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .blue
btn.setTitle("go on", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var triggerStopBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .yellow
btn.setTitle("stop", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var showBallBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .brown
btn.setTitle("显示", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var hidBallBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .cyan
btn.setTitle("隐藏", for: .normal)
btn.setTitleColor(.black, for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 18)
return btn
}()
private lazy var contentView: UIView = {
let view = UIView()
return view
}()
private var riveViewModel: RiveViewModel?
private(set) var dataBindingInstance: RiveDataBindingViewModel.Instance?
private var rivName : [String] = ["change_style(1)"]
private var stateMachineNames : [String] = []
private var inputNames : [String] = []
private var ballList : [String] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
var strcard:String = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = .white
self.view.addSubview(self.creatBtn)
self.view.addSubview(self.cleanBtn)
self.view.addSubview(self.changeStateMachineBtn)
self.view.addSubview(self.changeTriggerBtn)
self.view.addSubview(self.triggerGoOnBtn)
self.view.addSubview(self.triggerStopBtn)
self.view.addSubview(self.showBallBtn)
self.view.addSubview(self.hidBallBtn)
self.view.addSubview(self.contentView)
let viewWidth : CGFloat = self.view.frame.size.width
let viewHeight : CGFloat = self.view.frame.size.height
let x_padding : CGFloat = 15
let y_padding : CGFloat = 15
let btnWidth : CGFloat = viewWidth/2.0 - x_padding*2
let btnHeight : CGFloat = 50
self.creatBtn.frame = CGRect(x: x_padding, y: 110, width: btnWidth, height: btnHeight)
self.cleanBtn.frame = CGRect(x: viewWidth/2.0 + x_padding, y: 110, width: btnWidth, height: btnHeight)
self.changeStateMachineBtn.frame = CGRect(x: x_padding, y: self.creatBtn.frame.maxY + y_padding, width: btnWidth, height: btnHeight)
self.changeTriggerBtn.frame = CGRect(x: viewWidth/2.0 + x_padding, y: self.creatBtn.frame.maxY + y_padding, width: btnWidth, height: btnHeight)
self.triggerGoOnBtn.frame = CGRect(x: x_padding, y: self.changeStateMachineBtn.frame.maxY + y_padding, width: btnWidth, height: btnHeight)
self.triggerStopBtn.frame = CGRect(x: viewWidth/2.0 + x_padding, y: self.changeStateMachineBtn.frame.maxY + y_padding, width: btnWidth, height: btnHeight)
self.showBallBtn.frame = CGRect(x: x_padding, y: self.triggerGoOnBtn.frame.maxY + y_padding, width: btnWidth, height: btnHeight)
self.hidBallBtn.frame = CGRect(x: viewWidth/2.0 + x_padding, y: self.triggerGoOnBtn.frame.maxY + y_padding, width: btnWidth, height: btnHeight)
self.contentView.frame = CGRect(x: 0, y: self.showBallBtn.frame.maxY + y_padding, width: viewWidth , height: viewHeight - (self.showBallBtn.frame.maxY + y_padding))
self.creatBtn.addTarget(self, action: #selector(creatBtnClick), for: .touchUpInside)
self.cleanBtn.addTarget(self, action: #selector(cleanBtnClick), for: .touchUpInside)
self.changeStateMachineBtn.addTarget(self, action: #selector(changeStateMachineBtnClick), for: .touchUpInside)
self.changeTriggerBtn.addTarget(self, action: #selector(changeTriggerBtnClick), for: .touchUpInside)
self.triggerGoOnBtn.addTarget(self, action: #selector(triggerGoOnBtnClick), for: .touchUpInside)
self.triggerStopBtn.addTarget(self, action: #selector(triggerStopBtnClick), for: .touchUpInside)
self.showBallBtn.addTarget(self, action: #selector(showBallBtnClick), for: .touchUpInside)
self.hidBallBtn.addTarget(self, action: #selector(hidBallBtnClick), for: .touchUpInside)
}
@objc private func creatBtnClick() {
// 指定对应的Artboard
self.riveViewModel = RiveViewModel(fileName:"change_style(1)")
self.riveViewModel?.reset()
if let riveView = self.riveViewModel?.createRiveView() {
self.contentView.addSubview(riveView)
riveView.frame = self.contentView.bounds
riveView.backgroundColor = .clear
riveView.stateMachineDelegate = self
if let riveModel = self.riveViewModel?.riveModel {
if let artboard = riveModel.artboard {
MSLog(artboard.name())
self.stateMachineNames = artboard.stateMachineNames()
do {
try riveModel.setStateMachine("3")
} catch {
MSLog(error.localizedDescription)
}
self.riveViewModel?.play(loop: .oneShot)
MSLog("当前文件全部状态机")
MSLog("artboard.stateMachineNames() = \(artboard.stateMachineNames())")
}
riveModel.enableAutoBind { [weak self] instance in
guard let strongSelf = self else { return }
strongSelf.dataBindingInstance = instance
}
guard let binding = self.dataBindingInstance else { return }
print("instance--\(binding.name)")
}
}
}
@objc private func cleanBtnClick() {
self.stateMachineNames = []
self.inputNames = []
self.riveViewModel?.stop()
self.riveViewModel?.riveView?.removeFromSuperview()
self.riveViewModel = nil
}
@objc private func changeStateMachineBtnClick() {
let alertController = UIAlertController(title: "切换动画", message: "选择stateMachine", preferredStyle: UIAlertController.Style.alert)
self.stateMachineNames.forEach { name in
alertController.addAction(UIAlertAction(title: name, style: .default, handler: { _ in
if let riveModel = self.riveViewModel?.riveModel {
self.riveViewModel?.reset()
do {
try riveModel.setStateMachine(name)
} catch {
MSLog(error.localizedDescription)
}
if let stateMachine = riveModel.stateMachine {
self.inputNames = stateMachine.inputNames()
MSLog("当前状态机全部-stateMachine.inputNames() = \(stateMachine.inputNames())")
}
self.riveViewModel?.play(loop: .oneShot)
}
}))
}
alertController.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil))
self.present(alertController, animated: true)
}
@objc private func changeTriggerBtnClick() {
let alertController = UIAlertController(title: "切换动画", message: "选择trigger", preferredStyle: UIAlertController.Style.alert)
self.inputNames.reversed().forEach { name in
alertController.addAction(UIAlertAction(title: name, style: .default, handler: { _ in
self.riveViewModel?.triggerInput(name)
}))
}
alertController.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil))
self.present(alertController, animated: true)
}
@objc private func triggerGoOnBtnClick() {
// self.riveViewModel?.triggerInput("go on")
guard let inst = self.dataBindingInstance,
let t = inst.triggerProperty(fromPath: "go on") else { return }
t.trigger()
}
@objc private func triggerStopBtnClick() {
// self.riveViewModel?.triggerInput("stop")
guard let inst = self.dataBindingInstance,
let t = inst.triggerProperty(fromPath: "stop") else { return }
t.trigger()
}
@objc private func showBallBtnClick() {
guard let binding = self.dataBindingInstance else { return }
let alertController = UIAlertController(title: "选择并显示球", message: "", preferredStyle: UIAlertController.Style.alert)
self.ballList.reversed().forEach { name in
alertController.addAction(UIAlertAction(title: name, style: .default, handler: { _ in
if let ball = binding.triggerProperty(fromPath: "ball \(name) on") {
ball.trigger()
self.riveViewModel?.triggerInput("AR \(name) on")
self.riveViewModel?.triggerInput("reset")
}
}))
}
alertController.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil))
self.present(alertController, animated: true)
}
@objc private func hidBallBtnClick() {
guard let binding = self.dataBindingInstance else { return }
let alertController = UIAlertController(title: "选择并显示球", message: "", preferredStyle: UIAlertController.Style.alert)
self.ballList.reversed().forEach { name in
alertController.addAction(UIAlertAction(title: name, style: .default, handler: { _ in
if let ball = binding.triggerProperty(fromPath: "ball \(name) off") {
ball.trigger()
self.riveViewModel?.triggerInput("AR \(name) off")
self.riveViewModel?.triggerInput("reset")
}
}))
}
alertController.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil))
self.present(alertController, animated: true)
}
}
extension vc: RivePlayerDelegate {
func player(playedWithModel riveModel: RiveRuntime.RiveModel?) {
print("playedWithModel")
}
func player(pausedWithModel riveModel: RiveRuntime.RiveModel?) {
print("pausedWithModel")
}
func player(loopedWithModel riveModel: RiveRuntime.RiveModel?, type: Int) {
print("loopedWithModel.type = \(type)")
}
func player(stoppedWithModel riveModel: RiveRuntime.RiveModel?) {
print("stoppedWithModel")
}
func player(didAdvanceby seconds: Double, riveModel: RiveRuntime.RiveModel?) {
// print("didAdvanceby.seconds = \(seconds)")
}
}
private let selectable = [1, 2, 3, 4]
extension vc: RiveStateMachineDelegate {
func touchBegan(onArtboard artboard: RiveArtboard?, atLocation location: CGPoint) {
print("touchBegan(onArtboard")
}
func touchMoved(onArtboard artboard: RiveArtboard?, atLocation location: CGPoint) {
print("touchMoved(onArtboard")
}
func touchEnded(onArtboard artboard: RiveArtboard?, atLocation location: CGPoint) {
print("touchEnded(onArtboard")
}
func touchCancelled(onArtboard artboard: RiveArtboard?, atLocation location: CGPoint) {
print("touchCancelled(onArtboard")
}
func stateMachine(_ stateMachine: RiveStateMachineInstance, receivedInput input: RiveRuntime.StateMachineInput) {
print("stateMachine - stateMachine = \(stateMachine.name()) - receivedInput input = \(input.name)")
}
func stateMachine(_ stateMachine: RiveStateMachineInstance, didChangeState stateName: String) {
// MSLog("stateMachine - stateMachine = \(stateMachine.name()) - didChangeState stateName = \(stateName)")
print("-----------\(stateName)")
print("---\(stateMachine.name())")
// 动画在此结束
if stateName == "ExitState" {
}
}
func stateMachine(_ stateMachine: RiveStateMachineInstance, didReceiveHitResult hitResult: RiveHitResult, from event: RiveRuntime.RiveTouchEvent) {
}
func trigger(_ path: String, in instance: RiveDataBindingViewModel.Instance?) -> Bool {
guard let prop = instance?.triggerProperty(fromPath: path) else {
print("⚠️ triggerProperty not found: \(path)")
return false
}
prop.trigger()
print("✅ triggered: \(path)")
return true
}
private func handleSubmit() {
guard let sel = Int(strcard), selectable.contains(sel) else {
print("❌ 未选中有效编号:\(strcard)")
return
}
guard let instance = self.dataBindingInstance else { return }
// 1) 选中项触发 `_y`
self.trigger("\(sel)_y", in: instance) // ← 只走一种触发通道
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 0.5) {
// 2) 其余触发 `_n`
for i in selectable where i != sel {
self.trigger("\(i)_n", in: instance)
}
}
// 3) 如需 reset,建议稍微延迟一下,避免和上一帧冲突
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
}
}
// 放到类里:一个“安全修改 Rive 状态”的小助手
private func safeRiveMutation(after delay: TimeInterval = 0, _ block: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
guard let self = self, let v = self.riveViewModel?.riveView else { return }
let wasPaused = v.isPaused
v.isPaused = true // 冻结一帧,避免在 advance/apply 过程中重入
block()
// 下一轮 runloop 再恢复,确保不在同一 CADisplayLink tick 内
DispatchQueue.main.async { v.isPaused = wasPaused }
}
}
func onRiveEventReceived(onRiveEvent e: RiveEvent) {
let name = e.name()
print("touch: \(name)")
switch name {
case "1","2","3","4":
self.strcard = name
print("11111----\(name)")
case "submit":
handleSubmit()
default:
break
}
}
}