当 New View 出现在 Scene View App 上时被冻结
When New View appears on Scene View App is Freezed
在我的一个 iOS 应用程序开发项目中,每当我尝试在 ARSCNView 上推送视图时。该应用程序在这里冻结,下面是我的代码。如果您知道相同的情况,请提出适当的解决方案。
-> 在 sceneView
控制器
上推送视图时应用程序冻结
let session = ARSession()
var sessionConfig: ARSessionConfiguration = ARWorldTrackingSessionConfiguration()
var use3DOFTracking = false {
didSet {
if use3DOFTracking {
sessionConfig = ARSessionConfiguration()
}
sessionConfig.isLightEstimationEnabled = true
session.run(sessionConfig)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupScene()
setupSession()
}
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.tabBar.isHidden = false
session.run(sessionConfig, options: [.resetTracking, .removeExistingAnchors])
}
override func viewDidDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
session.pause()
}
func setupScene() {
sceneView.delegate = self
sceneView.session = session
sceneView.antialiasingMode = .multisampling4X
sceneView.automaticallyUpdatesLighting = false
sceneView.preferredFramesPerSecond = 60
sceneView.contentScaleFactor = 1.3
//sceneView.showsStatistics = true
enableEnvironmentMapWithIntensity(25.0)
if let camera = sceneView.pointOfView?.camera {
camera.wantsHDR = true
camera.wantsExposureAdaptation = true
camera.exposureOffset = -1
camera.minimumExposure = -1
}
}
func setupSession() {
if let worldSessionConfig = sessionConfig as? ARWorldTrackingSessionConfiguration {
worldSessionConfig.planeDetection = .horizontal
session.run(worldSessionConfig, options: [.resetTracking, .removeExistingAnchors])
}
}
在我看来,您应该具有 viewDidAppear 的覆盖功能并在那里启动您的 setupSession()。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Prevent the screen from being dimmed after a while.
UIApplication.shared.isIdleTimerDisabled = true
// Start the ARSession.
setupSession()
}
您不应出于任何原因中断 AR 会话。尝试使用弹出屏幕重新构建您的设计。
有一个 iOS 11 Beta 错误,它会在 ARSCNView 消失时冻结 ARCamera
,因此,如果您真的需要使用 AR 暂时隐藏屏幕:
- 从故事板中删除
ARSCNView
并从视图控制器中删除 IBOutlet
;
- 以编程方式创建
ARSCNView
,当 UIViewController
出现时;
- 移除
ARSCNView
,当 UIViewController 消失时。
有一个简短的例子:
class ViewController: UIViewController, ARSCNViewDelegate {
// Weak reference for scene view.
weak var sceneView: ARSCNView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a new AR Scene View.
let sceneView = ARSCNView(frame: view.bounds)
sceneView.delegate = self
sceneView.showsStatistics = true
view.addSubview(sceneView)
// Create a new scene.
sceneView.scene = SCNScene(named: "art.scnassets/ship.scn")!
// Running session.
sceneView.session.run(ARWorldTrackingSessionConfiguration())
// Saving weak reference.
self.sceneView = sceneView
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Removing current SceneView to avoid freezes.
sceneView?.removeFromSuperview()
}
}
当然,您应该根据需要检查场景视图和设置 ARSCNView
、ARSession
和 SCNScene
的框架。
Xcode 测试版 5
大部分卡顿已在 Beta 5 中得到修复。但有时它仍然会卡顿,例如当您使用本机共享视图控制器时。
在我的一个 iOS 应用程序开发项目中,每当我尝试在 ARSCNView 上推送视图时。该应用程序在这里冻结,下面是我的代码。如果您知道相同的情况,请提出适当的解决方案。
-> 在 sceneView
控制器
let session = ARSession()
var sessionConfig: ARSessionConfiguration = ARWorldTrackingSessionConfiguration()
var use3DOFTracking = false {
didSet {
if use3DOFTracking {
sessionConfig = ARSessionConfiguration()
}
sessionConfig.isLightEstimationEnabled = true
session.run(sessionConfig)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupScene()
setupSession()
}
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.tabBar.isHidden = false
session.run(sessionConfig, options: [.resetTracking, .removeExistingAnchors])
}
override func viewDidDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
session.pause()
}
func setupScene() {
sceneView.delegate = self
sceneView.session = session
sceneView.antialiasingMode = .multisampling4X
sceneView.automaticallyUpdatesLighting = false
sceneView.preferredFramesPerSecond = 60
sceneView.contentScaleFactor = 1.3
//sceneView.showsStatistics = true
enableEnvironmentMapWithIntensity(25.0)
if let camera = sceneView.pointOfView?.camera {
camera.wantsHDR = true
camera.wantsExposureAdaptation = true
camera.exposureOffset = -1
camera.minimumExposure = -1
}
}
func setupSession() {
if let worldSessionConfig = sessionConfig as? ARWorldTrackingSessionConfiguration {
worldSessionConfig.planeDetection = .horizontal
session.run(worldSessionConfig, options: [.resetTracking, .removeExistingAnchors])
}
}
在我看来,您应该具有 viewDidAppear 的覆盖功能并在那里启动您的 setupSession()。
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Prevent the screen from being dimmed after a while.
UIApplication.shared.isIdleTimerDisabled = true
// Start the ARSession.
setupSession()
}
您不应出于任何原因中断 AR 会话。尝试使用弹出屏幕重新构建您的设计。
有一个 iOS 11 Beta 错误,它会在 ARSCNView 消失时冻结 ARCamera
,因此,如果您真的需要使用 AR 暂时隐藏屏幕:
- 从故事板中删除
ARSCNView
并从视图控制器中删除IBOutlet
; - 以编程方式创建
ARSCNView
,当UIViewController
出现时; - 移除
ARSCNView
,当 UIViewController 消失时。
有一个简短的例子:
class ViewController: UIViewController, ARSCNViewDelegate {
// Weak reference for scene view.
weak var sceneView: ARSCNView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a new AR Scene View.
let sceneView = ARSCNView(frame: view.bounds)
sceneView.delegate = self
sceneView.showsStatistics = true
view.addSubview(sceneView)
// Create a new scene.
sceneView.scene = SCNScene(named: "art.scnassets/ship.scn")!
// Running session.
sceneView.session.run(ARWorldTrackingSessionConfiguration())
// Saving weak reference.
self.sceneView = sceneView
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Removing current SceneView to avoid freezes.
sceneView?.removeFromSuperview()
}
}
当然,您应该根据需要检查场景视图和设置 ARSCNView
、ARSession
和 SCNScene
的框架。
Xcode 测试版 5
大部分卡顿已在 Beta 5 中得到修复。但有时它仍然会卡顿,例如当您使用本机共享视图控制器时。