2012-05-09 2 views
2

메소드 또는 루프 내에서 NSWindow (Mac OS X) 및 UIView (iOS)의 배경색을 설정하는 데 큰 어려움이 있습니다. 배경색을 설정하는 코드는 루프의 마지막 코드 행에만 적용됩니다. i, j, k의 모든 값이 255 일 때 RGB의 적절한 혼합으로 화면이 흰색으로 변합니다. 사전에NSWindow 및 UIView BackgroundColor를 메서드 내 루프 내에서 반복 설정합니다.

`- (void) ChangeColorLoop 
{ 
for (int i=0; i<=255; i++) 
    for (int j=0; j<=255; j++) 
     for (int k=0; k<=255; k++) 
     { 
      [NSThread sleepForTimeInterval: 0.1]; 
      //NSLog(@"%d, %d, %d", i, j, k); 
      float red = (float) i/255; 
      float green = (float) j/255; 
      float blue = (float) k/255;  
      float alpha = 1.0f; 
      UIColor *mixedColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 
      //BackgroundView.backgroundColor = mixedColor; 
      [BackgroundView setBackgroundColor:mixedColor]; 
     } 
}` 

감사합니다,

제리 같은 의견이 주 스레드에서 실행에서 소리

+0

이 방법은 백그라운드 스레드에서 실행 : 당신이 GCD를 사용하는 경우

, 당신의 논리는 같은 것을 할 필요가? –

+0

모르겠지만 게시 한 것처럼 (무효) 대신 (IBAction)을 가정합니다. 단추를 클릭하면이 메서드가 실행되고 실행됩니다. – Jerry

답변

0

맨 끝. 이것이 바로 마지막 색만이 "필요한 것"입니다.

그래서 백그라운드 스레드에서 루프를 실행해야합니다. 그러나setBackgroundColor: 호출은 주 스레드에 있어야합니다 (UI 코드가있는 곳이므로).

-(void)changeColorLoop { 
    dispatch_async(backgroundqueue, ^{ 
    for (;;) { 
     // Do stuff 
     dispatch_sync(main_queue, ^{ 
     [BackgroundView setBackgroundColor:mixedColor]; 
     }); 
    } 
    }); 
} 
+0

다른 2 줄의 코드 "dispatch_queue_t main_queue = dispatch_get_main_queue(); dispatch_queue_t backgroundqueue = dispatch_queue_create ("com.app.request ", NULL);"에서 작동합니다. 굉장해, 다시금 고마워! – Jerry

0

. 나는 그것에 몇 가지 문제가 있음을 본다. 색상 변경을 보지 못하는 근본적인 이유는 루프가 주 스레드를 차단하고 있으며 실행 루프 사이클의 끝에서보기가 (일반적으로) 다시 그려지기 때문입니다. 그것은 전체 루프가 끝날 때까지는 발생하지 않습니다. 이를 해결하는 방법은 다양합니다. 가장 간단한 방법은 아마도 for 루프를 통해 매번 실행 루프를 수동으로 실행하는 것입니다. 이 작업을 백그라운드 스레드로 옮기고 setBackgroundColor: 호출을 기본 대기열로 보낼 수도 있습니다. 이렇게하는 또 다른 방법은 타이머 (NSTimer 또는 타이머 디스패치 소스)를 사용하여 주기적으로 색상을 업데이트하는 것입니다.

어쨌든 for 루프의 중간에서 주 스레드를 잠자 지 않아야합니다. 메인 스레드를 잠 그려면 좋은 이유가 거의 없기 때문에 UI가 사용자 입력 이벤트를 업데이트하거나 처리하는 것을 차단합니다.

편집 : 저는 여기에 언급 된 타이머 접근 방식을 보여주는 몇 가지 예제 코드는 다음과 같습니다

setBackgroundColor: 메시지는 당신의 코드가 될 때까지하지 않는 이벤트 루프에 반환 할 때 수행 할 액션 것입니다
@interface AppDelegate() 

@property (nonatomic, strong) NSTimer *colorChangeTimer; 
@property (nonatomic) float red; 
@property (nonatomic) float green; 
@property (nonatomic) float blue; 

@end 

@implementation AppDelegate 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     self.red = 0.5; 
     self.blue = 0.5; 
     self.green = 0.5; 
    } 
    return self; 
} 

- (void)updateColors:(NSTimer *)timer 
{ 
    NSColor *newColor = [NSColor colorWithDeviceRed:self.red green:self.green blue:self.blue alpha:1.0]; 
    [self.window setBackgroundColor:newColor]; 
    if (self.red >= 1.0) { 
     [self.colorChangeTimer invalidate]; 
     self.colorChangeTimer = nil; 
    } 
    if (self.green > 1.0) { 
     self.green = 0.0; 
     self.red += 0.01; 
    } 
    if (self.blue >= 1.0) { 
     self.blue = 0.0; 
     self.green += 0.01; 
    } else { 
     self.blue += 0.01; 
    } 
} 

- (IBAction)changeColors:(id)sender 
{ 
    if (self.colorChangeTimer != nil) return; 
    self.colorChangeTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateColors:) userInfo:nil repeats:YES]; 
} 

@synthesize window = _window; 
@synthesize colorChangeTimer = _colorChangeTimer; 
@synthesize red = _red; 
@synthesize green = _green; 
@synthesize blue = _blue; 

@end