如何在iOS 9中以编程方式为UIStackView的对齐方式设置动画 [英] How to programmatically animate the alignment property of an UIStackView in ios 9

查看:109
本文介绍了如何在iOS 9中以编程方式为UIStackView的对齐方式设置动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何为从UIStackViewAlignmentCenter到UIStackViewAlignmentTop的水平UIStackView的对齐属性进行动画处理,反之亦然,并且我想同时直观地反映此更改.

I want to know how can I animate a change in the alignment property of an horizontal UIStackView say from UIStackViewAlignmentCenter to UIStackViewAlignmentTop and vice versa, and I want to visually reflects this change at the same time.

我所拥有的:

这是我的视图层次结构:

This is my hierarchy of views:

  • 两个分别名为b1和b2的按钮; b1具有一个名为"changeAlignmentToTop"的动作,b2具有一个名为"changeAlignmentToCenter"的动作,在相应按钮中触摸Up Inside时将激活它们.
  • 一个名为Pview的UIView,其框架为(0,100,414,100).
    • 一个名为S1的水平UIStackView,其对齐方式属性设置为"center".此stackView已固定到pView的边界.
      • 一个名为S2的水平UIStackView,其对齐方式属性设置为填充",并且在两个标签内.
      • two buttons named b1 and b2; b1 has an action named "changeAlignmentToTop" and b2 has an action named "changeAlignmentToCenter", which are activated Upon touch Up Inside in the respective button.
      • an UIView named Pview with frame (0,100,414,100).
        • an horizontal UIStackView named S1, with the alignment property set as "center". This stackView has been pinned to the borders of pView.
          • an horizontal UIStackView named S2, with the alignment property set as "Fill" and which has inside two labels.

          我想做什么:

          当我触摸按钮b1并希望对其进行动画处理时,我想将S1的对齐方式从中心"更改为顶部".

          I want to change the alignment of S1 from "Center" to "Top" when I touch the button b1 and I want to animate that change.

          我尝试过的事情

          - (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];
          }
          

          这些选项都不起作用.适应性更改,但UI均未反映该更改,也没有为任何动画设置.如果我更改轴的对齐方式(尝试将轴从水平方向更改为垂直方向,反之亦然),一切都会顺利进行.如果我动态地改变两个标签中使用的字体大小,一切都会顺利进行,那么问题就出在stackView的对齐上.但是根据苹果的文档,alignment属性是可设置动画的,所以我做错了吗?

          None of these options work. The aligment change but the UI does not reflects it neither it animates anything. If I change the alignment for axis (trying to change the axis from horizontal to vertical and vice versa) every things goes well. If I change animatedly the size of the font used in both label every thing goes well, the problem is with the alignment of the stackView. but according to the apple documentation the alignment property is animatable, so what I'm doing wrong??

          有人可以帮助我吗?

          预先感谢

          推荐答案

          所以希望我能理解您的问题,如果不告诉我,我会进行编辑.

          So hopefully I understand your question and if not let me know and I will edit.

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

          First I will offer what I think is happening and why and then I will try to give you a solution although I don't know your use case.

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

          The way UIStackView works is to create constraints for you. I am sure you know this but let's take your stack and analyze it together. Adding a horizontal stackview inside another horizontal stackview as I read the question. At run time the outer stackview sizes the inner stackview with intrinsic height then adds constraints to the centerY of the outer(s1). See image from visual debugger.

          .

          您可以看到它垂直居中.为此,它必须添加一些约束以处理某些水平保持水平的Y值丢失.所以现在想想动画.它不会直接更改任何约束,并且显然更改堆栈视图的对齐方式一定不能完全清除原始约束,因为内部堆栈视图无法移动.至少这是我认为正在发生的事情.

          You can see it is vertically centered. To do this it must add some constraints to deal with a missing Y value of some type horizontal holding horizontal. So now think of the animation. It is not directly changing any constraints and apparently changing the alignment of a stackview must not completely clear the original constraints as the inner stackview is unable to move. At least this is what I think is going on.

          有趣的是,如果将外部stackview(s1)设置为垂直stackview,则这就是运行时的外观.看图片

          So interestingly enough if you make the outer stackview(s1) a vertical stackview this is what it looks like at run time. see image

          您会看到内部stackview(s2)在垂直填充之前已被拉伸,以填充整个外部stackview(s1),然后再水平填充.垂直布局的布局和空间差异很大.

          You can see that the inner stackview(s2) is stretched vertically to fill the entire outer stackview(s1) before it was horizontally filled. Much different as far as layout and room to animate vertically.

          现在运行动画,但是使用此代码在内部stackview(s2)

          Now running the animation But on the inner stackview(s2) with this code

          @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
                  })
              }
          }
          

          您将看到内部stackview(s2)移至s1的顶部.我认为这是因为stackview的内容视图允许它.我希望这能解决您的问题.抱歉,我无法完全解释由不同的stackview创建的约束,但是我知道,无论是从Horizo​​ntal保持水平创建的约束,都必须使其免受垂直动画的影响.

          You will see the inner stackview(s2) move to the top of s1. I think this is because of the content view of the stackview allowing it. I hope this solves your issue. Sorry I cannot fully explain the constraints created by the different stackviews but I know that whatever constraints are created from Horizontal holding a horizontal must keep it from animating vertically.

          另外,更改字体大小的可能原因是,它可能导致标签视图重新计算其约束,使之进入堆栈视图的某些内容视图,从而使其向上移动.只是我的想法.

          Also a possible reason that changing the font size works is that it is probably causing the label view to recalculate its constraints to some content view of the stackview which would allow it to move up. Just my thoughts on it.

          如果仍然需要在内部水平"内添加水平",则可以在内部s2的外部stackview(s1)上添加相等的高度,并且很有可能与上述相同.

          If having Horizontal inside Horizontal is still needed you could add equal heights to outer stackview(s1) on the inner s2 and it would most likely work the same as above.

          这篇关于如何在iOS 9中以编程方式为UIStackView的对齐方式设置动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