在我的应用程序中,我正在设置视图的高度约束,当高度约束发生变化时,尽管我将约束设置为顶部为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
我相信你需要做的是实际动画更新的布局。更具体地说是这样的
if finalHeight >= mediumY {
self.heightConstraintConstant = self.maxHeight
} else {
self.heightConstraintConstant = self.minHeight
}
UIView.animate(withDuration: 0.5) {
viewThatTheConstraintBelongsTo.layoutIfNeeded()
}