UIPickerView 高度约束动画跳跃
Posted
技术标签:
【中文标题】UIPickerView 高度约束动画跳跃【英文标题】:UIPickerView height constraint animation jumps 【发布时间】:2016-10-13 12:02:17 【问题描述】:我正在为 UIPickerView 的高度约束设置动画。 视图跳到一个小的高度仍然显示 1 行,然后动画直到高度 0。
UIView.animate(withDuration: 0.5, animations:
self.timePickerHeightConstraint.constant = self.pickerIsClosed ? 216 : 0
self.view.layoutIfNeeded()
) compilation in
self.pickerIsClosed = !self.pickerIsClosed
有什么建议吗? 谢谢
【问题讨论】:
【参考方案1】:试试这样的,
func showPickerView(_ animated: Bool)
weak var weakSelf = self
UIView.animate(withDuration: (animated ? kPickerView_AppearanceAnimationDuration : 0.0), delay: (animated ? kPickerView_AppearanceAnimationDelay : 0.0), options: (animations as! UIViewAnimationOptionCurveEaseInOut), () -> Void in
weakSelf!.pickerViewContainerView.transform = CGAffineTransform(translationX: 0, y: 0)
, completion: (finished: Bool) -> Void in
weakSelf!.view.layoutIfNeeded()
)
func hidePickerView(_ animated: Bool)
weak var weakSelf = self
UIView.animate(withDuration: (animated ? kPickerView_DisappearanceAnimationDuration : 0.0), delay: (animated ? kPickerView_DisappearanceAnimationDelay : 0.0), options: (animations as! UIViewAnimationOptionCurveEaseInOut), () -> Void in
weakSelf!.pickerViewContainerView.transform = CGAffineTransform(translationX: 0, y: kPickerView_Height)
, completion: (finished: Bool) -> Void in
它对我有用。
【讨论】:
【参考方案2】:您应该在动画块之外更改约束常量值,
self.timePickerHeightConstraint.constant = self.pickerIsClosed ? 216 : 0
UIView.animate(withDuration: 0.5, animations:
self.view.layoutIfNeeded()
) compilation in
self.pickerIsClosed = !self.pickerIsClosed
另外请确保您没有设置顶部和底部约束,因为这将不允许自动布局将高度设置为 0 点。
【讨论】:
谢谢,但同样的问题。 您为 PickerView 设置了哪些约束? 尾随、前导、高度、顶部、底部 在这种情况下,将高度更改为 0 将不起作用,因为自动布局引擎需要打破约束。尝试设置垂直和水平中心约束并设置宽度和高度约束,只需制作高度约束的出口并更新。根据需要进行更改。【参考方案3】:我遇到了同样的问题。似乎 UIPickerView 的高度动画效果不佳,或者至少按照我希望的方式进行动画处理。
我发现的解决方法是将 UIPickerView 包装在 UIView 中,将 UIView 的 clipsToBounds 设置为 true,然后在 UIView 包装器的高度约束上执行动画,而不是直接使用 UIPickerView。需要注意的一点是,要使其正常工作,UIPicker 视图的高度必须独立于包装器视图的高度进行约束,否则它的反应方式与没有包装器时相同。
// create and add UIPicker to view
UIPickerView *picker = [[UIPickerView alloc] init];
picker.translatesAutoresizingMaskIntoConstraints = NO;
picker.delegate = self;
picker.dataSource = self;
picker.alpha = 0.0;
_myUiPicker = picker; // weak reference property
// make wrapper view
UIView *wrapper = [UIView new];
wrapper.translatesAutoresizingMaskIntoConstraints = NO;
wrapper.clipsToBounds = YES;
[wrapper addSubview:picker];
[self.view addSubview:wrapper];
// Picker constraints
[picker.leadingAnchor constraintEqualToAnchor:wrapper.leadingAnchor].active = YES;
[picker.trailingAnchor constraintEqualToAnchor:wrapper.trailingAnchor].active = YES;
// ***** Note this height is not determined by wrapper view ***
[picker.heightAnchor constraintEqualToConstant:130.0].active = YES;
// ****
[picker.topAnchor constraintEqualToAnchor:wrapper.topAnchor].active = YES;
// wrapper constraints
[wrapper.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
[wrapper.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].active = YES;
// **** this is the constraint you will animate ***
NSLayoutConstraint *heightConstraint = [wrapper.heightAnchor constraintEqualToConstant:0.0];
heightConstraint.active = YES;
// ****
NSLayoutConstraint *topConstraint = [wrapper.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:8.0];
topConstraint.active = YES;
[self.view layoutIfNeeded]; // initial layout
// animate picker height and reminderBtn position
[UIView animateWithDuration:JAPPickerAnimationTime animations:^
heightConstraint.constant = 130.0; // from 0 to 130
picker.alpha = 1.0; // make is show
[self.view layoutIfNeeded];
];
【讨论】:
听起来是个不错的解决方案——你能展示一些代码吗?我不明白你的最后一句话(即独立约束需要)。您能否详细说明一下您是如何做到的? @iKK 我添加了一个代码示例。我所说的独立高度的意思是,设置 UIPickerView 高度的约束与充当包装器的 UIView 的高度无关或绑定。【参考方案4】:选择器组件行的高度是多少。签到
func pickerView(pickerView: UIPickerView, rowHeightForComponent 组件: Int)
当 self.pickerIsClosed == true 时返回 0。
【讨论】:
还会在动画块完成时重新加载选取器视图。以上是关于UIPickerView 高度约束动画跳跃的主要内容,如果未能解决你的问题,请参考以下文章