当前位置: 首页 > 知识库问答 >
问题:

如何正确动画高度约束

席俊
2023-03-14

在我的应用程序中,我正在为视图的高度约束设置动画,当高度约束更改时,视图会向下平移一段时间,尽管我将约束设置为0。下面是我用来设置更改动画的代码:

UIView.animate(withDuration: 0.5) {
    if finalHeight >= mediumY {
        self.heightConstraintConstant = self.maxHeight
    } else {
        self.heightConstraintConstant = self.minHeight
    }
}

下面是创建所有可扩展视图的方法:

    //
//  ExpandibleView.swift
//  PhotoMapping
//
//  Created by Lorenzo Santini on 04/09/18.
//  Copyright © 2018 Lorenzo Santini. All rights reserved.
//

import Foundation
import UIKit

class ExpandableView: UIView {
    let panGestureRecognizer = UIPanGestureRecognizer()

    var minHeight: CGFloat = 0 {
        didSet {
            initialHeight = minHeight
        }
    }
    var maxHeight: CGFloat = 0

    var initialHeight: CGFloat = 0
    var initialPoint: CGPoint? = nil

    var heightConstraintConstant: CGFloat {
        get {
            if !self.constraints.filter({ $0.firstAttribute == .height}).isEmpty {
                return self.constraints.filter({$0.firstAttribute == .height && $0.secondItem == nil}).first!.constant
            } else {
                let constrain = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: initialHeight)
                constrain.priority = .defaultHigh
                self.addConstraint(constrain)
                return constrain.constant
            }
        }

        set(newConstant){
            if !self.constraints.filter({ $0.firstAttribute == .height}).isEmpty {
                self.constraints.filter({$0.firstAttribute == .height && $0.secondItem == nil}).first?.constant = newConstant
            } else {
                let constrain = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: newConstant)
                self.addConstraint(constrain)
            }
            //self.layoutIfNeeded()
        }

    }

    func initialize(minHeight: CGFloat, maxHeight: CGFloat) {
        //Create panGestureRecognizer
        panGestureRecognizer.addTarget(self, action: #selector(handlePan(_:)))
        panGestureRecognizer.minimumNumberOfTouches = 1
        panGestureRecognizer.maximumNumberOfTouches = 1
        self.addGestureRecognizer(panGestureRecognizer)

        //Set min and max height
        self.minHeight = minHeight
        self.maxHeight = maxHeight

        self.translatesAutoresizingMaskIntoConstraints = false

        self.subviews.map{$0.translatesAutoresizingMaskIntoConstraints = false}
    }

    @objc func handlePan(_ sender: Any) {
        let translation = panGestureRecognizer.translation(in: self)

        if initialPoint == nil {
            initialPoint = translation
        }

        let translationHeight = CGFloat(translation.y - initialPoint!.y)
        let finalHeight = translationHeight + initialHeight

        if panGestureRecognizer.state == .changed {
            if finalHeight <= maxHeight && finalHeight >= minHeight {
                heightConstraintConstant = finalHeight
            } else if finalHeight >= maxHeight {
                heightConstraintConstant = maxHeight
            } else if finalHeight <= minHeight {
                heightConstraintConstant = minHeight
            }
        } else if panGestureRecognizer.state == .ended {

            let mediumY = maxHeight / 2 + minHeight / 2

            if finalHeight >= mediumY {
                self.heightConstraintConstant = self.maxHeight
            } else {
                self.heightConstraintConstant = self.minHeight
            }
            UIView.animate(withDuration: 0.5) {
                self.layoutIfNeeded()
            }

            initialPoint = nil
            initialHeight = heightConstraintConstant
        }

        //layoutIfNeeded()
    }

}

对我来说,问题不在于如何设置高度变化的动画,因为这是可行的,而在于解决一个事实,即在一段时间内,应用程序似乎忽略了顶部的约束。这是显示动画的gif

共有1个答案

柴茂材
2023-03-14

我相信你需要做的实际上是动画的布局正在更新。更具体地说是这样的

if finalHeight >= mediumY {
    self.heightConstraintConstant = self.maxHeight
} else {
    self.heightConstraintConstant = self.minHeight
}
UIView.animate(withDuration: 0.5) {
    viewThatTheConstraintBelongsTo.layoutIfNeeded()
}
 类似资料:
  • 我以前从未使用过自动布局约束。我有一个新的小应用程序,我正在开发,并注意到NIB的视图默认为自动布局。所以,我想我会借此机会使用它,并尝试弄清楚苹果公司在这方面的进展。 第一个挑战: 我需要调整MKMapView的大小,并将其设置为新位置的动画。如果我按照我习惯的方式来做: ...然后,每当更新同级视图时,MKMapView将“捕捉”回其原始高度(在我的例子中,UISegmentedControl

  • 我尝试在视图顶部设置黑色标签高度约束的动画,并在下面的白色标签上设置约束,以设置与上面标签的距离。然后,我尝试使用以下代码设置高度更改黑色标签的动画(我还尝试删除UIView.animateWithDuration块中更改self.height的代码): 按按钮可调用调整大小操作。。有一些东西是动态的,但不是我所期望的:标签立即将其大小更改为0或100。当它变为0时,第二个标签将缓慢向上移动到其新

  • 问题内容: 我通过隐藏上的所有其他布局和视图将其扩展到全屏。有一个上面 我想对此应用自定义动画。大小应缓慢增加(例如500毫秒)。 但是我怀疑这可能吗?谢谢。 这是我在做什么: 是我点击的ID 。该函数从 问题答案: 当然可以。 只需编写自己的自定义动画并修改动画视图的。在此示例中,动画为动画视图的 高度 设置了动画。当然, 对宽度进行动画处理也是可能的 。 它看起来像这样: 在代码中, 创建一个

  • 我正在用更新一个旧的应用程序,当没有广告时,它就会滑出屏幕。当有广告时,它会在屏幕上滑动。基本的东西。 老风格,我设置了一个动画块的框架。新样式中,我有一个到auto-layout约束,它确定位置,在本例中是距离超级视图底部的距离,并修改常数: 和预期的一样,但没有动画。 更新:我重新观看了WWDC12讨论的最佳实践,以掌握自动布局,其中包括动画。它讨论了如何使用CoreAnimation更新约束

  • 问题内容: 可以固定桌子上一行的高度(tr)吗? 当我缩小浏览器窗口时,会出现问题,一些行开始播放,而我无法确定行的高度。 我尝试了几种方法: 我正在使用IE7 样式 HTML代码。 问题答案: 当涉及固定高度和不换行文本时,表格很难(至少在IE中如此)。我认为您会发现唯一的解决方案是将文本放入元素中,如下所示: 这样,的高度就是包含单元格的高度,并且文本无法增长,无论窗口大小如何,单元格/行都必

  • 关于UITableViewCell高度动画,在堆栈溢出方面有很多类似的问题,但对于新的iOS8自动布局驱动的表视图,这些问题都不起作用。我的问题: 自定义单元格: 注意旋转木马高度限制。这是内容视图的子视图(唯一的子视图)的高度约束。 然后,在“查看我要展开的所有操作”单元上,我的代码: 如您所见,我尝试使用这个很好的旧解决方案: 您可以在选中UITableViewCell时设置高度更改的动画吗?