Note: I’ve already checked the following stack overflow issues:
27907570, 32229252, 26118141, 31604300
All I am trying to do is fade animate in a view (by alpha) when called by an IBAction attached to a button. Then reverse when a button on the view is hit.
My wrinkle may be that I'm using a secondary view that is on the ViewDock in the storyboard View. The view is added to the subview at the time of viewDidLoad where the frame/bounds are set to the same as the superview (for a full layover)
The reason this is done as an overlay view since it is a tutorial indicator.
The result (like many others who've listed this problem) is that the view (and contained controls) simply appears instantly and disappears as instantly. No fade.
I have tried animationWithDuration with delay, with and without completion, with transition, and even started with the old UIView.beginAnimations.
Nothing is working. Suggestions warmly welcomed.
The code is about as straight forward as I can make it:
Edit: Expanded the code to everything relevant
Edit2: TL;DR Everything works with the exception of UIViewAnimateWithDuration which seems to ignore the block and duration and just run the code inline as an immediate UI change. Solving this gets the bounty
@IBOutlet var infoDetailView: UIView! // Connected to the view in the SceneDock override func viewDidLoad() { super.viewDidLoad() // Cut other vDL code that isn't relevant setupInfoView() } func setupInfoView() { infoDetailView.alpha = 0.0 view.addSubview(infoDetailView) updateInfoViewRect(infoDetailView.superview!.bounds.size) } func updateInfoViewRect(size:CGSize) { let viewRect = CGRect(origin: CGPointZero, size: size) infoDetailView.frame = viewRect infoDetailView.bounds = viewRect infoDetailView.layoutIfNeeded() infoDetailView.setNeedsDisplay() } override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) updateInfoViewRect(size) } func hideInfoView() { AFLog.enter(thisClass) UIView.animateWithDuration( 2.0, animations: { self.infoDetailView.alpha = 0.0 }, completion: { (finished) in return true } ) AFLog.exit(thisClass) } func showInfoView() { AFLog.enter(thisClass) UIView.animateWithDuration( 2.0, animations: { self.infoDetailView.alpha = 0.75 }, completion: { (finished) in return true } ) AFLog.exit(thisClass) } // MARK: - IBActions @IBAction func openInfoView(sender: UIButton) { showInfoView() } @IBAction func closeInfoView(sender: UIButton) { hideInfoView() }
Please note, I started with the following:
func showInfoView() { UIView.animateWithDuration(2.0, animations: { () -> Void in self.infoDetailView.alpha = 0.75 }) } func hideInfoView() { UIView.animateWithDuration(2.0, animations: { () -> Void in self.infoDetailView.alpha = 0.00 }) }
If you infoDetailView is under auto layout constraints you need to call layoutIfNeeded on the parent view inside animateWithDuration:
func showInfoView() { self.view.layoutIfNeeded() // call it also here to finish pending layout operations UIView.animate(withDuration: 2.0, animations: { self.infoDetailView.alpha = 0.75 self.view.layoutIfNeeded() }) }
Theoretically this should not be needed if you just change the .alpha value, but maybe this could be the problem in this case.
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