2

此页面上来自 Apple 用户界面设计指南的第二张图片显示了高导航栏内的分段控件:

https://developer.apple.com/library/ios/documentation/userexperience/conceptual/mobilehig/Anatomy.html#//apple_ref/doc/uid/TP40006556-CH24-SW1

这是如何做到的?在我看来, UINavigationBar 总是 64 像素高,所以我不明白他们是如何让它变得更高的。

它是一个自定义元素(在本文档中会令人惊讶),还是有一种简单的方法来实现这一点?我想知道它是否是 UIToolbar ......它们是否与 iOS 7 下的 UINavigationBar 合并?如果是这样,我们该怎么做?

请注意,我需要在 iPad 应用程序中执行此操作,其中 UINavigationController 位于拆分视图控制器内。

4

1 回答 1

2

我终于找到了解决方案。

我必须用我的自定义子类覆盖 UINavigation 栏才能更改高度。通过使用外观代理,可以正确地重新定位标题和导航项。不幸的是,代理不能用于向上移动后退按钮的箭头(在 iOS 7 上),所以我们必须重写 layoutSubview 来处理它。

#define kAppNavBarHeight 66.0

@implementation TATallNavigationBar

- (id)initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setupAppearance];
    }
    return self;
}

- (id)init
{
    self = [super init];
    if (self) {
        [self setupAppearance];
    }
    return self;
}

- (void)setupAppearance {

    static BOOL appearanceInitialised = NO;

    if (!appearanceInitialised) {

        // Update the appearance of this bar to shift the icons back up to their normal position

        CGFloat offset = 44 - kAppNavBarHeight;

        [[TATallNavigationBar appearance] setTitleVerticalPositionAdjustment:offset forBarMetrics:UIBarMetricsDefault];
        [[UIBarButtonItem appearanceWhenContainedIn:[RRSNavigationBar class], nil] setBackgroundVerticalPositionAdjustment:offset forBarMetrics:UIBarMetricsDefault];
        [[UIBarButtonItem appearanceWhenContainedIn:[RRSNavigationBar class], nil] setBackButtonBackgroundVerticalPositionAdjustment:offset forBarMetrics:UIBarMetricsDefault];
        [[UIBarButtonItem appearanceWhenContainedIn:[RRSNavigationBar class], nil] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, offset) forBarMetrics:UIBarMetricsDefault];

        appearanceInitialised = YES;
    }
}

- (CGSize)sizeThatFits:(CGSize)size {

    return CGSizeMake(self.superview.frame.size.width, kNavBarheight);

}

- (void)layoutSubviews {

    static CGFloat yPosForArrow = -1;

    [super layoutSubviews];

    // There's no official way to reposition the back button's arrow under iOS 7. It doesn't shift with the title.
    // We have to reposition it here instead.

    for (UIView *view in self.subviews) {

        // The arrow is a class of type _UINavigationBarBackIndicatorView. We're not calling any private methods, so I think
        // this is fine for the AppStore...

        if ([NSStringFromClass([view class]) isEqualToString:@"_UINavigationBarBackIndicatorView"]) {
            CGRect frame = view.frame;

            if (yPosForArrow < 0) {

                // On the first layout we work out what the actual position should be by applying our offset to the default position.

                yPosForArrow = frame.origin.y + (44 - kAppNavBarHeight);
            }

            // Update the frame.

            frame.origin.y = yPosForArrow;
            view.frame = frame;
        }
    }
}

@end

请注意,在 XCode 中指定子类很容易:单击 UINavigationController 可以访问左侧列中的 UINavigationBar。单击它并在检查器中更改它的子类。

我还为此创建了一个要点:

https://gist.github.com/timothyarmes/7080170

于 2013-10-21T07:45:33.687 回答