Using animateWithDuration to fade subview makes parent(ViewController) fade as well - ios

so I'm trying to fade in a custom control and fade out a UIButton. The fading of the custom control is all well, but when I try to fade out the UIButton the whole screen goes black, which is due to the alpha of the root view being set to 0. Here's the code:
func fadeKeypadIn() {
UIView.animateWithDuration(0.5, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.keypad.alpha = 1
self.btnVideo.alpha = 0
}, completion: nil)
UIView.animateWithDuration(0.5, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.btnKeypad.alpha = 0
self.view.alpha = 1
}, completion: {(value: Bool) -> Void in
self.view.alpha = 1
})
}
In the above code if I don't do self.view.alpha = 1 the screen remains totally black.
And here's what the code does in action:
FadeInOutProblem
I'm using Xcode Version 7.2.1 (7C1002)

I don't know how on earth this happened, but the outlets to the buttons I wanted to fade out were referring to the parent view. :|
Recreating the outlets CAREFULLY solved the problem.

Related

How would I go about coding a UIView fade-in animation for bringSubviewToFront

I am attempting to add a UIView Animation/fade-in effect to my function:
self.view.bringSubview(toFront: self.webView)
I've tried implementing it programmatically, but the UIView doesn't animate; instead, it just shows it immediately without the fade-in effect:
UIView.animate(withDuration: 1, animations: {
self.view.bringSubview(toFront: self.webView)
}, completion: nil)
How would I go about implementing an animation for the bringSubview(_: ) and sendSubview(_ : ) functions? I've tried looking everywhere, but no one seems to have the answer.
You can't use UIView.animate like that. It only works on certain properties. In this case, you need to animate the alpha property.
Before you start animating, set the view's alpha to 0 then bring it to front:
self.webView.alpha = 0
self.view.bringSubview(toFront: self.webView)
// After that you animate the alpha:
UIView.animate(withDuration: 1, animations: {
self.webView.alpha = 1
}, completion: nil)

How to show an UIView on top of an UITableView?

I have an UIViewController which contains a table view and a simple view. Both of them are at the same level.
At startup my view starts hidden at the bottom and when I press a button I want my view to slide up. When I do this only 1/4 of the view is shown and not the complete view.
This worked okay before adding the table view, but now I don't understand why it doesn't fully show.
Here is the code to show and hide my view:
func showPicker(date: Date?) {
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: {
self.timePickerView.transform = CGAffineTransform(translationX: 0, y: 0)
}, completion: { _ in
})
}
func hidePicker() {
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: {
self.timePickerView.transform = CGAffineTransform(translationX: 0, y: self.timePickerView.frame.size.height)
}, completion: { _ in
})
}
And here is a screenshot with the view (below the buttons there should be an UIDatePicker which is not shown):
Someone know what the issue is ? I am trying to do this from the storyboards.
edit:
This is what I have right now, but it still doesn't work. It doesn't animate and it also shows just a part of the view. Apparently if I increase the height the view is shown even more, so somehow it says that the shown part is exactly 220 height, which is strange :/
func hidePicker() {
self.pickerBottomConstraint.constant = -220
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: {
self.timePickerView.layoutIfNeeded()
}, completion: { _ in
})
}
func showPicker(date: Date?) {
self.pickerBottomConstraint.constant = 0
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseOut], animations: {
self.timePickerView.layoutIfNeeded()
}, completion: { _ in
})
}
If you're using autolayout, I bet you do and you should, then the easiest way to do what you wanna do is to toggle the constraint of your view, see the gif I added below.
First is to have a reference to your either top or bottom constraint of your view you wanna show and hide. Then modify the constant of the constraint to adjust its position, in that way, you get the illusion that the view is hidden and shown. The demo below uses tableView too.
Hope this helps.
See a demo here showHide that accomplish what you want
Rather then transform, change your views center y position.
ex:
#IBOutlet weak var viewToAnimateOutlet: UIView!
#IBAction func showViewButtonAction(_ sender: Any) {
UIView.animate(withDuration: 1.5) {
self.viewToAnimateOutlet.center.y -= self.viewToAnimateOutlet.frame.height
}
}
#IBAction func hideViewButtonAction(_ sender: Any) {
UIView.animate(withDuration: 1.5) {
self.viewToAnimateOutlet.center.y += self.viewToAnimateOutlet.frame.height
}
}
What i did:
I used autolayout and provided constraint for ViewToAnimate View is
ViewToAnimates.leading = safeArea.leading "constant = 8"
ViewToAnimates.trailing = safeArea.trailing "constant = 8"
This constraint will place ViewToAnimate view outside of the main views bottom. so view will not visible until showViewButtonAction method called.
ViewToAnimates.top = safeArea.bottom "constant = 0"
ViewToAnimates.height = 130

