Я пытаюсь использовать SKView
в моем интерфейсе входа для некоторых анимаций. SKView
добавляется как подпредставление к LoginContainerView
, а также к представлению, содержащему поля UITextFields и кнопку входа. Все подпредставления позиционируются с помощью автоматического размещения, а FireScene
, прикрепленный к SKView
, имеет scaleMode, установленный в .resizeFill
.
Проблема, с которой я столкнулся, очень понятна из этого клипа: https://streamable.com/5it17.
Описание клипа: всякий раз, когда я дважды нажимаю любое из полей UITextField (чтобы вызвать
Кнопка UIMenuController / Paste) FireScene
останавливается на короткое время
количество времени (но это очень заметно) и FPS падает до 30 в течение 1-2 секунд.
Единственный узел, который FireScene
добавил в качестве дочернего узла, - это модифицированный шаблон SKEmitterNode светлячков. Я совершенно уверен, что это не имеет никакого отношения к реальному коду (поскольку он очень прост и лаконичен) и, вероятно, представляет собой UIKit, смешанный с ошибкой SpriteKit.
Соответствующий код:
class FireScene: SKScene {
// MARK: - Properties
var fireSparkEmitter: SKEmitterNode? = nil
// MARK: - Inherited
override func didChangeSize(_ oldSize: CGSize) {
// position the emitter to scene's center
fireSparkEmitter?.position = CGPoint(x: size.width/2, y: size.height/2)
}
override func didMove(to view: SKView) {
if let emitter = fireSparkEmitter {
emitter.resetSimulation()
} else {
guard let emitter = SKEmitterNode(fileNamed: "FireSparks.sks") else { return }
addChild(emitter)
fireSparkEmitter = emitter
}
}
}
class LoginContainerView: UIView {
/// ...
let fireBackgroundScene: FireScene = {
let scene = FireScene(size: .zero)
scene.scaleMode = .resizeFill
return scene
}()
/// ...
// MARK: - Inherited
// called after view initialization
func setupSubviews() {
let skView = SKView(frame: .zero)
skView.translatesAutoresizingMaskIntoConstraints = false
addSubview(skView)
skView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
skView.topAnchor.constraint(equalTo: topAnchor).isActive = true
skView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
skView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
skView.showsFPS = true
skView.presentScene(fireBackgroundScene)
}
}
PS: я попытался профилировать приложение с помощью Time Profiler, и кажется, что узким местом является обработка жестов UITextField самой UIKit.