У меня есть приложение ARKit, которое отображает изображения. Они работают нормально, но если я пытаюсь использовать этот код для отображения анимированных GIF-файлов, я получаю следующие ошибки (при необходимости возможна полная трассировка стека).
[Animation] +[UIView setAnimationsEnabled:] being called from a background thread. Performing any operation from a background thread on UIView or a subclass is not supported and may result in unexpected and insidious behavior. trace=(
0 UIKitCore 0x0000000191b6cb1c D7630067-7A00-3CB7-99E1-E7F6C55D85C5 + 15252252
1 libdispatch.dylib 0x0000000102ddabd8 _dispatch_client_callout + 16
2 libdispatch.dylib 0x0000000102ddc4c8 _dispatch_once_callout + 84
3 UIKitCore 0x0000000191b6ca80 D7630067-7A00-3CB7-99E1-E7F6C55D85C5 + 15252096
4 UIKitCore 0x0000000191b6cc08 D7630067-7A00-3CB7-99E1-E7F6C55D85C5 + 15252488
...
Я не могу найти нигде, где код выбирает запуск в фоновом потоке. В моем коде addImage()
работает нормально, но addGIF()
вызывает ошибку выше. Соответствующие части моего ViewController.swift
:
import UIKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var planeDetected: UILabel!
@IBOutlet weak var sceneView: ARSCNView!
let configuration = ARWorldTrackingConfiguration()
var portalDisplayed = false
override func viewDidLoad() {
super.viewDidLoad()
self.sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]
self.configuration.planeDetection = .horizontal
self.sceneView.session.run(configuration)
self.sceneView.delegate = self
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
self.sceneView.addGestureRecognizer(tapGestureRecognizer)
}
@objc func handleTap(sender: UITapGestureRecognizer) {
guard let sceneView = sender.view as? ARSCNView else {return}
let touchLocation = sender.location(in: sceneView)
let hitTestResult = sceneView.hitTest(touchLocation, types: .existingPlaneUsingExtent)
if !hitTestResult.isEmpty {
self.addPortal(hitTestResult: hitTestResult.first!)
} else {
//
}
}
func addPortal(hitTestResult: ARHitTestResult) {
self.portalDisplayed = true
self.sceneView.debugOptions = []
let portalScene = SCNScene(named: "Portal.scnassets/Portal.scn")
let portalNode = portalScene!.rootNode.childNode(withName: "Portal", recursively: false)!
let transform = hitTestResult.worldTransform
let planeXposition = transform.columns.3.x
let planeYposition = transform.columns.3.y
let planeZposition = transform.columns.3.z
portalNode.position = SCNVector3(planeXposition, planeYposition, planeZposition)
self.sceneView.scene.rootNode.addChildNode(portalNode)
...
// Using the commented line below instead means I don't get this error!
// self.addImage(nodeName: "box", portalNode: portalNode, imageName: "image")
self.addGIF(nodeName: "box", portalNode: portalNode, imageName: "image")
}
func addImage(nodeName: String, portalNode: SCNNode, imageName: String) {
let child = portalNode.childNode(withName: nodeName, recursively: true)
child?.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "Portal.scnassets/\(imageName).jpg")
child?.renderingOrder = 300
}
func addGIF(nodeName: String, portalNode: SCNNode, imageName: String) {
let child = portalNode.childNode(withName: nodeName, recursively: true)
let gifImage = UIImage.gifImageWithName("\(imageName)")
let gifImageView = UIImageView(image: gifImage)
child?.geometry?.firstMaterial?.diffuse.contents = gifImageView
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard anchor is ARPlaneAnchor else {return}
DispatchQueue.main.async {
if self.portalDisplayed == false {
self.planeDetected.isHidden = false
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.planeDetected.isHidden = true
}
}
}
Есть ли способ предотвратить это при вызове кода по ссылке выше? Я также попробовал следующее, но я все еще получаю ту же ошибку:
DispatchQueue.main.async {
self.addGIF(nodeName: "boxBW", portalNode: portalNode, imageName: "angel")
}
Я проверил ряд поднятых проблем (таких как this ), но они не делают кажется, что отвечают на этот конкретный c вопрос.