2014-11-18 4 views
0

App (AppDelegate.m)이 시작될 때 생성되는 NSStatusItem 객체가 있습니다. 이 객체 "_statusBarItem"에는 NSMenu 클래스의 하위 클래스 인 statusBarMenu 클래스의 Menu가 첨부되어 있지만 아래에서 볼 수있는 것처럼 statusBarMenu의 인스턴스를 만들 때 (NSMenuItem 클래스의) _panelItem 속성도 있습니다. statusBarItem.mNSMenuItem 사용자 정의보기가 업데이트되지 않습니다.

- (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 초마다 호출됨을 알 수 있습니다. 새 시간으로 매 초마다 레이블을 업데이트해야하기 때문입니다. 그러나 PanelViewController의 뷰에 대해 setNeedsDisplay :를 호출하더라도 레이블이 업데이트되지 않습니다. 대신 잘못된 뷰 (예 : _panelItem의 뷰를 업데이트해야 함)를 업데이트했기 때문에 이것이 가능하다고 생각했습니다. 그래서 menuDelegate 속성을 만들고 statusBarMenu를 아래의 프로토콜 쇼와 일치하게 만들었습니다.

@protocol PanelViewControllerMenuDelgate 

- (void)refreshView:(id)obj; 

@end 

다시 한번 refreshView : 메서드가 호출되어 패널보기를 업데이트합니다.

- (void)refreshView:(id)obj{ 
[_panelItem.view setNeedsDisplay:YES]; 
// [self itemChanged:_panelItem]; 
} 

그러나보기를 새로 고치지 않고 새 라벨 값을 표시합니다. 또한 다른 결과가 없었지만 statusBarMenu obj (_statusBarItem) 자체에 itemChanged : 메서드를 시도했습니다.

내가주의 한 것은 다른 곳을 클릭하여 메뉴를 닫고 다시 열면 시계/레이블의 새 값이 표시된다는 것입니다. 그래서 내가 뭘 잘못하고 있는지, 아니면 내가 뭘하지 않는지, 그건보기를 똑같이 유지하는 것입니다. 내가 몇 초 동안 _panelItem의 뷰를 새로 고치려면 다른 절차를 사용해야합니까?

는 편집 :

는 또한 발견하는 시뮬레이션 정지 실행, 모든 _statusBarItem을 클릭합니다. tickload : 메소드에 NSLog 문을 추가하기 만하면 메뉴를 열 때 콘솔에서 인쇄가 중단되었습니다. 이것은 아마도 app/Xcode가 메뉴를 클릭 할 때 일시 중지되기 때문에보기가 업데이트되지 않는 이유 일 것입니다. 왜 그런 일이 일어날까요? 또한 어떻게 멈출 수 있습니까?

답변

0

몇 주 전에이 문제가 발생했습니다. 내 경우, NSTimer은 내 NSMenuItem을 업데이트하지 않았습니다. 메뉴가 다른 실행 루프에서 연기와 함께 업데이트되기 때문에 문제가 발생했다고 생각합니다. 이 질문에 대한 답변은 fewplaces입니다. 하지만 필요한 코드는 다음과 같습니다.

NSTimer interfaceUpdateTimer = [NSTimer timerWithTimeInterval:self.timerSettings.timerUpdateInterval//one second in your case 
             target:self 
                selector:@selector(tickTock:) 
             userInfo:nil 
             repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:interfaceUpdateTimer forMode:NSRunLoopCommonModes]; 

키는 NSRunLoopCommonModes입니다. 내가 링크 된 다른 답변을 확인하십시오. 그들은 이미 그것을 아주 잘 설명합니다. 그것은 내가 생각하는 트릭을해야한다. 보조 노트로


, 어느 것도 NSTimer이나 performSelector:withObject:afterDelay:사용자가 지정한 정확하게 시간에 화재을 보장합니다. 따라서 정확성이 필요하다면 시간을 말하기에 의존하지 마십시오.충분히 가까워지면이 메모를 무시할 수 있습니다.)