Представление SwiftUI в UIHostingController некорректно отображается во время анимации кадра, если есть внутренняя анимация

#ios #swift #swiftui #uikit

#iOS #swift #swiftui #uikit

Вопрос:

При анимации изменения кадра для a UIHostingController визуализируемый View внутри не будет анимировать изменение размера, если в данный момент выполняется внутренняя анимация.

Это известная проблема или я должен делать что-то другое? Я должен представить, что это довольно распространенный вариант использования. Я тестировал это на iOS 13.3 и 14.2.

Вот снимок экрана проблемы: https://www.loom.com/share/91eb220dad244c848161330b574e22df

Обратите внимание, что вы видите желтый фон UIView во время анимации кадра, хотя вы никогда не должны его видеть. Отображаемое представление SwiftUI немедленно изменяется на конечный размер кадра и анимирует только начало координат.

 import UIKit
import SwiftUI


// When `true`, issue presents itself.
let animate = true


struct SwiftUIView: View {

    @State var appeared = false

    let animation = Animation
        .default
        .repeatForever(autoreverses: false)

    var body: some View {
        ZStack {
            Color.pink
            Image(systemName: "rays")
                .resizable()
                .frame(width: 50, height: 50)
                .rotationEffect(appeared ? .degrees(360) : .zero)
                .onAppear {
                    withAnimation(animation) {
                        if animate {
                            appeared = true
                        }
                    }
                }
        }
    }
}


class ViewController: UIViewController {

    var vc: UIViewController!

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .blue
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTap)))

        vc = UIHostingController(rootView: SwiftUIView())
        vc.view.backgroundColor = .yellow

        self.addChild(vc)
        view.addSubview(vc.view)
        vc.view.frame = CGRect(x: 50, y: 50, width: 400, height: 100)
        vc.didMove(toParent: self)
    }

    @objc private func didTap() {
        UIView.animate(withDuration: 4) {
            self.vc.view.frame = CGRect(x: 300, y: 300, width: 100, height: 400)
            self.view.layoutIfNeeded()
        }
    }
}