I have a button embedded in a view, which is inside UIBarButtonItem. What I want to achieve is to create animation, which moves my button by certain amount to the right when I'm opening sliding menu from the left and goes back when I'm closing it.
I'm using this function to create it:
static func createMenuButton(controller:UIViewController) -> UIBarButtonItem {
let target = controller.navigationController!.parentViewController!
let menuImage = UIImage(named: "menu.png")!.imageWithRenderingMode(.AlwaysTemplate)
let menuButton = UIButton(frame: CGRectMake(0, 0, 22, 22))
menuButton.tintColor = UIColor.blackColor()
menuButton.setBackgroundImage(menuImage, forState: .Normal)
menuButton.addTarget(target, action: Selector("toggleMenuClicked:"), forControlEvents:.TouchUpInside)
let menuButtonContainer = UIView(frame: menuButton.frame)
menuButtonContainer.addSubview(menuButton)
let menuButtonItem = UIBarButtonItem(customView: menuButtonContainer)
return menuButtonItem
}
I also want to rotate it, but I've got some issues with changing 2 properties at the same time. So I've decided to make 2 separate animations (this is for opening, for closing it's the same but in opposite direction):
Translate container (translation by CGAffine didn't work properly):
UIView.animateWithDuration(0.3, animations: {
menuContainerView.frame = CGRectOffset(menuContainerView.frame, 183, 0.0)
}, completion: nil)
Rotate button inside:
UIView.animateWithDuration(0.3, animations: {
menuButton.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
}, completion: nil)
It works - in 90% cases. But sometimes - when closing - button teleports outside screen and moves towards ending point from there.
In the same time I'm also moving menu view controller from outside of the screen (the same for closing just opposite values):
UIView.animateWithDuration(0.3, animations: {
self.leftViewController!.view.frame = CGRect(x: 0, y: self.view.frame.origin.y, width: 183, height: self.view.frame.height)
}, completion: { (Bool) -> Void in
self.menuShown = true
})
I'm also changing color on navigation bar to clear color when it's opened and back to default color when it's opened.
When it breaks up it doesn't look too good. What could be the reason? How can I fix it?
I recently ran in to a similar problem with the same setup that you have described. It took me a lot to try and get it working, and it's still not 100%, but one thing that I had to do that got it working the majority of the time was creating a dispatch queue and placing your completion animations inside that queue after waiting even just 1 tenth of a second. I think it has to do with the frames not quite being set yet when the completion handler is called, even though you would think it would be, but doing this worked for me, hopefully it can help you.
completion: { (Bool) -> Void in
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.05 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
self.menuShown = true
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With