2015-01-17 3 views
0

내가 뭘하려하는지 간단하게 보이지만 구현이 나를 던지고있다. 값을 변경 한 후 레이블을 강제로 새로 고칠 수 있습니까?NSTextField 레이블을 강제로 새로 고침하는 방법

방금 ​​간단한 진행 창을 만들었습니다. 주 앱이 무언가를하고있는 중이므로 진행 창을 팝업하고 루프가 실행될 때 레이블 및 진행률 막대의 값을 업데이트하려고합니다.

내가 라벨과 진행 막대에 매장을 가진 새 NSWindow 표시 및 XIB 파일을 생성 나는이 그것을로드 해요 :

_pbWindow       = [[ProgressBar alloc] initWithWindowNibName:@"ProgressBar"]; 

[_pbWindow showWindow:self]; 

내가 전화 할 때 :

_pbWindow.lblProgress1.stringValue = @"Doing this now..."; 

내가 할 수있는 새 창에서 실제로 새로 고칠 레이블을 얻지 못합니다.

여기서는 Google을 검색하여 다른 창에서이를 수행하는 방법을 찾을 수없는 것 같습니다. 메인 창에있는 경우에는 항상 새로 고침이됩니다 (항상 내 경험 이었기 때문에). 어쨌든).

[[NSApplication sharedApplication] beginSheet:[_pbWindow window] 
           modalForWindow:[[NSApplication sharedApplication] mainWindow] 
           modalDelegate:_pbWindow 
           didEndSelector:nil 
            contextInfo:nil]; 

을 그리고 여전히 작동하지 않습니다 :

나는 창에 포커스가하지 않았기 때문에 내가 모달을 열기 시도 그래서 그것이 어쩌면 생각했다.

답변

2

텍스트 필드를 stringValue으로 설정하면 텍스트 필드가 표시가 필요한 것으로 표시됩니다 (-setNeedsDisplay... 메서드 중 하나). 즉시 표시되지는 않습니다. 나중에 메인 이벤트 루프 동안 응용 프로그램은 각 창에 -displayIfNeeded을 알리고 텍스트 필드의 새로운 내용이 실제로 화면에 그려집니다.

그러나 장기 실행 루프이므로 기본 이벤트 루프가 실행되지 않으며 필요한 경우 창에 표시 할 기회가 없습니다.

_pbWindow.lblProgress1.stringValue = @"Doing this now..."; 
[_pbWindow.lblProgress1 displayIfNeeded]; 

그러나, 메인 이벤트 루프 실행을 허용하지 않습니다 다른 문제가 있습니다 :

한 가지 해결 방법은 당신이 stringValue을 변경 한 후 직접 텍스트 필드에 -displayIfNeeded를 호출하는 것입니다. 이 문제를 해결하는 것만으로도 여전히 다른 문제를 해결할 수 있습니다. 예를 들어, 앱이 활동 모니터에서 응답 없음으로 표시되고 마우스가 창 위에있을 때 시스템이 회전하는 색상환 커서를 표시합니다. 앱을 구성하는 또 다른 방법을 찾는 것을 고려해야합니다.

예를 들어 진행 창을 기본 스레드 (-[NSApplication runModalForWindow:] 사용)의 모달 창으로 실행하고 백그라운드 스레드에서 작업 할 수 있습니다. 작업이 완료되면 -[NSApplication stopModal...] 메소드 또는 -[NSApplication abortModal] 중 하나를 호출하십시오. 그러나 어떤 상황에서 사용해야하는지 알 수 있도록 설명서를 읽으십시오 (단, -stopModal...의 일부 제한은 10.9에서 해제되었지만). 주 스레드는 메인 이벤트 루프로 돌아갈 수 있지만 모달 창은 사용자가 나머지 UI를 수행하지 못하도록하여 작업이 진행되는 동안 수행 할 수 없도록해야합니다.

또는 작업이 실제로 전체 앱을 독점해서는 안됩니다. 어쩌면 하나의 창에 모달이어야합니다. 이 경우 작업 진행 중에 비활성화해야하는 창에 진행 창을 시트로 표시 할 수 있습니다.-[NSWindow beginSheet:completionHandler:]을 사용하여 시트를 시작하고 백그라운드에서 작업을 시작하십시오. 작업이 완료되면 주 스레드에서 -[NSWindow endSheet:...] 메서드 중 하나를 호출하십시오.

배경 스레드에서 작업을 실행하는 경우 GCD 및 dispatch_get_main_queue() 또는 -performSelectorOnMainThread:...을 사용하여 GUI에 영향을주는 모든 변경 사항을 주 스레드에 항상 분로해야합니다.

+0

환상적인 답변을 보내 주셔서 감사합니다. 두 솔루션 모두 잘 작동하므로 어느 쪽이 끝날 지 확신 할 수 없지만 displayIfNeeded 메서드를 사용하여 해당 요구 사항이 충족되는지 확인합니다. – C4W

관련 문제