【问题标题】:Move UINavigationController's toolbar to the top to lie underneath navigation bar将 NavigationController 工具栏移到顶部以位于导航栏下方
【发布时间】:2015-10-08 04:25:36
【问题描述】:

当您创建UINavigationController 时,您可以通过setToolbarHidden:animated:(或通过在Interface Builder 中选中显示工具栏)显示其默认隐藏的UIToolbar。这会导致一个工具栏出现在屏幕底部,并且该工具栏在导航堆栈上的视图控制器的推送和弹出之间持续存在。这正是我需要的,除了我需要将工具栏放在屏幕的 top 上。看来这正是 Apple 对 iTunes 应用所做的:

如何将UINavigationController 的工具栏移动到顶部以位于导航栏下方而不是底部?

我尝试实现UIToolbarDelegate,覆盖positionForBar:,并在将self.navigationController?.toolbardelegate设置为self后返回UIBarPosition.TopAttachedUIBarPosition.Top,但这甚至没有调用委托方法,因此它没有改变条形位置。

请注意,我需要在导航之间保留工具栏,因此我不能简单地将工具栏添加到视图控制器并将其放置在导航栏下方。

【问题讨论】:

  • 您是否尝试过更改toolbar.frame.origin.y 的值?
  • 你有没有找到解决这个问题的合适方法?
  • @DrMickeyLauer 不,我最终没有追求它

标签: ios uinavigationcontroller uinavigationbar uitoolbar


【解决方案1】:

这个问题的解决方案是一个两步(半)的过程:

首先,您必须将观察者添加到工具栏“中心”成员。

其次,在您的 observeValueForKeyPath:ofObject:change:context: 中,每次有人移动工具栏时(例如,当设备旋转时,导航控制器本身)将工具栏重新定位到您的目标位置)。

我在我的 UINavigationController 子类中做到了这一点。 为了避免递归,我安装了一个本地标志成员“inToolbarFrameChange”。

最后(一半)步骤有点棘手......你必须访问工具栏的“框架”成员,才能完全调用观察者......我猜,原因可能是,'frame' 是作为 UIToolbar 中的方法实现的,并且 UIView 中的基本 'frame' 值仅在调用 UIToolbar 方法时更新?!?

我确实在我重载的 setToolbarHidden:animated: 方法中实现了这个“框架”访问,除了转发调用和访问工具栏的“框架”值之外什么都不做。

@interface MMMasterNavigationController ()
@property (assign, nonatomic) BOOL          inToolbarFrameChange;
@end

@implementation MMMasterNavigationController

/*
 awakeFromNib

 */
- (void)awakeFromNib {

    [super awakeFromNib];

    // ... other inits

    self.inToolbarFrameChange = NO;
}

/*
 viewDidLoad

 */
- (void)viewDidLoad {

    [super viewDidLoad];

    // 'center' instead of 'frame' from: http://stackoverflow.com/a/17977278/2778898
    [self.toolbar addObserver:self
                   forKeyPath:@"center"
                      options:NSKeyValueObservingOptionNew 
                      context:0];
}

/*
 observeValueForKeyPath:ofObject:change:context:

 */
- (void)observeValueForKeyPath:(NSString *)pKeyPath
                      ofObject:(id)pObject
                        change:(NSDictionary<NSString *,id> *)pChange
                       context:(void *)pContext {

    if ([pKeyPath isEqualToString:@"center"]) {
        if (!self.inToolbarFrameChange) {
            //NSLog(@"%s (0): %@", __PRETTY_FUNCTION__, pChange);
            self.inToolbarFrameChange = YES;

            CGRect  tbFrame = self.toolbar.frame;
            // maybe some other values are needed here for you
            tbFrame = CGRectMake(0, 0, CGRectGetWidth(tbFrame), CGRectGetHeight(tbFrame));
            self.toolbar.frame = tbFrame;

            self.inToolbarFrameChange = NO;
        }
    } else {
        [super observeValueForKeyPath:pKeyPath ofObject:pObject change:pChange context:pContext];
    }
}

/*
 setToolbarHidden:animated:

 */
- (void)setToolbarHidden:(BOOL)pHidden
                animated:(BOOL)pAnimated {
    FLog;

    [super setToolbarHidden:pHidden animated:NO];

    // Access the 'frame' member to let to observer fire
    CGRect  rectTB = self.toolbar.frame;
    rectTB = CGRectZero;
}

【讨论】:

    【解决方案2】:

    你可能创建的不是 UITableViewController 而是 UIViewController。鉴于 UIViewController 将 UIToolBar 放在 NavigationBar 和 UITableView 下方。将所有必要的 UITableView 列表委托给 UIViewController,仅此而已。 为什么要使用 UIViewController 而不是 UITableViewController?因为 tableView 不会有静态位置元素。你应该有一些不包含 ScrollView 的东西。在这种情况下,它只是 UIView。你也可以对 tableView 的 UIScrollView 做一些修改,但我认为描述的方法更容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 2020-11-03
      • 1970-01-01
      • 2016-11-25
      • 2011-04-25
      • 1970-01-01
      相关资源
      最近更新 更多