如何在ios 9中以编程方式设置UIStackView对齐属性的动画

如何在ios 9中以编程方式设置UIStackView对齐属性的动画,ios,objective-c,core-animation,ios-autolayout,uistackview,Ios,Objective C,Core Animation,Ios Autolayout,Uistackview,我想知道如何设置水平UIStackView的对齐特性更改的动画,例如从UIStackViewAlignmentCenter到UIStackViewAlignmentTop,或者从UIStackViewAlignmentTop到UIStackViewAlignmentTop,反之亦然,同时我想直观地反映此更改 编辑: 我所拥有的: 这是我的视图层次结构: b1和b2两个按钮;b1有一个名为“changeAlignmentToTop”的操作,b2有一个名为“changeAlignmentToCen

我想知道如何设置水平UIStackView的对齐特性更改的动画,例如从UIStackViewAlignmentCenter到UIStackViewAlignmentTop,或者从UIStackViewAlignmentTop到UIStackViewAlignmentTop,反之亦然,同时我想直观地反映此更改

编辑:

我所拥有的:

这是我的视图层次结构:

  • b1和b2两个按钮;b1有一个名为“changeAlignmentToTop”的操作,b2有一个名为“changeAlignmentToCenter”的操作,在相应按钮的内部触动时激活
  • 一个名为Pview的UIView,带有框架(0100414100)。
    • 名为S1的水平视图,路线特性设置为“中心”。此stackView已固定到pView的边界。
      • 名为S2的水平视图,路线特性设置为“填充”,内部有两个标签
我想做什么:

当我触摸按钮b1时,我想将S1的对齐方式从“中心”更改为“顶部”,并且我想设置该更改的动画

我尝试的

- (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];
}
这些选项都不起作用。aligment会更改,但UI不会反映它,也不会设置任何动画。如果我更改轴的对齐方式(尝试将轴从水平更改为垂直,反之亦然),一切都会顺利进行。如果我动态地更改两个标签中使用的字体大小,一切都会顺利进行,问题在于stackView的对齐。但是根据苹果的文档,对齐属性是可设置动画的,那么我做错了什么呢

谁能帮帮我吗


提前感谢

希望我能理解你的问题,如果没有,请让我知道,我会编辑

首先,我将提供我认为正在发生的事情以及原因,然后我将尝试给您一个解决方案,尽管我不知道您的用例

UIStackView的工作方式是为您创建约束。我相信你知道这一点,但让我们一起来分析你的堆栈。阅读问题时,在另一个水平stackview中添加一个水平stackview。在运行时,外部stackview使用内部高度调整内部stackview的大小,然后将约束添加到外部stackview的中心(s1)。请参阅来自可视调试器的图像

您可以看到它垂直居中。要做到这一点,它必须添加一些约束,以处理某个类型的Y值丢失(保持水平)。现在想想动画。它不会直接更改任何约束,而且显然,更改stackview的对齐方式不能完全清除原始约束,因为内部stackview无法移动。至少我认为这是正在发生的事情

非常有趣的是,如果将外部stackview(s1)设置为垂直stackview,这就是运行时的外观。见图片

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

现在运行动画,但在内部堆栈视图(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的内容视图允许它。我希望这能解决你的问题。很抱歉,我无法完全解释由不同的StackView创建的约束,但我知道从水平方向创建的任何约束都必须保持水平方向,以防止垂直方向设置动画

更改字体大小起作用的另一个可能原因是,这可能会导致标签视图重新计算其对stackview的某些内容视图的约束,从而允许其向上移动。只是我的想法


如果仍然需要水平-内部-水平,则可以在内部s2上向外部stackview(s1)添加相同的高度,其工作原理很可能与上述相同

到目前为止你试过什么?什么不起作用?让人们知道什么是行不通的将减少重复你已经尝试过的答案的数量。@RoboticCAT我已经包括了我到目前为止已经尝试过的,按照你的建议。你能帮帮我吗?虽然我不认为需要
setNeedsDisplay
layoutifneedd
,但该代码看起来与我本来要写的代码完全一样。你在调试器中检查过方法是否真的被调用了吗?@robotcat是的,我检查过了,方法已经被调用了。尽管如此,尽管stackView的对齐已经更改了其值,但UI并没有反映此更改。你知道我还能做什么吗?艾瑞尔,想回顾一下我的答案吗?我检查了你的想法,它肯定会改变对齐方式,但前提是S1是垂直堆叠的。问题是,我认为我需要S1是一个水平堆栈,以便让我在应用程序中使用的其他组件正确对齐;这里的标签是为了简化问题。无论如何,我会检查这个作为答案,我会检查是否改变S1垂直和遵循你的建议适合我在原来的应用程序。我认为您关于stackview创建的约束的假设是正确的。谢谢你,伙计!!是的,我认为通过向外部StackView添加等高约束进行编辑将使其工作起来,并乐于提供帮助。干杯