我必须使用stackview作为父视图。我试图用2行动画stackview来获得折叠和膨胀底行的效果。 你可以这么说,我试图做的就是你将这段代码应用到带有子视图的普通自动浏览视图时所得到的一样:
func showView()
{
if(!expand)
{ UIView.animateWithDuration(0.5, animations:{
self.expandableViewHeight.constant = 50
// Update layout of all subviews
self.parentViewController!.view.layoutIfNeeded()})
} else {
UIView.animateWithDuration(0.5, animations:{
self.expandableViewHeight.constant = 100
// Update layout of all subviews
self.parentViewController!.view.layoutIfNeeded()})
}
}
简单而整洁。当您点击此视图时,它会扩展或折叠其所有子视图。随着动画的进行,子视图被剪裁(未调整大小/重新缩放),最后您只能看到原始视图的一半。
看起来很简单,但我无法用stackview完成它。当我将第二行添加到stackview然后设置layoutIfNeeded()动画时,就像在几个教程中一样,然后: - 当底部排气管从左侧到达位置时, - 折叠底行时消失(无动画) - 只有背景视图正确动画(参见代码)
当我使用高度约束并且不在底行的layoutIfNeeded()上设置动画时,则: - 当动画进行时,当底部行的充气重新调整到全高时 - 折叠时 - 底部行在动画播放时重新调整为0
不能让它夹在底行!任何提示赞赏! :)
这是我的stackview代码:
override func viewDidLoad(){
super.viewDidLoad()
background = UIView(frame:CGRectMake(0, 0, frame.width,frame.height))
background.backgroundColor = UIColor.whiteColor()
background.layer.cornerRadius = 5
background.layer.masksToBounds = true
self.addSubview(background)
vStack = UIStackView()
vStack.axis = .Vertical
vStack.alignment = .Fill
vStack.distribution = .Fill
vStack.spacing = 0
self.addArrangedSubview(vStack)
hStack = UIStackView()
hStack.axis = .Horizontal
hStack.alignment = .Center
hStack.distribution = .EqualSpacing
hStack.spacing = 10
hStack2 = UIStackView()
hStack2.axis = .Horizontal
hStack2.alignment = UIStackViewAlignment.Center
hStack2.distribution = UIStackViewDistribution.EqualCentering
hStack2.spacing = 10
lquestionStack = UIStackView()
questionStack.axis = .Horizontal
questionStack.alignment = .Center
questionStack.distribution = .EqualSpacing
questionStack.spacing = QUESTION_PADDING
let labelQuestionNumber = UIButton()
labelQuestionNumber.userInteractionEnabled = false
let numberImage = UIImage(named: "backgroundImage")
labelQuestionNumber.setBackgroundImage(numberImage, forState: .Normal)
questionStack.addArrangedSubview(labelQuestionNumber)
hStack.addArrangedSubview(questionStack)
vStack.addArrangedSubview(hStack)
hStack2.addArrangedSubview(questionStack)
vStack.addArrangedSubview(hStack2)
}
public func collapseInflateAction() {
if checkWidget.collapsed {
inflateWidget()
} else {
collapseWidget()
}
checkWidget.collapsed = !checkWidget.collapsed
}
private func collapseWidget(){
vStack.removeArrangedSubview(self.hStack2)
self.hStack2.removeFromSuperview()
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.background.frame.size.height = (self.background.frame.size.height)/2
self.layoutIfNeeded()
self.superview?.layoutIfNeeded()
})
}
private func inflateWidget(){
self.vStack.addArrangedSubview(self.hStack2)
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.background.frame.size.height = self.background.frame.size.height*2
self.layoutIfNeeded()
self.superview?.layoutIfNeeded()
})
}
这是使用约束而不是layoutIfNeeded()动画的最后两个方法的变体。并且还修改了约束:
override func viewDidLoad(){
super.viewDidLoad()
(...)
heightConstraint = NSLayoutConstraint(item: hStack2, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 0)
self.addConstraint(heightConstraint)
}
private func collapseWidget(){
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.background.frame.size.height = 44
self.heightConstraint.constant = 0
self.superview?.layoutIfNeeded()
})
}
private func inflateWidget(){
UIView.animateWithDuration(0.5, animations: { () -> Void in
self.background.frame.size.height = 88
self.heightConstraint.constant = 44
self.superview?.layoutIfNeeded()
})
}
答案 0 :(得分:1)
那是很久以前的事了,但我认为在布局superview之前添加self.layoutIfNeeded()是有帮助的
fileprivate func collapseWidget(){
UIView.animate(withDuration: 0.25, animations: { () -> Void in
self.background.frame.size.height = self.heightCollapsed
self.heightConstraint.constant = self.heightCollapsed
self.layoutIfNeeded()
self.superview?.layoutIfNeeded()
})
}
fileprivate func inflateWidget(){
self.separatorView.isHidden = false
UIView.animate(withDuration: 0.25, animations: { () -> Void in
self.background.frame.size.height = self.heightInflated
self.heightConstraint.constant = self.heightInflated
self.layoutIfNeeded()
self.superview?.layoutIfNeeded()
})
}
答案 1 :(得分:0)
在这种情况下,可以帮助人们使动画顺利工作的某件事是在层次结构的最高视图上触发layoutIfNeeded()
。
当您的UIStackView
嵌入UIScrollView
中时,这特别有用。如果您仅在layoutIfNeeded
或arrangedSubviews
上触发UIStackView
,那么动画中的怪异故障就会结束。
另一种解决方案是仅在您的layoutIfNeeded
视图上触发UIViewController
。
希望这个答案会有所帮助。