0

i´m trying to make my own interactive transition in swift. In my sample project I have two view controllers. With my own transition I can swipe to each other. My problem is: when swiping from the first to the second view controller the second (where I want to swipe in) view controller is appears for a millisecond on the screen, when I did cancel the transition in my pan gesture.

I tried to solve the problem by taking a snapshot from the first view controller and lay it on the transition layer when the transition cancelled. That worked on my iPhone 8, but on the iPhone XS I get the same flash for a millisecond.

The flashing only appears when I swipe very fast over the screen.

Anyone with the same problem.

PangestureHandler:

@IBAction func HandlePan(_ sender: UIPanGestureRecognizer) {
    let percentThreshold:CGFloat = 0.25

    let translation = sender.translation(in: view)
    var verticalMovement = (translation.y) / view.bounds.height
    verticalMovement = verticalMovement - verticalMovement - verticalMovement
    let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
    let downwardMovementPercent = fminf(downwardMovement, 1.0)
    let progress = CGFloat(downwardMovementPercent)

    let movementToStart: CGFloat = 0.0

    let interactor = self.interactor

    switch sender.state {
    case .began:
        print(".began")
    case .changed:
        print("progress: \(progress)")
        if progress > movementToStart && !interactor.hasStarted {
            interactor.hasStarted = true
            performSegue(withIdentifier: "segueToSecondVC", sender: nil)
            interactor.update(progress - movementToStart)
        }
        if interactor.hasStarted {
            interactor.update(progress - movementToStart)
            interactor.shouldFinish = progress > percentThreshold
        }
    case .cancelled:
        print("cancel")
        interactor.hasStarted = false
        interactor.cancel()
    case .ended:
        interactor.hasStarted = false
        if interactor.shouldFinish {
            interactor.finish()
        } else {
            interactor.cancel()
            print("interactor cancel")
        }

    default:
        break
    }
}

AnimatorClass:

import UIKit

class PresentAnimator: NSObject, UIViewControllerAnimatedTransitioning {




private var myView: UIView!

func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return 0.6

}


func animationEnded(_ transitionCompleted: Bool) {
    if !transitionCompleted {
        self.myView.alpha = 1.0
    }
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    guard let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to) else { return }
    let containerView = transitionContext.containerView


    let screenBounds = UIScreen.main.bounds
    let startPoint = CGPoint(x: 0, y: UIScreen.main.bounds.height )
    toVC.view.frame = CGRect(origin: startPoint, size: screenBounds.size)
    toVC.view.clipsToBounds = true

    self.myView = fromVC.view.snapshotView(afterScreenUpdates: false)
    containerView.addSubview(myView)
    self.myView.alpha = 0.0

    containerView.insertSubview(toVC.view, aboveSubview: fromVC.view)

    let bottomLeftCorner = CGPoint(x: 0, y: 0)
    let finalFrame = CGRect(origin: bottomLeftCorner, size: screenBounds.size)
    let duration = transitionDuration(using: transitionContext)



    UIView.animate(
        withDuration: duration, delay: 10.0, options: .curveLinear,
        animations: {
            toVC.view.frame = finalFrame
            self.myView.removeFromSuperview()
    },
        completion: { _ in
            self.myView.removeFromSuperview()
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    })

}

}

Christian
  • 75
  • 10
  • I'm confused as to what the purpose of `myView` is? You take a snapshot of the presenting view controller, add it to the container view, set its alpha to 0, and then remove it in the animation and then again after the animation. What is the thinking behind this? – trndjc Nov 21 '18 at 19:08
  • The idea was to cover the flashing by presenting myView over all layers if the transition canceled. So I set the alpha on 1 when the animationEnded fired up and it didn't complete. The flash only appears when i make a very short slide with a single tap. The progress is then at lower than 0.025xxxx – Christian Nov 21 '18 at 19:26
  • I can reproduce the same flashing effect in the latest Spotify app too. Only with my iPhone XS, not with iPhone 8. I think its a problem with only this device or with the OLED Displays. – Christian Nov 25 '18 at 10:35

0 Answers0