2015-07-18 5 views
4

Когда вы создаете UINavigationController, вы можете показать скрытый по умолчанию скрытый UIToolbar через setToolbarHidden:animated: (или путем проверки панели «Показать панель инструментов в построителе интерфейса»). Это приводит к появлению панели инструментов в нижней части экрана, и эта панель инструментов сохраняется между нажатием и появлением контроллеров представления в стеке навигации. Это именно то, что мне нужно, за исключением того, что мне нужна панель инструментов для размещения на верхнем экрана. Оказывается, что это именно то, что компания Apple сделала с приложением ITunes:Переместите панель инструментов UINavigationController вверх, чтобы лежать под навигационной панелью

enter image description here

Как можно переместить панель инструментов UINavigationController «s к вершине, чтобы лежать под панелью навигации, а не на дне?

Я пытался реализовать UIToolbarDelegate, переопределить positionForBar: и вернуть UIBarPosition.TopAttached или UIBarPosition.Top после установки delegate из self.navigationController?.toolbar в self, но это даже не вызывается метод делегата поэтому он не изменил позицию бар.

Обратите внимание, что мне нужно, чтобы панель инструментов сохранялась между навигацией, поэтому я не могу просто добавить панель инструментов в контроллер просмотра и разместить ее под панелью навигации.

+0

Вы пытались изменить значение 'toolbar.frame.origin.y'? – Koen

ответ

0

Решением этой проблемы является два (с половиной) процессом шага:

Сначала вы должны добавить наблюдатель на Панель инструментов «центра» член.

Во-вторых, внутри observeValueForKeyPath: ofObject: изменение: контекст:, переместить панель инструментов для целевой позиции каждый раз, когда он перемещается кем-то (например контроллер навигации сам по себе, например, когда устройство вращается).

Я сделал это в своем подклассе UINavigationController. Чтобы избежать рекурсии, я установил локальный флаг «inToolbarFrameChange».

Последний (полу) шаг был немного сложным, чтобы узнать ... вы должны получить доступ к члену фрейма панелей инструментов, чтобы заставить наблюдателя вообще называться ... Наверное, причина для это может быть, что «кадр» реализован как метод внутри UIToolbar, а базовое значение «frame» в UIView обновляется только при вызове метода UIToolbar?!?

Я реализовал этот «кадр» доступ в моем перегруженном setToolbarHidden: анимированный: метод, который ничего не делает, кроме как переадресовывать вызов и получать доступ к значению фрейма панелей.

@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; 
} 
0

Вы можете создать не UITableViewController, а UIViewController. Ввиду UIViewController поместите UIToolBar ниже NavigationBar и UITableView. Делегируйте весь необходимый список UITableView в UIViewController и все. Почему вы должны использовать UIViewController вместо UITableViewController? Поскольку tableView не будет иметь элементов статических позиций. У вас должно быть что-то, что не содержит ScrollView. В этой ситуации это только UIView. Также вы можете взломать UIScrollView таблицыView, но я думаю, что описанный метод является более простым.

Смежные вопросы