Reputation: 649
I want to animate hide show when one of my view is hidden. so I'm using content hugging priority to animate that, but it failed it has a gap between view. here I show you the ui and my code
This is 3 uiview code like the picture above
scrollView.addSubview(chooseScheduleDropDown)
chooseScheduleDropDown.translatesAutoresizingMaskIntoConstraints = false
chooseScheduleDropDown.setContentCompressionResistancePriority(.required, for: .vertical)
NSLayoutConstraint.activate([
chooseScheduleDropDown.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
chooseScheduleDropDown.topAnchor.constraint(equalTo: scrollView.topAnchor),
chooseScheduleDropDown.widthAnchor.constraint(equalToConstant: 285),
chooseScheduleDropDown.heightAnchor.constraint(equalToConstant: 60)
])
scrollView.addSubview(entryView)
entryView.isHidden = true
entryView.setContentHuggingPriority(.defaultLow, for: .vertical)
entryView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
entryView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
entryView.topAnchor.constraint(equalTo: chooseScheduleDropDown.bottomAnchor, constant: topPadding),
entryView.widthAnchor.constraint(equalToConstant: 285),
entryView.heightAnchor.constraint(equalToConstant: 60)
])
scrollView.addSubview(chooseDateView)
chooseDateView.setContentHuggingPriority(.defaultLow, for: .vertical)
chooseDateView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
chooseDateView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
chooseDateView.topAnchor.constraint(equalTo: entryView.bottomAnchor, constant: topPadding),
chooseDateView.widthAnchor.constraint(equalToConstant: 285),
chooseDateView.heightAnchor.constraint(equalToConstant: 60)
])
Upvotes: 0
Views: 5510
Reputation: 77442
After exchanging comments, you have a number of different tasks to work on.
But, to give you an example of one approach to showing / hiding the "middle" view and having the bottom view move up / down, here is something to try. It will look like this:
Tapping the top (red) view will hide the middle (green) view and slide the bottom (blue) view up. Tapping the top (red) view again will slide the bottom (blue) view down and show the middle (green) view.
This is done by creating two top constraints for the Bottom view. One relative to the bottom of the Top view, and the other relative to the bottom of the Middle view, with different .priority
values.
The example code is fairly straight-forward, and the comments should make things clear. All done via code - no @IBOutlet
or @IBAction
connections - so just create a new view controller and assign its custom class to AnimTestViewController
:
class DropDownView: UIView {
}
class AnimTestViewController: UIViewController {
let scrollView: UIScrollView = {
let v = UIScrollView()
return v
}()
let chooseScheduleDropDown: DropDownView = {
let v = DropDownView()
return v
}()
let entryView: DropDownView = {
let v = DropDownView()
return v
}()
let chooseDateView: DropDownView = {
let v = DropDownView()
return v
}()
var visibleConstraint: NSLayoutConstraint = NSLayoutConstraint()
var hiddenConstraint: NSLayoutConstraint = NSLayoutConstraint()
override func viewDidLoad() {
super.viewDidLoad()
[chooseScheduleDropDown, entryView, chooseDateView].forEach {
v in
v.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(v)
}
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
let g = view.safeAreaLayoutGuide
let topPadding: CGFloat = 20.0
// chooseDateView top anchor when entryView is visible
visibleConstraint = chooseDateView.topAnchor.constraint(equalTo: entryView.bottomAnchor, constant: topPadding)
// chooseDateView top anchor when entryView is hidden
hiddenConstraint = chooseDateView.topAnchor.constraint(equalTo: chooseScheduleDropDown.bottomAnchor, constant: topPadding)
// we will start with entryView visible
visibleConstraint.priority = .defaultHigh
hiddenConstraint.priority = .defaultLow
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
scrollView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -40.0),
scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
chooseScheduleDropDown.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
chooseScheduleDropDown.topAnchor.constraint(equalTo: scrollView.topAnchor),
chooseScheduleDropDown.widthAnchor.constraint(equalToConstant: 285),
chooseScheduleDropDown.heightAnchor.constraint(equalToConstant: 60),
entryView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
entryView.topAnchor.constraint(equalTo: chooseScheduleDropDown.bottomAnchor, constant: topPadding),
entryView.widthAnchor.constraint(equalToConstant: 285),
entryView.heightAnchor.constraint(equalToConstant: 60),
chooseDateView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
//chooseDateView.topAnchor.constraint(equalTo: entryView.bottomAnchor, constant: topPadding),
visibleConstraint,
hiddenConstraint,
chooseDateView.widthAnchor.constraint(equalToConstant: 285),
chooseDateView.heightAnchor.constraint(equalToConstant: 60),
])
//entryView.isHidden = true
chooseScheduleDropDown.backgroundColor = .red
entryView.backgroundColor = .green
chooseDateView.backgroundColor = .blue
let tap = UITapGestureRecognizer(target: self, action: #selector(toggleEntryView(_:)))
chooseScheduleDropDown.addGestureRecognizer(tap)
}
@objc func toggleEntryView(_ sender: UITapGestureRecognizer) -> Void {
print("tapped")
// if entryView IS hidden we want to
// un-hide entryView
// animate alpha to 1.0
// animate chooseDateView down
// if entryView is NOT hidden we want to
// animate alpha to 0.0
// animate chooseDateView up
// hide entryView when animation is finished
let animSpeed = 0.5
if entryView.isHidden {
entryView.isHidden = false
hiddenConstraint.priority = .defaultLow
visibleConstraint.priority = .defaultHigh
UIView.animate(withDuration: animSpeed, animations: {
self.entryView.alpha = 1.0
self.view.layoutIfNeeded()
}, completion: { _ in
})
} else {
visibleConstraint.priority = .defaultLow
hiddenConstraint.priority = .defaultHigh
UIView.animate(withDuration: animSpeed, animations: {
self.entryView.alpha = 0.0
self.view.layoutIfNeeded()
}, completion: { _ in
self.entryView.isHidden = true
})
}
}
}
Upvotes: 1
Reputation: 100503
Do
// declare an instance property
var hCon:NSLayoutConstraint!
// get only the height constraint out of the activate block
hCon = entryView.heightAnchor.constraint(equalToConstant: 60)
hCon.isActive = true
and play with
hCon.constant = 300 / 0
view.layoutIfNeeded()
Upvotes: 1