Reveal and Hide Animations
Twitter Slide Out Menu
With the menu now popping into the application's frame, we can now make it smoother by adding animations to the reveal and hide processes. This behavior might seem a little advanced, but it turns out to be quite simple with the UIView.animate(...) animator function call. When we finish the reveal and hide implementation, you'll notice that the original home controller has been polluted with a lot of unnecessary menu logic. Let's look at how we can move this code into the Menu controller where it belongs.

Comments (11)
jwaples
4 years ago
I know this is not a very important comment but I really don't think the blue controller is blue it looks like purple to me
Brian Voong
4 years ago
pawelcichonski
4 years ago
In cellForRowAt, what is the difference between using: 1) let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) //and 2) let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell") New syntax for the same thing?
Brian Voong
4 years ago
vandanpatel
4 years ago
Hi Brian, I had two questions: 1) Now that we are not removing child viewController in order to make the hide animation work, every time we tap open, it adds that childViewController. Is that a good practice? 2) In the animation closure, we are using strong self. What if that view controller gets deallocated before that code is executed? Wouldn't that crash our App? Shall we go weak-strong dance? Thanks for your amazing tutorials. I look forward to hearing from you.
rehannali
4 years ago
1) You are right about removing child view controller because we just adding it in controller again and again and not removing it. Here is the fix a swe always add it as child view controller. You have to right this animation with completion and in completion block remove it from superview as well as from parent view. 2) Well there are some rare cases when that will happen so you can use weak self. As i said it is rare and i never encounter this problem so it is up to you. Hopefully you'll get answer from Brain and may be a better one.
Brian Voong
4 years ago
vandanpatel
4 years ago
Hi Brian, Thanks a lot for your response. I understand how busy you can be. I appreciate your time.
mustii
4 years ago
Isn't it also possible to fix the issue by doing the following: UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { self.slideMenu.view.transform = .identity }) { (_) in self.slideMenu.view.removeFromSuperview() self.slideMenu.removeFromParent() }
Tube
4 years ago
Tube
4 years ago
I guess you can't use emojis in comments here. I said I'm glad you are getting around to showing us some child vc stuff!
Brian Voong
4 years ago
Tube
4 years ago
Well, I'm a little confused about the discussion below. So, are we going to create the child vc once and reuse it? Or? Also, why add the menu view to the keyWindow? Why not to the HomeVC? After all, it is the HomeVC's responsibility to place it.
Tube
4 years ago
I found out in the next video. If you don't add the menu view to keyWindow, the transform (self.view.transform = transform) doesn't work like you want.
Brian Voong
4 years ago
jefflai
4 years ago
Before getting to the question, just want to say this has been a great course so far. I actually finished this section and I'm really enjoying it. Definitely will be purchasing other courses, I love how you actually teach how to do everything programmatically! Here is the actual question, for the actual question of menuWidth fileprivate let menuWidth: CGFloat = 300 Is there a way that I can set it dependent on the view's width, instead of a set number? fileprivate let menuWidth: CGFloat = self.view.frame.width - 100 But I get an error saying that the class has no member value of view. Thank you Brian!
Brian Voong
4 years ago
lassesilk
4 years ago
Hi Brian. I have a question. I wrote the deinit func in both controllers, and a print statement to let me know when the controller gets released from memory. But it does not seem to get called at any point, even when we used the removeFromSuperView(). Do you know why it does not get called? If I keep pressing hide and open, am I just stacking up controllers in memory? Your tutorials are amazing! Thanks a lot.
stonypig1
4 years ago
just wandering if we click open side menu button x100 times, then we call addchild x100 times, but never remove it, will build up memory usage? can we call removefromparent() at the animation function completion handler to remove it every time once we done shrink back the menu ? thanks
Brian Voong
4 years ago
LucienChu
4 years ago
Hello Brian, I have a question At 19:33, you finished the animation with the slide menu. Everything was okay. I clicked the hide button, the menu was gone with animation. However, when I click the open button, the menu view was not shown up. I did a little bit debug and I found that the animation works only the first time the open button is pressed. After the menu view is hidden by pressing the hide button (it is removed from the superview and from it’s parent view with no animation implemented), if I click the open button again, the animation seems not working. First open -------------------------------------- frame 1: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) Transform with with: 331.20000000000005 frame 2: (0.0, 0.0, 331.20000000000005, 896.0) // It is transform and shown Second open -------------------------------------- frame 1: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) Transform with with: 331.20000000000005 frame 2: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) // Transformation fails since position x is not changed Third open -------------------------------------- frame 1: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) Transform with with: 331.20000000000005 frame 2: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) // Transformation fails since position x is not changed Everything works fine when the animation is also added to the hide button method -------------------------------------- frame 1: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) Transform with with: 331.20000000000005 frame 2: (0.0, 0.0, 331.20000000000005, 896.0) // It is transform and shown -------------------------------------- frame 1: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) Transform with with: 331.20000000000005 frame 2: (0.0, 0.0, 331.20000000000005, 896.0) // It is transform and shown -------------------------------------- frame 1: (-331.20000000000005, 0.0, 331.20000000000005, 896.0) Transform with with: 331.20000000000005 frame 2: (0.0, 0.0, 331.20000000000005, 896.0) // It is transform and shown To me, in the first case, since the menuViewController is removed from the superview and form its parent, each time the shown button is pressed, it should be reconstructed and add it to its parent view (illustrated by frame 1 in the first part), and the animation should be executed, however, it turns out it is not the case. Could you give me a hint why this is happening?
Brian Voong
4 years ago
LucienChu
4 years ago
Yeah, it does solved the problem. It looks like that the code menuViewController.view.removeFromSuperview() would take all the content out from the menuViewController and leave something like an empty frame over there. That's why each time I tape the button, there are correct x, y, width and height data but nothing is shown. There is literately nothing on the frame. I verified by the following steps 1. set up break point on handleOpenBtnPressed() 2. run the app 3. tap Open button, break point reached and menueView was shown normally, continue 4. tap Hide button, menuView was hidden as expected 5. tap Open button, break point reached but menuView was not shown, continue 6. tap Open button again, break point reached again. However, I did not find any official material or blog post to support my idea. Also, I agree that the menu view should not be remove from superview each time it is hidden from the user. I was too obsessive to save memory while neglect performance. Regarding to the way how swift use the view, I have more questions for that. However, i don't think I can articulate them properly now. May be later on the course. Thanks
Brian Voong
4 years ago
Joseph Fisher
4 years ago
Hey Brian, loving the course this far. Upon refactoring ViewController.swift to HomeController.swift, the contents of the file seem to disappear and the file name on left (now called HomeController.swift) is in red font. The error says the build input file cannot be found. This does make sense because when I go to the folder on my desktop where I saved the project and I look for the swift files, I still see ViewController.swift and not HomeController.swift.
Joseph Fisher
4 years ago
Brian, I just renamed the file inside of my desktop folder manually to HomeController.swift since refactoring it doesn't seem to do that for me at this moment. Now the build succeeds. Still unsure of why it was not changing the file name when it changed it everywhere else (like inside of AppDelegate.swift).
harry528tt
4 years ago
Hi Brian, with the animation block, even I commented out the addChild(menuViewController), the table view are still showing on the menu view controller. Do you know why?
HELP & SUPPORT