ios - 堆栈 View 动画 - 折叠排列的 subview

标签 ios animation stackview

我必须使用 stackview 作为父 View 。我正在尝试用 2 行为 stackview 设置动画,以获得折叠和膨胀底行的效果。 你可以这么说,当你将这段代码应用到带有 subview 的普通自动布局 View 时,我正在尝试做的是同样的事情:

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()})
    }
}

简单明了。当您假设单击此 View 时,它会展开或折叠所有 subview 。随着动画的进行, subview 被裁剪(未调整大小/重新缩放),最后您只能看到原始 View 的一半。

这看起来很简单,但是我无法用stackview来完成它。当我将第二行添加到堆栈 View 然后设置 layoutIfNeeded() 动画时,就像在几个教程中一样,然后: - 当底排从左边充气到它的位置时, - 折叠底行时消失(无动画) - 只有背景 View 动画正确(见代码)

当我使用高度限制并且不在底行的 layoutIfNeeded() 上设置动画时,则: - 充气时,底部行会随着动画的进行而重新缩放到全高 - 折叠时 - 随着动画的进行,底行重新缩放为 0

无法让它夹住底行!任何提示表示赞赏! :)

这是我的堆栈 View 代码:

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()
    })

}

最佳答案

那是很久以前的事了,但我认为在布局 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()
    })
}

关于ios - 堆栈 View 动画 - 折叠排列的 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33700522/

相关文章:

ios - 如何在 ios 中绘制具有多种颜色的动画路径?

ios - UICollectionView(自动调整大小).reloadData() 将 contentOffset 重置为 0(顶部)

安卓3.0 : Stackview example NON widget

ios - 如何将水平堆栈 View 内的所有按钮拉伸(stretch)为设备宽度

ios - 闭包如何捕获值?

安卓 : Click event is not triggered at time of animation

安卓。 TranslateAnimation 无效

android - 如何从图像的中心开始创建动画

ios - Swift 3 Table View - 从某些单元格中删除堆栈 View

ios - 未找到 RCTBridgeModule - RNGoogleSignin