2015-01-18 8 views
1

저는이 한 인스턴스에 대해 로더를 사용하는 대신 사용자에게 무엇인가가 발생했음을 알리기 위해 사용하고 싶은 UIButton 설정을 가지고 있습니다.UIButton 비활성화 상태가 즉시 바뀌지 않습니다.

그래서 예를 들어 UIControlStateNormal가 있습니다
배경 녹색
제목 텍스트 흰색
제목 - 그럼

보내기를 클릭 UIControlStateDisabled 있습니다
배경 화이트
제목 텍스트 녹색
제목 -

보내기

버튼을 클릭하면 버튼이로 업데이트됩니다..

문제
내가주의 문제는 버튼이 비활성화 (활성화 NO)로 변경 될 때 모든 방법이 너무 너무, 완료 등을 호출 할 때까지 제목 텍스트, 색상, 배경에 대한 변경이 완료되지 않은 것입니다 늦은.

btn layoutIfNeeded 및/또는 btn setNeedsLayout을 사용하는 다른 스레드를 읽었습니다. 이것은 실제로 버튼을 강제로 업데이트하지만 다른 모든 호출/메소드가 완료 될 때까지는 발생하지 않는 것 같습니다. 따라서 버튼 텍스트 등을 업데이트하기에는 너무 늦었습니다.

버튼 상태와 속성을 바로 업데이트하고 다른 작업을 완료하는 방법에 대한 아이디어가 있습니까? 나는 주 스레드와 모든 업데이트/호출에 문제가 없는지 확인했다.

편집
버튼을 우리가 상태 업데이트 도청 기본적 때

- (IBAction)sendFeedbackButtonPressed:(id)sender { 
    DebugLog(@"selected: %@",self.sendFeedbackButton.selected ? @"Yes" : @"No"); 
    DebugLog(@"highlighted: %@",self.sendFeedbackButton.highlighted ? @"Yes" : @"No"); 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self shouldFeedbackButtonBeEnabled:NO]; 
     DebugLog(@"enabled: %@",self.sendFeedbackButton.enabled ? @"Yes" : @"No"); 
    }); 

    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSString *errorMessage = [self validateForm]; 

     if (errorMessage) { 
      [[[UIAlertView alloc] initWithTitle:nil message:errorMessage delegate:nil cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"Feedback Form Validation Error Ok Button", nil), nil] show]; 
      [self shouldFeedbackButtonBeEnabled:YES]; 
      return; 
     } 

     //TODO: send it 
     // Send the form values to the server here. 
     [self sendFeedbackToParse]; 
    }); 
} 

-(void)setupSendFeedbackButton { 
    UIColor *mainColor = [UIColor colorWithRed:41/255.0f green:128/255.0f blue:185/255.0f alpha:1]; 

    self.sendFeedbackButton.clipsToBounds = YES; 
    self.sendFeedbackButton.layer.cornerRadius = 5.0f; 
    self.sendFeedbackButton.layer.borderWidth = 2; 
    self.sendFeedbackButton.layer.borderColor = mainColor.CGColor; 

    // Disabled State 
    [self.sendFeedbackButton setBackgroundImage:[WTNUtility imageFromColor:[UIColor whiteColor]] forState:UIControlStateDisabled | UIControlStateHighlighted]; 
    [self.sendFeedbackButton setTitle:NSLocalizedString(@"Feedback Form Send Feedback Button - Sending feedback disabled state", nil) forState:UIControlStateDisabled | UIControlStateHighlighted]; 
    [self.sendFeedbackButton setTitleColor:mainColor forState:UIControlStateDisabled | UIControlStateHighlighted]; 

    // Normal State 
    [self.sendFeedbackButton setBackgroundImage:[WTNUtility imageFromColor:mainColor] forState:UIControlStateNormal]; 
    [self.sendFeedbackButton setTitle:NSLocalizedString(@"Feedback Form Send Feedback Button Title", nil) forState:UIControlStateNormal]; 
    [self.sendFeedbackButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 
} 

-(void)shouldFeedbackButtonBeEnabled:(BOOL)decision { 
    BOOL currentState = self.sendFeedbackButton.enabled; 

    if (currentState == decision) { 
     return; 
    } else { 
     self.sendFeedbackButton.enabled = decision; 
     [self.sendFeedbackButton layoutIfNeeded]; 
    } 
} 

-(void)sendFeedbackToParse { 
    DebugLog(@"%s",__PRETTY_FUNCTION__); 
    DebugLog(@"button is enabled: %@",self.sendFeedbackButton.enabled ? @"Yes" : @"No"); 
    DebugLog(@"highlighted: %@",self.sendFeedbackButton.highlighted ? @"Yes" : @"No"); 
// sleep(10); 

// self.sendFeedbackButton.enabled = YES; 
} 
+0

그것을 실행하는 첫 번째 것은 그래서 방법의 상단에있는 버튼의 스타일을 변경하는 코드를 넣습니다. –

+0

@Varosion 실행 첫 번째예요 – StuartM

답변

3

메인 큐 확인에 대한 올바른 궤도에있어,하지만 당신의 추가 처리는 UI가 오기 전에 완료해야 업데이트 기회.

코드가이 접근법에 친숙하면 주 큐에 두 개의 디스패치 블록을 사용하십시오. 첫 번째는 UI 상태 설정이고, 두 번째는 나머지 처리입니다. 이렇게하면 추가 처리가 완료되기 전에 UI 상태가 실제로 업데이트됩니다.

의사 코드 :

- (IBAction) handlePress:(id)sender { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
// Do your state update (button disabled, etc) 
         }); 

    dispatch_async(dispatch_get_main_queue(), ^{ 
// Do your further processing - AFTER the ui has been updated 
         }); 
} 
+0

고마워, 어떻게 생각하세요? 우리가 실행하는 프로세스는 너무 집중적이고 충분히 친숙하지 않습니다. 기본적으로 우리는 데이터가 어딘가에 전달되면 통과하는지 확인하는 몇 가지 검증/오류를 수행합니다. 어떻게 메인에 파견 블록 2 개가 있니? 예를 들어 몇 가지 코드로 질문을 업데이트 할 수 있습니다 – StuartM

+0

Udpated, 그래서 추가 문자 ... – StuartM

+0

동시에 편집하는 것처럼 보입니다. 수정 된 답변을 살펴보십시오. 이 점이 더 명확하거나 더 필요합니까? –