第一次点击按钮时不会播放 segue 的自定义动画

Custom animation of segue is not played the first time tapping the button

我遇到了一个异常行为,我有点卡住了,问题如下。

我正在使用 BWWalkthrough 库,以便将 4 张幻灯片作为启动屏幕。所以在我的 appdelegate 中,我有以下代码初始化 viewcontrollers:

let storyboard = UIStoryboard(name: "SlidesFlow", bundle: nil)

let walkthrough = storyboard.instantiateViewController(withIdentifier: "SlidesView") as! BWWalkthroughViewController
let page_zero = storyboard.instantiateViewController(withIdentifier: "page_1")
let page_one = storyboard.instantiateViewController(withIdentifier: "page_2")
let page_two = storyboard.instantiateViewController(withIdentifier: "page_3")
let page_three = storyboard.instantiateViewController(withIdentifier: "page_4")

walkthrough.delegate = self
walkthrough.addViewController(page_zero)
walkthrough.addViewController(page_one)
walkthrough.addViewController(page_two)
walkthrough.addViewController(page_three)

一切正常,所以没有问题。在 viewController page_three 上我有一个按钮,它使用自定义 segue 动画将我重定向到另一个视图控制器

class sentSegueFromRight: UIStoryboardSegue {

override func perform()
{
    let src = self.source as UIViewController
    let dst = self.destination as UIViewController

    src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
    dst.view.transform = CGAffineTransform(translationX: src.view.frame.size.width, y: 0)

    UIView.animate(withDuration: 0.25,
                               delay: 0.0,
                               options: UIViewAnimationOptions.curveEaseInOut,
                               animations: {
                                dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
        },
                               completion: { finished in
                                src.present(dst, animated: false, completion: nil)
        }
    )
}
}

现在的问题是,如果我在正常 viewcontroller 上使用相同的代码,按钮和动画工作没有问题。问题是当我使用上面从我的 BWWalkthrough 的最后一张幻灯片中定义的 segue 时。我第一次点击按钮时,应该出现的 viewcontroller 确实出现了,但没有相应的动画。关闭它并再次点击按钮后,播放动画但返回错误:

Presenting view controllers on detached view controllers is discouraged

如果我将按钮与标准动画一起使用(不使用我的自定义动画代码),我不会收到任何错误消息,并且会播放默认动画。

我似乎找不到解决这个问题的方法。有没有人偶然发现这样的事情?

这里的问题在于 BWWalkthrough 库,它使用滚动视图来呈现您添加的各种 ViewController 的所有视图。

因此,您将 dst.view 添加到滚动视图的开头(在偏移屏幕宽度,0 处),然后将其转换为偏移量 (0,0)。

所有这些都在屏幕外,因为您当前处于演练的第三个屏幕(偏移量为 (screenwidth*3,0))。因此,当 segue 结束时,您看不到动画并直接看到呈现的视图控制器。

要解决这个问题,请将您的 dst.view 添加到 segue 到滚动视图的超级视图中。即而不是 src.view.superview?.insertSubview(dst.view, aboveSubview: src.view) 在 segue 中写入 src.view.superview?.superview?.insertSubview(dst.view, aboveSubview: src.view)。 (假设您仅使用演练中的 segue)

如果你打算在其他地方也使用segue,那么你可以在segue中添加一个类型检查来检查src.view的superview是否是一个scrollview,如果是,添加dst.view 到滚动视图的超级视图。