【问题标题】:Custom UIToolbar with UINavigationController for Pros用于专业人士的带有 UINavigationController 的自定义 UIToolbar
【发布时间】:2015-12-31 18:03:13
【问题描述】:

几周以来,我一直在搜寻资源并寻找非儿童开发人员关于使自定义大小的 UIToolbar 在基于 UINavigationController 的应用程序中工作的建议。我所说的“工作”是指一种非骇客的方法,它允许诸如工具栏的优雅隐藏/显示、滑动隐藏和其他优雅动画之类的关键操作。

创建一个自定义的UIToolbar 类实例,该实例位于覆盖sizeThatFits:UINavigationController 实例内部,会按预期更改大小,但会导致一些不可接受的问题。

所以,这里我们有许多人提供的常见sizeThatFits: 替换:

    - (CGSize) sizeThatFits:(CGSize)inSize {
        CGSize sz = [super sizeThatFits:inSize];
        sz.height = SS_TOOLBAR_HEIGHT;
        return sz;
    }

好的,很好,大小已更改,但如果您在该函数上设置断点,很明显其他 44 pt 高度仍在敲打。尝试在那里设置一个断点,看看它被调用的频率——看起来很可疑(稍后会起作用)。

好的,很好,它可以根据需要更改高度,因此我们继续添加功能,以便工具栏在触摸或滑动时隐藏(带动画)。好吧,如果我们启用 UINavigationController 的 hidesBarsOnSwipe,那么有两个问题:导航栏被束缚在隐藏处(糟糕),并且工具栏被完全隐藏,因此将它带回来完全不是所见即所得.我们的设计目标是让工具栏像抽屉一样操作,在适当的滑动方向上滑入/滑出,独立于导航栏。除了完全隐藏工具栏之外,我们还希望有一个可能有 10-20 pts 高的 lil stub/tab 事物,这表明用户可以像抽屉一样将工具栏向上滑回其正常状态。

为此,我们在 UIToolbar 派生类中更改 sizeThatFits:

- (CGSize) sizeThatFits:(CGSize)inSize {
    CGSize sz = [super sizeThatFits:inSize];
    sz.height = _minimized ? SS_TOOLBAR_HEIGHT_MINIMIZED : SS_TOOLBAR_HEIGHT;
    return sz;
}

在最小化状态更改时,我们会自然地隐藏/显示适当的子视图,使其正常显示,或者说是 15 pts 高,带有一点抓地力图形小曲。因此,这种方法的主要问题是,由于在动画期间调用sizeThatFits: 并将其短路,现在任何尝试将工具栏动画滑入/滑出都会完全失败。好的 Apple,好的,让我们尝试一些技巧,比如在其他地方设置目标大小:

- (CGSize) sizeThatFits:(CGSize)inSize {
    CGSize sz = [super sizeThatFits:inSize];
    if ( _animationInProgress ) {
        sz.height = _minimized ? SS_TOOLBAR_HEIGHT_MINIMIZED : SS_TOOLBAR_HEIGHT;
    }
    return sz;
}

好吧,事情在这一点上就像滚雪球一样疯狂。对sizeThatFits: 的调用比比皆是,并且随着 44 pt 幽灵大小胜出,对抽屉式隐藏/显示动画的尝试看起来更加破碎,一切都被搞砸了。

因此,简而言之,我正在寻找专业开发人员来分享有关如何继续使用 UINavigationController 的信息/建议,但拥有一个具有良好的动画抽屉式行为的工具栏。在这一点上,我几乎可以满足任何条件,只是“最小化”状态是 WYSIWYG 友好的,因此用户可以恢复工具栏。也许一种方法是制作一个位于底部的微小浮动 UIView 并且仅在工具栏隐藏时显示(并且当触摸或滑动时,工具栏将被取消隐藏并且动画将是流畅的)。我将如何以及在哪里坚持这种“浮动”视图?

我想是什么让我对这一切感到愤怒,为什么我觉得我在发帖寻求帮助是因为这里讨论的所需工具栏功能似乎是大多数 iOS 开发人员绝对欢迎的功能,并将视为对 UINavigationController 的重大改进+UIToolbar 的当前限制。