Can all constraints in swift 3 be animated?

I want to animate a view like using the following code:
UIView.animate(withDuration: 2.7, delay: 0.1, options: .allowAnimatedContent, animations: {
self.AVCenterY.constant = 0.8
}, completion: nil)
But it happens so fast it seems like it is not animated. On the other hand, when I animate the property alpha it is animated (it takes the 2.7 seconds to change). I used 2.7 sec to make sure the problem was that I was using a small duration time.
Constraints cannot be animated at all. It is the act of layout that can be animated:
UIView.animate(withDuration: 2.7, delay: 0.1, options: .allowAnimatedContent, animations: {
self.AVCenterY.constant = 0.8
theView.superview?.layoutIfNeeded() // *
}, completion: nil)
When we animate the act of layout (or when the runtime does so), then any constraint changes are also automatically animated.
Note that what I animate is the layout of the superview of the view that is to move. I called it theView but that is just something I made up. You will need an outlet to that view so that you can get its superview, and use the name of that outlet.

How To Only Animate Contents of UIImageView

How do you animate only the contents of a UIImageView? If the image view is centered in the middle of the screen how do you animate the image to slide in from the left but only be shown within the frame of the image view?
As if you are looking at a wall with a window and someone walks by. You don't see them until they are in the frame of the window.
The code below certainly does not do it. I had it a few days ago with ease and erased it and now I can't remember how I did it. It was pretty simple but now it's driving me crazy.
self.lockImages[button.tag].center.x -= self.lockImages[button.tag].bounds.width
UIView.animateWithDuration(2.0, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 1.0, options: nil, animations: { () -> Void in
self.lockImages[button.tag].center.x += self.lockImages[button.tag].bounds.maxX
}, completion: { (Bool) -> Void in
})
UIImageView a subclass of UIView, inherits the .clipsToBounds() method, which will create the desired effect.

swift animateWithDuration animation not right

I am hiding my navigation bar and a UIView under it that acts as a extension bar to it when I scroll my page.
My app is built like:
VC that holds a container view with an embedded table view.
From the table view I have delegates that notify VC1 once a user scrolls up or down.
My problem now is that the animation dont looks that good. What I am trying to do is to animate the extension bar to animate up or down with a fade in or fade out effect as well. When that occurs I also update the top contraint on my container view so that the table view will fill the whole screen. (I am not sure if I use layoutneeded() right or if something else should be used when updating constraints)
My code:
func ContainerTableViewControllerScrolledUp(controller: ContainerTableViewController) {
self.navigationController?.setNavigationBarHidden(false, animated: true)
println("UP")
UIView.animateWithDuration(
1.5,
delay: 0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: nil,
animations: {
self.extensionV.alpha = 1
self.tableVConst.constant = 0
}, completion: { finished in
self.view.layoutIfNeeded()
}
)
}
func ContainerTableViewControllerScrolledDown(controller:ContainerTableViewController) {
self.navigationController?.setNavigationBarHidden(true, animated: true)
println("DOWN")
UIView.animateWithDuration(
1.5,
delay: 0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: nil,
animations: {
self.extensionV.frame.origin.y = CGFloat(-10)
self.tableVConst.constant = -41
self.extensionV.alpha = 0
}, completion: { finished in
self.view.layoutIfNeeded()
}
)
}
extensionV is the extension view
tableVConst is the top constraint for my container view that holds my table view
So how should I edit my code in order to get the extension view to animate up/down with a fade in/fade out effect?
Instead of calling self.view.layoutIfNeeded() in the completion block, try calling it inside the animation block on the last line before it returns.

Resources