UIView.transitionWithView破坏了加载器的布局。

5

我正在尝试对我的应用程序进行根视图控制器更改的动画。在交换视图控制器后,我立即加载第二个控制器所需的数据。当数据正在加载时,我会显示一个加载器(MBProgressHUD)。这是我的视图控制器交换功能:

class ViewUtils {

    class func animateRootViewController(duration: NSTimeInterval, changeToViewController: UIViewController) {
        let window = UIApplication.sharedApplication().delegate?.window?
        if window == nil {
            return
        }
        UIView.transitionWithView(window!,
            duration: duration,
            options: UIViewAnimationOptions.TransitionFlipFromLeft | UIViewAnimationOptions.AllowAnimatedContent,
            animations: {
                window!.rootViewController = changeToViewController
            },
            completion: nil
        )
    }
}

这个没问题,但是有一个问题——它会完全破坏加载器。我附上一个图片来说明发生了什么:2nd view controller 这是第二个视图控制器旋转时的情况。旋转完成后,加载器会正常出现,旋转体和文本会动画到圆角矩形的正确位置。
我真的不明白为什么会这样,请问有人能给我解释一下吗?有没有办法防止这种情况发生?
以下是我展示加载器的第二个视图控制器的代码:
override func viewDidLoad() {
    super.viewDidLoad()

    hud = HUD(containingView: view)
    hud.show()

    createBackground()
}

我的hud类:

这是我的hud类:

class HUD {

    private var hudBG: UIView!
    private var view: UIView!
    private(set) var isShown = false

    init(containingView: UIView) {
        view = containingView
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func show() {
        if !isShown {
            if(hudBG == nil) {
                hudBG = UIView(frame: CGRectMake(0, 0, view.bounds.width, view.bounds.height))
                hudBG.backgroundColor = UIColor(white: 0, alpha: 0.4)
            }
            view.addSubview(hudBG)
            let hud = MBProgressHUD.showHUDAddedTo(view, animated: true)
            hud.mode = MBProgressHUDModeIndeterminate
            hud.labelText = "Cargando"

            hudBG.alpha = 0

            UIView.animateWithDuration(0.3, animations: { () -> Void in
                self.hudBG.alpha = 1
            })
            isShown = true
        }
    }

    func hide() {
        if isShown {
            UIView.animateWithDuration(0.3, animations: {
                () -> Void in
                self.hudBG.alpha = 0
            }, completion: {
                (b) -> Void in
                self.hudBG.removeFromSuperview()
            })
            MBProgressHUD.hideHUDForView(view, animated: true)
            isShown = false
        }
    }
}

非常感谢您提供的任何想法!
2个回答

2
你正在向尚未正确初始化的视图添加hud。 如果你从xib或storyboard中加载视图控制器,那么视图及其子视图的大小与它们从接口加载时的大小相同。
必须在视图已调整为最终大小后再添加hud。
如果你移动
hud = HUD(containingView: view)
hud.show()

要查看viewDidLayoutSubviews,它应该可以正常工作。


你认为为什么在viewDidLoad中视图没有正确初始化?它已经具有正确的边界和正确的框架(例如,iP4 / S的(0.0,0.0,320.0,480.0))。正是视图控制器的旋转使其变得疯狂 - 没有过渡就没有问题。 - Fygo
你怎么知道视图的框架是正确的?你在viewDidLoad中放置了日志吗? - pteofil
可能还要看我们正在谈论的是哪个视图。这个“视图”是什么,您将hud添加到控制器的主视图还是其子视图之一?如果是主视图,我认为您应该使用self.view。 - pteofil
在viewDidLoad中,视图始终具有正确的框架。我仍然尝试了您的建议将其放置在viewDidLayoutSubviews中,但它的行为完全相同。 "view"是控制器的主视图。由于它处于相同的作用域而不是闭包内部,因此不需要self.view。 - Fygo
根据此处答案的一些用户评论:https://dev59.com/-Wsz5IYBdhLWcg3wuKQm 问题出在您更改rootViewController上。 我建议您为应用程序创建另一个RootViewController,不要对其进行任何更改。 并将当前的rootViewControlelr作为子视图控制器添加到新创建的RootViewController中。当您想要进行转换时,请在RootViewController的子视图控制器之间进行动画转换。 - pteofil
真是不可思议,最后一个链接居然有效!(我还没有检查第一个链接)。它并没有真正解释为什么会发生这种情况,所以我仍然不确定(请注意这就是我没有将其标记为正确答案的原因),但考虑到您对这个问题的关注,我认为这100分是应该的。再次感谢! - Fygo

0

我注意到在将应用从iOS 7移植到iOS 8时出现了类似的问题。在动画过程中,特别是涉及缩放时,视图位置会变形。

我很确定这是一个bug。最简单的解决方法是仅对屏幕截图或视图快照进行动画处理,而不是实际的视图 - 这需要更多的工作,并且当主要动画正在进行时,您不能让视图进行动画处理,但总体来说,这是一个更稳定的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接