如何创建此导航控件

时间:2013-10-20 18:31:37

标签: uinavigationcontroller ios7

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位于拆分视图控制器内。

1 个答案:

答案 0 :(得分:2)

我终于找到了解决方案。

我必须使用自定义子类覆盖UINavigation bar才能更改高度。通过使用外观代理,可以正确地重新定位标题和导航项。不幸的是,代理不能用于向后移动后退按钮的箭头(在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