2013-10-20 38 views
2

第二圖像此頁面上,從蘋果的用戶界面設計指南顯示一個高大的導航條內分段控制:這種導航控制是如何被創建

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位於分割視圖控制器中。

回答

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

+0

如何確定你是對_UINavigationBarBackIndicatorView使用是可以接受的?這是一個無證的財產,如果蘋果改變它,你的應用程序可能會被打破。 – Tim

+1

我只是在測試類的類型,所以從接受的角度來看應該沒問題。它可能會在未來的操作系統更新中發生變化,但我不認爲這會很快發生,所以我個人確定。如果你願意的話,你總是可以嘗試找到另一種方法來檢查特定的視圖(例如,我的代碼的第一個版本,我看它的大小和位置)。 – tarmes

+0

我遇到了另一個使用我自己版本的解決方案的問題,後來出現了問題,因爲我推送了更多的視圖控制器,我不需要這麼高 - 關於如何將它變成更優雅的解決方案的任何想法? – Tim