0

I have a custom transition event going on with my view controllers where view controller a (VC_A) will present (VC_B).

Now when doing the transition, VC_A will still exist, but VC_B will not receive any touch events. Now if I remove the view from VC_A, VC_B will get touch events. I am not sure what I am missing in my transition that tells the app to be sending all touch events to VC_B not VC_A. I have tried setting the first responder, but that did not work, if somebody could tell me what I am missing, it would be appreciated.

//
//  AnimationController.swift
//  MarineWars
//
//      Created by Anthony Randazzo on 5/6/15.
//  Copyright (c) 2015 Anthony Randazzo. All rights reserved.
//

import Foundation
import UIKit


class TransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return AnimationController(transitionType: .Presenting)
}

func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return AnimationController(transitionType: .Dismissing)
}
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?
{
    return nil;
}
}

private var inSuperView : UIView?;
private var toSuperView : UIView?;

class AnimationController: NSObject,     UIViewControllerAnimatedTransitioning {

enum TransitionType {
    case Presenting
    case Dismissing
}

var animationTransitionOptions: UIViewAnimationOptions
var inView   : UIView?;
var toView   : UIView?;
var fromView : UIView?;

init(transitionType: TransitionType) {
    switch transitionType {
    case .Presenting:
        animationTransitionOptions = .TransitionFlipFromLeft
    case .Dismissing:
        animationTransitionOptions = .TransitionFlipFromRight
    }

    super.init()

}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    inView   = transitionContext.containerView()
    toView   = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)?.view    // if iOS 8 only, I'd use `viewForKey`, instead
    fromView = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)?.view
    if(animationTransitionOptions == .TransitionFlipFromLeft)
    {
    NSTimer.scheduledTimerWithTimeInterval(transitionDuration(transitionContext)/2, target: self, selector: Selector("fireHalfwayIn"), userInfo: nil, repeats: false);
    }
    else if(animationTransitionOptions == .TransitionFlipFromRight)
    {
        NSTimer.scheduledTimerWithTimeInterval(transitionDuration(transitionContext)/2, target: self, selector: Selector("fireHalfwayOut"), userInfo: nil, repeats: false);
    }
    var scene = GameScene.instance;
    scene!.paused = false;
    scene!.view?.paused = false;
    UIView.transitionFromView(fromView!, toView: toView!, duration: transitionDuration(transitionContext), options: animationTransitionOptions | .CurveEaseInOut | .AllowAnimatedContent) { finished in

        transitionContext.completeTransition(true)
        NSNotificationCenter.defaultCenter().postNotificationName("DropNotifications",object:nil);

        //inSuperView is our parent

        if(inSuperView == nil)
        {
            inSuperView = self.fromView;
            println(self.fromView);
            for view in self.fromView!.subviews
            {
                for subview in view.subviews
                {
                    if(subview.isMemberOfClass(GameSceneView))
                    {
                        self.fromView!.resignFirstResponder()
                        self.toView!.becomeFirstResponder();
                        (subview as! GameSceneView).removeScene();
                        return;
                    }
                }

               if(view.isMemberOfClass(GameSceneView))
                {
                    self.fromView!.resignFirstResponder()
                    self.toView!.becomeFirstResponder();
                    (view as! GameSceneView).removeScene();
                    return;
                }
            }


        }
        else
        {
            for view in self.toView!.subviews
            {
                for subview in view.subviews
                {
                    if(subview.isMemberOfClass(GameSceneView))
                    {
                        (subview as! GameSceneView).createScene();
                        break;
                    }
                }
            }
        }

    }
}

func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
    return 1.0
}
func fireHalfwayIn()
{
    //println("\nFire In\n");
    var scene = GameScene.instance;
    //scene!.paused = false;
    if(scene!.player.grid.parent != nil)
    {
        scene!.currentPlayer = scene!.enemy;

        scene!.player.grid.removeFromParent();
        scene!.addChild(scene!.enemy.grid);
        var player = scene!.currentPlayer;



        player!.grid.position = GameScene.fixPositionOnScreen(CGPointMake(toView!.frame.width/2 - player!.gridSize.width/2, toView!.frame.height/2 - player!.gridSize.height/2),currentPlayer: player!);

    }
}
func fireHalfwayOut()
{
   // println("\nFire Out\n");
    var scene = GameScene.instance;
    if(scene!.enemy.grid.parent != nil)
    {
        scene!.enemy.grid.removeFromParent();
        scene!.currentPlayer = scene!.player;

        scene!.addChild(scene!.player.grid);

    }

}

}
Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • Can you post some code for your custom transition? I remember having a similar problem where I wasn't calling `completeTransition(_:)` on my transition context (`UIViewControllerContextTransitioning`). – Patrick Lynch Jul 11 '15 at 19:29
  • ok I cleaned up the class a bit and posted it, hope it helps. – Knight0fDragon Jul 11 '15 at 19:40
  • http://stackoverflow.com/questions/22300050/touches-not-recognized-after-custom-transition is a similar problem, but of course, that answer is not an acceptable answer for me, I prefer to keep the view loaded for what I am doing. – Knight0fDragon Jul 11 '15 at 22:06
  • Perhaps another acceptable alternative would be to figure out a nice and easy way for the view to be reloaded when I am transitioning back. Here is where my problem lies, sometimes I want to transition back, sometimes I want to just skip the transition so that I can go up to the parent view controller. To not get the warning that the view is not in the hierarchy why I am dismissing VC_A, it has to be in the hierarchy, obviously, so that is why I can not just remove it, and I am not looking for a dirty workaround that will only work in 1 scenario, I am looking for a more portable way – Knight0fDragon Jul 11 '15 at 22:18

1 Answers1

0

OK I found the problem, I need to add the view to the content subview

    if(self.presenting)
    {
        self.inView!.addSubview(self.toView!);
    }

This of course leads to a bug when a context is completed, removing the from view from the key window.

So I needed to add this line after the context completed:

    UIApplication.sharedApplication().keyWindow!.addSubview(self.toView!);

to get it to properly work

Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44