2014-10-22 1 views
16

사전에 내가 원하는 바가 있지만 실제로 만족할만한 방식으로 표시되지 않았다는 것을 알았습니다. 지금은 제약 조건을 "깨뜨린"상태로 유지해야합니다. 제대로 업데이트되고 있습니다.자동 레이아웃 제약 조건을 프로그래밍 방식으로 변경 한 후보기가 업데이트되지 않음

UITableView를 보유하고있는 ViewController가 있습니다. tableView의 높이는 0 (표시되지 않음)에서 보유하는 행 수와 관계없이 다양 할 수 있습니다. 높이는 현재 행의 수에 행의 높이를 곱하여 ViewController의 viewDidLoad()에서 계산됩니다.

내가 먼저 시도한 것은 @IBOutlet weak var tableHeightConstraint: NSLayoutConstraint!을 스토리 보드에 설정된 높이 제약 조건에 연결하는 것입니다. 그냥 어떤 임의의 초기 높이를 가지고 있지만 필요한 경우 뷰 업데이트 방법 다음에의 ViewController의 viewDidLoad() 내에서 올바른 값으로 업데이트됩니다

tableHeightConstraint = NSLayoutConstraint(item: tableView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0, constant: calculatedTableViewHeight) 

// At this point I've tried a variety of methods like the following two but actually none has worked for me 
view.layoutIfNeeded() 

// or 
view.updateConstraints() 

// or 
view.layoutSubviews() 

을 ... 그리고있는 tableView에 심지어 같은 방법은 확실하게 이 모든 것을 viewDidLayoutSubviews()에 넣는 것뿐입니다.

그래서 다음과 같은 제약 조건을 위와 같이 작성했지만 업데이트하는 대신 방금보기에 추가했습니다. view.addConstraint(tableHeightConstraint). 이것은 실제로 원하는 시각적 효과가 있었지만 로그에서이 두 높이 제약 조건의 충돌로 인해 초기 높이가 깨졌습니다. 내 목표는 정확하고 깨끗한 코드를 얻는 것이므로 계속 노력하고 있습니다. 그래서 이번에는 먼저 조정 된 것을 다시 추가하기 전에 뷰에서 제약 조건을 제거했습니다. 시각적으로, 다시, 모든 것이 완벽했지만 여전히 상충되는 제약을 제거하지 못했습니다.

내 실제 질문은 (내가 지금까지 잘못하고 있었던 것 외에) 내가 할 수있는 방법 - 가능한 한 - 기존의 제약 조건을 업데이트하고 어떤 시점에서든 뷰와 하위 뷰의 적절한 갱신/처음 뷰를로드 할 때 또는 사용자가 상호 작용할 때 일부 제약 조건을 변경하려고하는지 여부를 나타냅니다. 어떤 도움을 주셔서 감사합니다!

+0

새 제약 조건에 속성을 설정해도 이전 제약 조건이 제거되지는 않습니다. 포인터를 새 제약 조건으로 설정하면 충돌하는 제약 조건이 발생합니다. 당신은 @ cmyr의 답과 같이해야합니다. – rdelmar

+0

@rdelmar 좋아, 설명해 주셔서 감사합니다! 그러나 왜 view.removeConstraint (tableHeightConstraint)에 갈 때 여전히 충돌이 있었고 새로운 것을 생성하고 view.addConstraint (tableHeightConstraint)에 의해 뷰에 다시 추가 했는가? 그냥 이유를 이해하기 위해서 ... –

+1

그 진술의보기 란 무엇입니까? 컨트롤러의 self.view입니까? 스토리 보드에서 높이 제한을 설정하면 높이를 설정 한보기, 사례보기의 테이블보기 (수퍼 뷰가 아님)에 추가됩니다. 시도해 봤나? self.tableView.removeConstraint (tableHeightConstraint)? 새 테이블 뷰도 테이블 뷰에 추가해야합니다. – rdelmar

답변

29

현재 현재 제약 조건을 업데이트하는 대신 새 제약 조건을 할당합니다. 새 제한 조건도 뷰 계층 구조에 추가되지 않았습니다.

당신이 IB에서 설정 한 제약 조건이 좋은 방법이지만, 그 대신 VAR에 새로운 제약 조건을 할당하는, 당신은 단지 제약의 일정 수정해야 참조하기 위해 함께 IBOutlet을 사용하여 귀하의 접근 방식 :

tableHeightConstraint.constant = calculatedTableHeight합니다.

Constraint를 변경하면 Constraint가 자동으로 레이아웃 패스를 호출하기 때문에 layoutIfNeeded()를 호출 할 필요가 없습니다. updateConstraints()layoutSubviews()은 분명히 원하는 것이 아닙니다.

+0

2 개의 모드를보다 우아하게 토글하기 위해 다른 제약 조건을 참조하기 위해 포인터를 간단히 변경할 수 있어야합니다. 그러나 어떤 업데이트 메시지라도 새로 참조 된 제약 조건이 이전의 제약 조건을 대체하게 만들지는 않습니다. 모드를 변경하려고 할 때마다 문제의 제약 조건을 추가하고 제거해야하는 번거 로움이 있습니까? – Michael

+0

@Michael : 당신이 제약 조건을 가지고있는 참조는 당신이 사용하기위한 것입니다; 뷰에 제약 조건을 추가하고 뷰에 제약 조건을 저장하지 않으면 여전히 뷰에 추가됩니다. – cmyr

+0

예, 이해가됩니다. 뷰의 제약 조건을 단순히 항목 배열로 생각할 때 이해하기 쉽습니다. IBOutlet에 연결된 XIB 제약 조건은 제약 조건을 초기화하고 첫 번째로드시 제약 조건에 추가하는 방법 일뿐입니다. 컨트롤러의 포인터를 변경해도 배열에있는 내용은 변경되지 않지만 제약 조건 (즉, 상수)의 속성을 변경하면 값이 변경되고 실제 효과가 있습니다. – Michael

관련 문제