У меня есть объект NSStatusItem, который создается при запуске приложения (в AppDelegate.m). К этому объекту «_statusBarItem» прикреплено меню класса statusBarMenu, которое является подклассом класса NSMenu, но у него также есть свойство _panelItem (класса NSMenuItem), созданное при создании экземпляра statusBarMenu, как вы можете видеть ниже.
В statusBarItem.m
- (instancetype)initWithTitle:(NSString *)aTitle{
self = [super initWithTitle:aTitle];
if (self){
_panelItem = [[NSMenuItem alloc]init];
PanelViewController *panelViewController = [[PanelViewController alloc]init];
panelViewController.menuDelegate = self;
_panelItem.view = panelViewController.view;
[self addItem:_panelItem];
}
return self;
}
_PanelItem имеет настраиваемый вид, то есть часы в метке (среди прочего). Это представление контролируется классом PanelViewController, в котором при вызове метода viewDidLoad вызывается метод tickTock :, показанный ниже. _upTime - это метка, показывающая часы / время. Он создается в файле .xib и подключается
- (void)tickTock:(id)obj{
NSTimeInterval timeInterval = 7.5 * 60 * 60;
NSDate *timeToGetUp = [NSDate dateWithTimeInterval:timeInterval sinceDate:[NSDate date]];
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:@"hh:mm:ss"];
[_upTime setStringValue:[dateFormatter stringFromDate:timeToGetUp]];
[self.view setNeedsDisplay:YES];
[self.menuDelegate refreshView:self];
[self performSelector:@selector(tickTock:) withObject:NULL afterDelay:1.0];
}
Как видите, метод tickTock: вызывается каждые 1,0 секунды. Это потому, что я хочу, чтобы метка обновлялась каждую секунду с новым временем. Однако метка не обновляется, хотя я вызываю setNeedsDisplay: для представления PanelViewController. Я подумал, что это могло быть потому, что я мог обновлять неправильное представление, т.е. мне нужно было вместо этого обновлять представление _panelItem. Итак, я создал свойство menuDelegate и сделал statusBarMenu соответствующим протоколу, показанному ниже.
@protocol PanelViewControllerMenuDelgate
- (void)refreshView:(id)obj;
@end
Опять же, метод refreshView: вызывается каждую секунду, он обновляет представление панели.
- (void)refreshView:(id)obj{
[_panelItem.view setNeedsDisplay:YES];
// [self itemChanged:_panelItem];
}
Однако это по-прежнему не обновляет представление и не отображает новое значение метки. Я также попробовал метод itemChanged: для самого объекта statusBarMenu (_statusBarItem), хотя он не дал других результатов.
Что я заметил, так это то, что если я закрою меню (щелкнув в другом месте) и снова открою его, оно покажет новое значение часов / метки. Итак, что я делаю не так, или что я не делаю, что заставляет представление оставаться прежним. Должен ли я использовать какую-то другую процедуру, чтобы представление _panelItem обновлялось каждую секунду?
РЕДАКТИРОВАТЬ:
Я также заметил, что симуляция перестает работать, когда каждый щелчок по _statusBarItem. Я просто добавил оператор NSLog в метод tickTock:, и он перестал печатать в консоли, когда я открываю меню. Вероятно, поэтому представление не обновляется, поскольку приложение / Xcode приостанавливается, когда я нажимаю на меню. Почему так случилось? Также как я могу это остановить?