如何以编程方式为ios 9中的UIStackView的alignment属性设置animation效果

我想知道如何在水平UIStackView的alignment属性中将UIStackViewAlignmentCenter中的alignment属性更改为UIStackViewAlignmentTop,反之亦然,并且我想在视觉上同时反映此更改。

编辑:

我拥有的:

这是我的观点层次:

  • 两个button名为b1和b2; b1有一个名为“changeAlignmentToTop”的动作,而b2有一个名为“changeAlignmentToCenter”的动作。
  • 一个名为Pview的UIView框架(0,100,414,100)。
    • 一个名为S1的水平UIStackView,其alignment属性设置为“center”。 这个堆栈视图已被固定到pView的边界。
      • 一个名为S2的水平UIStackView,其alignment属性设置为“Fill”,里面有两个标签。

我想做的事:

当我触摸buttonb1时,我想将S1的alignment从“中心”更改为“顶部”,并且我想为该更改设置animation。

我试过了

- (void) changeAlignmentToTop { [UIView animationWithduration 0.3 animations : ^{ S1.alignment = UIStackViewAlignmentTop; // here I'd prove several options // option - 1 [S1 setNeedsDisplay]; [S1 layoutIfNeeded]; // option - 2 //[S1 setNeedsLayout]; //[S1 layoutIfNeeded]; // option - 3 //[S1 setNeedsDisplay]; //[pView layoutIfNeeded]; // option - 4 //[pView setNeedsDisplay]; //[pView layoutIfNeeded]; // option - 5 //[pView setNeedsDisplay]; //[self.view layoutIfNeeded]; } completion: nil]; } - (void) changeAlignmentToCenter { [UIView animationWithduration 0.3 animations : ^{ S1.alignment = UIStackViewAlignmentCenter; // here I'd prove several options // option - 1 [S1 setNeedsDisplay]; [S1 layoutIfNeeded]; // option - 2 //[S1 setNeedsLayout]; //[S1 layoutIfNeeded]; // option - 3 //[S1 setNeedsDisplay]; //[pView layoutIfNeeded]; // option - 4 //[pView setNeedsDisplay]; //[pView layoutIfNeeded]; // option - 5 //[pView setNeedsDisplay]; //[self.view layoutIfNeeded]; } completion: nil]; } 

这些选项都不起作用。 alignment的变化,但用户界面不反映它既不animation任何东西。 如果我改变轴的alignment方式(试图将轴从水平改变到垂直,反之亦然),每一件事情都会顺利进行。 如果我更改animation大小的标签中使用的两个标签的每一件事情顺利,问题是与stackView的alignment。 但根据苹果文档的alignment属性是可以animation的,所以我做错了什么?

任何人都可以帮我吗?

提前致谢

所以希望我明白你的问题,如果不让我知道,我会编辑。

首先我会提供我认为正在发生的事情,为什么然后我会尝试给你一个解决scheme,虽然我不知道你的用例。

UIStackView的工作方式是为您创build约束。 我相信你知道这一点,但让我们把你的堆栈和分析一起。 当我阅读问题时,在另一个水平堆栈视图中添加水平堆栈视图。 在运行时,外部堆栈视图使用内在高度调整内部堆栈视图,然后将约束添加到外部(s1)的中心Y. 从可视化debugging器查看图像。

Horizo​​ntalInside

你可以看到它是垂直居中。 要做到这一点,它必须添加一些约束来处理一些types水平持有水平的缺lessY值。 所以现在想想animation。 它不是直接改变任何约束,显然改变stackview的alignment方式不能完全清除原始约束,因为内部堆栈视图不能移动。 至less这是我认为正在发生的事情。

有趣的是,如果你将外部堆栈视图(s1)设置为垂直堆栈视图,那么它就是运行时的样子。 看到图像

垂直

您可以看到内部堆栈视图(s2)被垂直拉伸,以便在水平填充之前填充整个外部堆栈视图(s1)。 就布局和空间而言,垂直方向上有很大的不同。

现在运行animation但是在内部stackview(s2)与此代码

 @IBAction func changeLayoutDidPress(_ sender: Any) { if s2.alignment == .center{ UIView.animate(withDuration: 10.0, animations: { self.s2.alignment = .top }) }else{ UIView.animate(withDuration: 10.0, animations: { self.s2.alignment = .center }) } } 

您将看到内部堆栈视图(s2)移动到s1的顶部。 我认为这是因为stackview允许它的内容视图。 我希望这可以解决你的问题。 对不起,我不能完全解释由不同的stackviews创build的约束,但我知道无论水平持有一个水平的限制,必须保持垂直的animation。

另外一个可能的原因是更改字体大小的作用是可能会导致标签视图重新计算它的约束到一些内容视图的堆栈视图,这将允许它向上移动。 只是我的想法。

如果仍然需要Horizo​​ntal内的Horizo​​ntal,则可以在内层s2上添加相同高度的外部堆栈视图(s1),并且很可能与上面的一样。