将UINavigationController的工具栏移到顶部,位于导航栏下方

Jor*_*n H 6 uinavigationbar uitoolbar uinavigationcontroller ios

创建时UINavigationController,可以显示其默认隐藏的UIToolbar通过setToolbarHidden:animated:(或通过选中Interface Builder中的显示工具栏).这会导致工具栏出现在屏幕的底部,并且此工具栏在导航堆栈上的视图控制器的推送和弹出之间保持不变.这正是我需要的,除了我需要工具栏位于屏幕顶部.看起来这正是Apple在iTunes应用程序中所做的事情:

在此输入图像描述

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

我试图实现UIToolbarDelegate,重写positionForBar:,并返回UIBarPosition.TopAttachedUIBarPosition.Top设置后delegateself.navigationController?.toolbarself,但是这都没打电话委托方法,因此它并没有改变栏的位置.

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

Lab*_*Ars 0

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

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

其次,在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;
}
Run Code Online (Sandbox Code Playgroud)