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
Related
I want to create a menu bar on top of a collectionview. When the user scroll down, the menu bar will gradually hide but while the user scroll up , the menu bar will appear immediately. The behavior similar to navigation bar's hidewhenswipe function. Is that any solution to create such behaviour on this menu bar? Thanks.
[screenshot]
Give your header view a height constraint if not given already. Then wired that constraint e.g.
#IBOutlet weak var headerViewHeightConstraint: NSLayoutConstraint!
Confirm your ViewController to UICollectionViewDelegate and UIScrollViewDelegate
set collectionView.delegate = self in ViewDidLoad()
UICollectionView is a subclass of UIScrollView so you can override the delegate method of scrollViewDidScroll and use the following code
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y > 50 {// the value when you want the headerview to hide
view.layoutIfNeeded()
headerViewHeightConstraint.constant = 0
UIView.animate(withDuration: 0.5, delay: 0, options: [.allowUserInteraction], animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}else {
// expand the header
view.layoutIfNeeded()
headerViewHeightConstraint.constant = 100 // Your initial height of header view
UIView.animate(withDuration: 0.5, delay: 0, options: [.allowUserInteraction], animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
}
I've been using HidingNavigationBarManager to do what you just described
and it is very easy to use. If you have a tableView in your ViewController then
it's as easy as adding these lines to your code.
var hidingNavBarManager: HidingNavigationBarManager?
...
...
override func viewDidLoad() {
super.viewDidLoad()
self.hidingNavBarManager = HidingNavigationBarManager(viewController: self, scrollView: tableView)
}
I'm trying to show a UICollectionView in a UITableViewCell. Initially the CollectionView shouldn't be shown, but when the users presses a button the CollectionView should become visible with an animation. I got this working however the first time the CollectionView becomes visible it looks like the cells get zoomed out, if I hide the CollectionView and expand it again, the animation looks correct:
http://g.recordit.co/DBhZCmJKPj.gif
This is the code for animation the change:
func expand() {
tableView?.beginUpdates()
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveLinear, animations: {
self.imageViewDisclosureIndicator.setImage(UIImage(named: "arrow-up"), for: .normal)
self.collectionViewHeight.constant = self.collectionView.intrinsicContentSize.height
self.layoutIfNeeded()
self.isExpanded = true
}, completion: nil)
tableView?.endUpdates()
}
func collapse() {
tableView?.beginUpdates()
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveLinear, animations: {
self.imageViewDisclosureIndicator.setImage(UIImage(named: "arrow-down"), for: .normal)
self.collectionViewHeight.constant = CGFloat(0.0)
self.layoutIfNeeded()
self.isExpanded = false
}, completion: nil)
tableView?.endUpdates()
}
Any help would be appreciated!
Try putting self.layoutIfNeeded outside the animation.
Based off your code, I don't see why you need that line of code, but it is probably the cause for your problem. I think that the content would even load fine without that line, because the size of the content view of the collection view is independent of the height of the collection view.
I want to have my tableview increase in size and moves up when scrolled down while also keeping the constraint to the bottom layout. I thought I would try CGAffineTransform.
func MoveUP() {
// pop up login screen
let bottom = CGAffineTransform(translationX: 0, y: -30)
UIView.animate(withDuration: 0.7, delay: 0.2, options: [], animations: {
// Add the transformation in this block
// self.container is your view that you want to animate
self.numberOfProperties.transform = bottom
self.tableview.transform = bottom
}, completion: nil)
}
The problem with this is that it moves up the tableview but does not keep the proper constraints to the bottom. Many apps seems to have this behavior, what tool am I missing in order to achieve this result?
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.
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.