我在 iOS 方面有不错的经验,但我是 maaaany moons 的 OS X 和 Win 兽医,因此非常感谢其他专业开发者的帮助。

提前致谢!

【问题讨论】:

    标签: ios uinavigationcontroller uitoolbar


    【解决方案1】:

    尝试覆盖 -intrinsicContentSize。

    【讨论】:

    • 我不这么认为。在UINavigationController 中甚至没有为UIToolbar 调用该方法。派生一个 UIToolbar 的子类,在 UINavigationController 中使用它,在其intrinsicContentSize 实现中设置一个断点,只要美国等待五角大楼和政治结构,它也不会将一切都视为轰炸目标或自然资源占有。
    【解决方案2】:

    试试这个方法:

    1. 将一个新的视图控制器拖到情节提要中。
    2. 将工具栏拖到该窗口上。
    3. 向工具栏添加约束:Leading、Trailing、Bottom、Height。
    4. 将工具栏的标签设置为1。
    5. 将容器视图添加到视图控制器。
    6. 添加约束:
      • 顶部空间到顶部布局指南
      • 底部空间到底部布局指南
      • Leading Space To Superview (NOT MARGIN)
      • 到 Superview 的尾随空间
    7. 删除容器视图链接到的视图控制器。
    8. ⎈ Ctrl - 从容器视图拖到导航控制器。选择“嵌入”。
    9. 将 Storyboard 入口点(从左侧淡入的箭头)移动到主视图控制器。
    10. 子类UINavigationController
    11. 在你的子类中覆盖:

      - (UIToolbar *)toolbar {
          UIToolbar *toolbar = (UIToolbar *)[self.parentViewController.view viewWithTag:1];
          if (!toolbar) {
              return super.toolbar; // prevent errors on app launch
          }
          return toolbar;
      }
      - (void)setToolbarHeight:(CGFloat)height {
          for (NSLayoutConstraint *constraint in self.toolbar.constraints) {
              if (constraint.firstAttribute == NSLayoutAttributeHeight) {
                  constraint.constant = height;
              }
          }
          [self.parentViewController.view layoutSubviews];
          [self.toolbar layoutIfNeeded];
      }
      // if you need:
      - (CGFloat)toolbarHeight {
          for (NSLayoutConstraint *constraint in self.toolbar.constraints) {
              if (constraint.firstAttribute == NSLayoutAttributeHeight) {
                  return constraint.constant;
                  break;
              }
          }
          return -1;
      }
      

    注意:工具栏中的所有视图都将停留在工具栏的底部。

    注意 2:这适用于动画,只需在 -animateWithDuration: 方法中设置 self.toolbarHeight = ###

    重要提示:如果要缩小工具栏的高度,请确保将toolbar.clipsToBounds 设置为YES

    【讨论】:

    • 感谢您的建议,但您能详细说明一下吗?目前尚不清楚这对 44 无形手和sizeThatFits 似乎会打断或以其他方式干扰动画这一事实没有问题。
    • @Drew 这不需要使用-sizeThatFits:
    • 我听到你的声音,但我想我是说细节似乎很模糊,你没有说清楚这是否是一个确认的解决方案。我正在为这个项目“使用”IB,但实际上只是为了实例化 UINavigationController 所以你的建议适用(其他一切都是以编程方式创建的)。但是,IB 中工具栏视图的所有约束都被禁用(这让我想知道您是否有使用此方法的经验)。
    • 我尝试通过以编程方式添加约束来使用不同的方式,并且工具栏的大小/高度从未从 44 改变。
    • 所以我尝试按照您的步骤进行操作,但存在一些差异(您是否尝试过这种方法!?)。无论如何,我知道这种方法是关于什么的,但是在尝试了足够多的方法之后,我一直遇到一个致命的问题。当调用 toolbar 时 main() 在启动时崩溃,因为 UINavigationController 的 parentViewController 仍然为零。我真诚地感谢您的帮助 JF,但如果您的建议是未经真正测试的东西,那么我不确定您为什么建议其他人尝试它(甚至没有提到这是一个实验性想法)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 2013-02-24
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2011-08-02
    相关资源
    最近更新 更多