Swift interactive transition - view from second view controller is flashing when cancelling the transition
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
add a comment |
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
I'm confused as to what the purpose ofmyView
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
add a comment |
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
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
swift flash transition interactive
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 ofmyView
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
add a comment |
I'm confused as to what the purpose ofmyView
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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