2016-10-25 3 views
0

이상한 문제가 있습니다 : 테이블보기에서 UISlider이 변경되면 단일 셀을 업데이트하려고합니다 (값이 변경된 컨트롤 이벤트). 슬라이더의 값이 변경되는 순간, 버튼을 셀에 애니메이션으로 적용하려고합니다 (오른쪽에서 슬라이드). 버튼의 제약 상수를 -50으로 설정하여 기본적으로 표시되지 않도록하고 슬라이더의 값이 변경되면 메서드가 호출되어 테이블 뷰를 업데이트하므로 cellForRowAtIndexPath이 내 테이블의 모든 셀에 대해 다시 호출됩니다. 제약 상수가 변경되지만 레이아웃이 업데이트되지 않습니까?

func valueChanged(sender:UISlider) { 
    // Reload table view 
    self.myTableView.reloadData() 

    // Let table view know the value of the slider got modified 
    self.didChangeValueOfSlider = true 
} 

그리고 cellForRowAtIndexPath에 나가있는 세포의 슬라이더를 추적하고있어 사용자 정의 selectedCellIndexPath 변수를 사용하여 변경할있어

: 그것은 다음과 같이 보입니다 단순화. 다음 코드와 실행 : 테이블 뷰 수정있어 세포에 도달 할 때

// Check if cell is selected 
    if indexPath == self.selectedCellIndexPath { 

     // Check if value of slider was changed 
     if self.didChangeValueOfSlider == true { 

      // Value was changed: set constraint back to default 
      saveButtonTrailingConstraint.constant = CGFloat(15) 
      self.view.setNeedsUpdateConstraints() 
      self.view.updateConstraintsIfNeeded() 

      // Reset slider update status 
      self.didChangeValueOfSlider = false 
     } 
    } 

setNeedsUpdateConstraints()updateConstraintsIfNeeded()이 과도하거나 불필요한 수 있습니다 호출을하지만,이 제 15 시도 정도 실제로 얻을 유의하시기 바랍니다 보기를 클릭하여 업데이트 된 레이아웃을 표시합니다. 위의 코드가 실행 완료되고 모든 것이 완벽하게 작동 한 후에 상수가 실제로 변경된다는 것을 확인하기 위해 중단 점을 사용했습니다. 내가 일할 수없는 유일한 부분은 업데이트 부분입니다. 나는 변화를 움직이기 위해 UIView.animateWithDuration을 시도했고, 테이블보기의 layoutIfNeeded()beginUpdates()endUpdates과 같은 방법을 시도했습니다. 아무 효과가 없습니다. 레이아웃이 업데이트되지 않는 이유는 무엇일까요? 그리고 layoutupdate 메서드를 어떻게 호출해야합니까? 나는 그들에게 self.view을 호출했지만 테이블 뷰 셀의 레이아웃을 업데이트하려고한다면보기에 호출해야하는지 확실하지 않습니다. 어떤 도움을 주시면 감사하겠습니다.

+0

"gotcha"는 주 스레드에서'reloadData'를 호출하지 않으므로 UI가 업데이트되지 않는다는 것입니다. 'valueChanged' 또는'cellForRowAtIndexPath' 메쏘드에서 중단 점을 설정하고 어떤 쓰레드가 실행 중인지 (thread 1, com.apple.main-thread 여야 함) 디버거에서 체크하는 경우를 볼 수 있습니다. 희망도 그게 네 문제 야 :) – pbodsk

+0

@pbodsk 아니요, 주 스레드는 확실히 문제가 아닙니다. 하나는 다른 스레드에서 다른 코드를 실행하지 않기 때문에 reloadData는 다른 스레드와 마찬가지로 주 스레드에서 호출됩니다. 두 가지, 문제가있는 경우 UI는 여전히 약간의 지연만으로 업데이트됩니다 (주 스레드의 코드가 먼저 실행되기 때문에). 그러나, 제 경우에는 UI가 전혀 업데이트되지 않습니다. 그리고 마지막으로, 중단 점을 설정하지 않아도 배경 스레드에서 레이아웃을 변경하는 경우 디버거에서 경고 메시지를 표시합니다. 나는 전혀 경고하지 않는다. –

+0

좋아, 그냥 그런 경우에 확인 가치가 있다고 생각 : – pbodsk

답변

0

나는 그것을 알아 냈다. 문제는 그 자체가 제약으로 밝혀졌습니다. 내가 틀린 것을 접근하고 있었던 것에 따라. 나는 그것을 saveButtonTrailingConstraint으로 정의했지만 실제로는 saveButton의 너비 제약 (분명히 움직일 수 없음)이 수정되었습니다. saveButton.constraints[indexOfTrailingConstraint]에 액세스하는 대신 제약 조건이 버튼 자체가 아닌 수퍼 뷰에 속하기 때문에 saveButton.superview!.constraints[indexOfTrailingConstraint]을 정의해야합니다. 이 서투른 실수에서 벗어나는 것이 가장 좋은 방법은 프로그래밍 방식으로 올바른 제약 조건을 수정하는지 항상 확인하는 것입니다. 프로그래밍 방식으로 수행하는 경우 항상 첫 번째 눈에 표시되지 않기 때문입니다.