Swift interactive transition - view from second view controller is flashing when cancelling the transition












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)
})

}


}










share|improve this question

























  • 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?

    – bsod
    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















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)
})

}


}










share|improve this question

























  • 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?

    – bsod
    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












0








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)
})

}


}










share|improve this question
















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)
})

}


}







swift flash transition interactive






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 18:43







Christian

















asked Nov 21 '18 at 18:20









ChristianChristian

187




187













  • 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?

    – bsod
    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



















  • 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?

    – bsod
    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

















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?

– bsod
Nov 21 '18 at 19:08





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?

– bsod
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







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





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






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418315%2fswift-interactive-transition-view-from-second-view-controller-is-flashing-when%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418315%2fswift-interactive-transition-view-from-second-view-controller-is-flashing-when%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Costa Masnaga

Fotorealismo

Sidney Franklin