Reputation: 3819
I'm trying to animate 2 UIViews
, UIView1 is present, and upon a button tap, UIView2 slides from right to left and occupies the screen, moving UIView1 out of the way.
That part I am able to achieve successfully with slideLeftTransitionFromView
. However, upon a button tap again to slide UIView1 from left to right with slideRightTransitionFromView
, UIView1 somehow disappears during the animation. UIView2 does slide successfully out of the way from left to right, but I cannot see UIView1.
I'm sure slideRightTransitionFromView
follows similar logic as slideLeftTransitionFromView
, but I'm having trouble getting it working.
Here's the 2 functions:
func slideLeftTransitionFromView(view: UIView, toView: UIView, duration: NSTimeInterval, completion: ((Bool) -> Void)?)
{
if let container = view.superview
{
// Final position of outgoing view
let outgoingViewEndX = view.frame.origin.x - view.frame.size.width
// Final position of incoming view (existing frame)
let incomingViewEndX = view.frame.origin.x
// Start point of incoming view -- at the right edge of the outgoing view
let incomingViewStartX = view.frame.origin.x + view.frame.size.width
// Distance traveled by outgoing view
let outgoingDisplacement = view.frame.origin.x - outgoingViewEndX
toView.frame.origin = CGPointMake(incomingViewStartX, toView.frame.origin.y)
container.addSubview(toView)
dispatch_async(dispatch_get_main_queue(), { ()
UIView.animateWithDuration(duration, delay: 0, options: .CurveLinear, animations: {
view.frame.origin.x = outgoingViewEndX
toView.frame.origin.x = incomingViewEndX
}, completion: {(complete: Bool) in
// If the outgoing view is still in onscreen, keep sliding until it's offscreen
if outgoingViewEndX + view.frame.size.width > 0 {
// Adjust the duration for the final animation based on the distance it has to travel in order to keep the same velocity.
let finalDuration = duration * Double((outgoingViewEndX + view.frame.size.width)/outgoingDisplacement)
UIView.animateWithDuration(finalDuration, delay: 0, options: .CurveLinear, animations: {
view.frame.origin.x = -view.frame.size.width
}, completion: { (complete: Bool) in
completion?(complete)
view.removeFromSuperview()
})
}
else
{
completion?(complete)
view.removeFromSuperview()
}
})
})
}
}
func slideRightTransitionFromView(view: UIView, toView: UIView, duration: NSTimeInterval, completion: ((Bool) -> Void)?)
{
if let container = view.superview
{
// Final position of outgoing view
let outgoingViewEndX = view.frame.origin.x + view.frame.size.width
// Final position of incoming view (existing frame)
let incomingViewEndX = view.frame.origin.x
// Start point of incoming view -- at the left edge of the outgoing view
let incomingViewStartX = view.frame.origin.x - view.frame.size.width
// Distance traveled by outgoing view
let outgoingDisplacement = view.frame.origin.x + outgoingViewEndX
toView.frame.origin = CGPointMake(incomingViewStartX, toView.frame.origin.y)
container.addSubview(toView)
dispatch_async(dispatch_get_main_queue(), { ()
UIView.animateWithDuration(duration, delay: 0, options: .CurveLinear, animations: {
view.frame.origin.x = outgoingViewEndX
toView.frame.origin.x = incomingViewEndX
}, completion: {(complete: Bool) in
// If the outgoing view is still in onscreen, keep sliding until it's offscreen
if outgoingViewEndX + view.frame.size.width < 0 {
// Adjust the duration for the final animation based on the distance it has to travel in order to keep the same velocity.
let finalDuration = duration * Double((outgoingViewEndX + view.frame.size.width)/outgoingDisplacement)
UIView.animateWithDuration(finalDuration, delay: 0, options: .CurveLinear, animations: {
view.frame.origin.x = view.frame.size.width
}, completion: { (complete: Bool) in
completion?(complete)
view.removeFromSuperview()
})
}
else
{
completion?(complete)
view.removeFromSuperview()
}
})
})
}
}
It's likely something simple, but I can't see it. What seems to be the problem?
Thanks
Upvotes: 0
Views: 2009
Reputation: 21805
You have probably declared the
UIView IBOutlet
as weak var
in slideLeftTransitionFromView
calling view.removeFromSuperview()
removes the view from view heirarchy and am pretty sure your view gets deallocated since it is a weak var and not part of the layout anymore.
Therefore you dont see it when you try to add it again as subview later on. Try making the var strong reference.
Upvotes: 1