【问题标题】:How to react to UIControl resize when its data changes数据更改时如何对 UIControl 调整大小做出反应
【发布时间】:2012-01-27 18:17:15
【问题描述】:
  • 我已经构建了一个 UIControl 子类来显示 1 个月的日历视图 一部 iPhone。大多数月份需要 5 周才能显示日期,但 有些月需要 6,所以我建立了动态​​调整大小的控件 自己根据需要。我正在使用 UIView 动画来改变框架 此处的控件。
  • 问题是,我现在需要屏幕上的其他控件 当日历改变大小时移动/调整大小。我真的需要那个 随着日历控件的动画大小改变而发生。 理想情况下,我不会在我的日历中编写大量细节来做到这一点 控制屏幕上的其他控件。
  • 这里最好的策略是什么?我希望我能以某种方式锚定 日历控件框架的其他控件,并具有 平台在动画帧更改时调整它们的位置/大小。 但是,到目前为止,我找不到任何支柱和弹簧的组合来 做到这一点。
  • 我是否只需要硬着头皮添加其他屏幕控件 到我的日历控件中发生的动画?

【问题讨论】:

    标签: ios uicontrol


    【解决方案1】:

    我很想看看是否有更好的答案。

    此时,我所知道的就是在您的日历视图上覆盖setFrame,当它发生变化时,将setNeedsLayout 发送到它的超级视图。

    但我不确定标准视图是否会正确自动调整大小。一般来说,几何图形顺着视图树向下流动,而不是向上流动,您希望它同时进行。

    您可能必须在包含视图上实现 layoutSubviews。

    【讨论】:

      【解决方案2】:

      将动画逻辑从特定视图中移出并移到管理所有控件的视图控制器中。视图仍然可以计算出自己合适的大小,并让视图控制器询问。例如:

      [self.calendarView setDate:date];
      CGSize calendarSize = [self.calendarView sizeForDate:date];
      [UIView animateWithDuration:...
              animations:^{
               ... re-layout everything, including the calendarView ...
              }];
      

      另一种类似的方法:

      [self.calendarView setDate:date];
      [UIView animateWithDuration:...
              animations:^{
               [self.calendarView sizeToFit];
               ... re-layout everything else ...
              }];
      

      根据您的喜好,有很多类似的方法。但关键是将逻辑移出特定视图。通常视图控制器是最好的解决方案。如果控件创建一个可以进入单个UIView 的逻辑集合,那么您可以让“集合”UIView 在其layoutSubviews 中管理相同的东西,但更常见的是视图控制器是更好的解决方案在这里。

      【讨论】:

        【解决方案3】:

        感谢您的帮助。我成功地尝试了这两种方法。 setFrame 的覆盖和 layoutSubviews 的实现起作用了,但是随着日历控件的增长,其他控件跳转到了它们的新位置,而不是动画到这些位置。

        在动画期间移动其他控件的方法是我必须采用的方法。但是,我想保持控件的逻辑完全独立以供重复使用,所以我将动画留在了控件中,但添加了一个代理来对大小变化做出反应,并将代理调用放在动画块中。在完全公开的情况下,我还在增加控件的同时将新月份的日历动画化到控件上,这样我就可以在动画块中做这两件事。

        所以,结束代码看起来像这样:

        // inside the calendar control:
        [UIView animateWithDuration:0.5 animations:^{
            self.frame = newOverallFrame;  // animate the growth of the control
            _offScreenCalendar.frame = newOnScreenFrame; // animate new month on screen
            _onScreenCalendar.frame = newOffScreenFrame; // animate old month off screen
            if (self.delegate)
            {
                [self.delegate handleCalendarControlSizeChange:newOverallFrame]; // animate other controls per the delegate
            }
        }];
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-08-05
          • 1970-01-01
          • 2017-07-13
          • 1970-01-01
          • 2017-12-05
          相关资源
          最近更新 更多