如何正确设置高度约束

问题描述 投票:0回答:1

在我的应用程序中,我正在设置视图的高度约束,当高度约束发生变化时,尽管我将约束设置为顶部为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()
    }

}

对我而言,问题不在于高度变化的动画效果,因为它可以起作用,而是解决了这样一个事实:应用程序似乎忽略了顶部的约束。 Here's the gif showing the animation

ios swift animation constraints
1个回答
2
投票

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

if finalHeight >= mediumY {
    self.heightConstraintConstant = self.maxHeight
} else {
    self.heightConstraintConstant = self.minHeight
}
UIView.animate(withDuration: 0.5) {
    viewThatTheConstraintBelongsTo.layoutIfNeeded()
}
© www.soinside.com 2019 - 2024. All rights reserved.