Im trying to dismiss a UIViewController with dismissViewControllerAnimated(true, completion: {}) but I get a EXC_BAD_ACCESS when trying to do it. (that is, in 1 out of 10 times its working).
I have used a custom transitionDelegate, and when Im not setting that, its working.
The ListTransitionDelegate returns animators and presentationController.
The PresentationController looks like this
init(presentingViewController: UIViewController!, presentedViewController: UIViewController!, controllerStyle: SideControllerStyle, shortest: CGFloat) {
self.controllerStyle = controllerStyle
self.shortest = shortest
super.init(presentingViewController: presentingViewController, presentedViewController: presentedViewController)
self.dimmingView.backgroundColor = UIColor.blackColor()
var tapGesture = UITapGestureRecognizer(target: self, action: Selector("closePresented"))
dimmingView.addGestureRecognizer(tapGesture)
}
override func adaptivePresentationStyle() -> UIModalPresentationStyle
{
return UIModalPresentationStyle.OverFullScreen
}
override func shouldPresentInFullscreen() -> Bool
{
return true
}
override func presentationTransitionWillBegin() {
var containerView = self.containerView
self.dimmingView.frame = self.containerView.bounds
containerView.insertSubview(self.dimmingView, atIndex:0)
presentedViewController.transitionCoordinator().animateAlongsideTransition({context in
self.dimmingView.alpha = 0.5
}, completion:nil)
}
override func presentationTransitionDidEnd(completed: Bool)
{
if !completed {
self.dimmingView.removeFromSuperview()
}
}
override func dismissalTransitionDidEnd(completed: Bool)
{
self.dimmingView.removeFromSuperview()
}
override func dismissalTransitionWillBegin() {
presentedViewController.transitionCoordinator().animateAlongsideTransition({context in
self.dimmingView.alpha = 0
}, completion: nil)
}
func closePresented() {
var presenting = self.presentingViewController
presentedViewController.dismissViewControllerAnimated(true, completion: nil)
}
override func sizeForChildContentContainer(container: UIContentContainer!, withParentContainerSize parentSize: CGSize) -> CGSize {
var size : CGSize
switch self.controllerStyle {
case .Left, .Right:
size = CGSizeMake(self.shortest, parentSize.height)
case .Bottom, .Top:
size = CGSizeMake(parentSize.width, self.shortest)
default:
size = CGSizeMake(parentSize.width, parentSize.height)
}
return size
}
override func frameOfPresentedViewInContainerView() -> CGRect {
var frame : CGRect
var size = sizeForChildContentContainer(nil, withParentContainerSize: containerView.bounds.size)
switch self.controllerStyle {
case .Left:
frame = CGRectMake(containerView.bounds.size.width - size.width, 0, size.width, size.height)
case .Right:
frame = CGRectMake(0, 0, size.width, size.height)
case .Bottom:
frame = CGRectMake(0, containerView.bounds.size.height - size.height, size.width, size.height)
case .Top:
frame = CGRectMake(0, 0, size.width, size.height)
default:
frame = CGRectMake(0, 0, size.width, size.height)
}
return frame
}
Try enabling zombie objects in your scheme settings. (Remember to turn it off when you're done because that change won't show up in your source control and you really don't want to release an app without ARC!)
If you get the error message
-[_UILayoutGuide superview]: message sent to deallocated instance 0x1781ac6a0
then just add this code to the view controller being dismissed:
deinit {
self.view.removeFromSuperview()
}
UILayoutGuide
is a private autolayout class. I believe this to be a bug (and filed it as such), since why would a dismissed view controller have any need for autolayout? Removing a class from its superview will preemptively prevent the autolayout constraints from being accessed after they've been deallocated.