使用自定义segue

时间:2015-04-26 03:32:05

标签: ios swift uistoryboardsegue

在按下按钮时实现以下交叉溶解自定义segue(在https://www.youtube.com/watch?v=xq9ZVsLNcWw处学习):

override func perform() {

    var src:UIViewController = self.sourceViewController as! UIViewController
    var dstn:UIViewController = self.destinationViewController as! UIViewController

    src.view.addSubview(dstn.view)

   dstn.view.alpha = 0

    UIView.animateWithDuration(0.75 , delay: 0.1, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: { () -> Void in


        dstn.view.alpha = 1


    }) { (finished) -> Void in

        dstn.view.removeFromSuperview()
        src.presentViewController(dstn, animated: false, completion: nil)

    }

}

我收到“不平衡调用开始/结束外观转换”警告/错误。

我已经彻底搜索了许多stackoverflow问题:

Unbalanced calls to begin/end appearance transitions for <UITabBarController: 0x197870>

  • 我的回答:我使用segue作为按钮按下而不是TabBar控制器,所以这个答案不适用

Keep getting "Unbalanced calls to begin/end appearance transitions for <ViewController>" error

  • 我的回答:我尝试了两种方法:1)所有segue用self.performseguewithidentifier以编程方式完成2)所有segue通过界面构建​​器完成,点击拖动按钮并从所选segue的属性窗格中选择我的自定义过渡。两者仍然产生了上述错误。

"Unbalanced calls to begin/end appearance transitions" warning when push a view in a modal way in XCode 4 with Storyboard

  • 我的回答:与上面相同,双重检查所有segues只能以编程方式或通过界面构建​​器执行一次,而不是两者都执行。

"Unbalanced calls to begin/end appearance transitions for DetailViewController" when pushing more than one detail view controller

  • 我的回答:我的segue中没有使用表视图控制器或导航控制器,所以这个答案不适用。

Unbalanced calls to begin/end appearance transitions for UITabBarController

  • 我的回答:我尝试让所有segues在发送中执行,如下所示

    let delay = 0.01 * Double(NSEC_PER_SEC)
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
    dispatch_after(time, dispatch_get_main_queue()) {
    
       self.performSegueWithIdentifier("toNonFBLogin", sender: nil)
    
     }
    

然而仍无济于事,警告/错误仍会弹出。

我知道错误意味着什么,它试图在前一个加载前提供一个新的viewcontroller,但不知道如何处理它。

我唯一的领先是前一个(源)视图控制器在最终视图控制器加载之前快速弹出,如0:04 at

所示。

https://youtu.be/i1D5fbcjNjY

实际上只出现了毛刺,我估计大约有5%的时间会出现故障。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

在最近的iOS版本中,看起来这种行为是一些 - 迄今为止 - 未记录的更改的结果。 对你的确切问题感到沮丧并且缺乏令人满意的答案我已经想出了这个:

// create a UIImageView containing a UIImage of `view`'s contents
func createMockView(view: UIView) -> UIImageView {
    UIGraphicsBeginImageContextWithOptions(view.frame.size, true, UIScreen.mainScreen().scale)

    view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
    let image = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()
    return UIImageView(image: image)
}

override func perform() {

   let src:UIViewController = self.sourceViewController as! UIViewController
   let dstn:UIViewController = self.destinationViewController as! UIViewController
   let mock = createMockView(dstn.view)

   src.view.addSubview(mock)
   mock.alpha = 0

   UIView.animateWithDuration(0.75, delay: 0.1, options: UIViewAnimationOptions.TransitionCrossDissolve, 
     animations: { () -> Void in
        mock.alpha = 1
     },
     completion: { (finished) -> Void in
        src.presentViewController(dstn, animated: false, completion: { mock.removeFromSuperView()})
   })
}

createMockView()将创建一个UIImageView,其中包含目标VC内容的快照,并使用它来执行过渡动画。 转换完成后,真实目的地VC将在没有动画的情况下呈现,从而导致两者之间的无缝转换。最后,一旦完成演示,就会删除模拟视图。