[ios] 보기가 숨겨져있을 때 자동 레이아웃을 사용하여 다른보기를 이동하는 방법은 무엇입니까?


8 Answers

런타임 동안 제약 조건을 추가하거나 제거하는 것은 성능에 영향을 줄 수있는 헤비 웨이트 작업입니다. 그러나 더 간단한 대안이 있습니다.

숨길보기에 대해 너비 제약 조건을 설정하십시오. 다른 뷰를 해당 뷰와의 수평 방향의 갭으로 구속합니다.

숨기려면 width 제약 조건의 .constant.constant 로 업데이트하십시오. 다른 뷰는 자동으로 왼쪽으로 이동하여 위치를 취합니다.

자세한 내용은 내 다른 답변을 참조하십시오.

런타임 동안 레이블 제약 조건을 변경하는 방법?

Question

IB에서 내 사용자 지정 셀을 디자인하고 서브 클래 싱하여 사용자 지정 클래스에 콘센트를 연결했습니다. UIView (cdView)와 두 개의 레이블 (titleLabel 및 emailLabel)의 세 가지 하위 뷰가 있습니다. 각 행에 사용할 수있는 데이터에 따라 때로는 UIView와 두 개의 레이블이 내 셀에 표시되기도하고 때로는 두 개의 레이블 만 표시되기도합니다. UIView 속성을 hidden으로 설정하면 superview에서 두 개의 레이블이 왼쪽으로 이동합니다. 10px 및 10px 다음 뷰 (UIView) 제약 조건을 선도하는 UILabels Superview (셀 내용) UIView 선행 제약 조건을 설정하려면했습니다. 나중에 내 코드

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
...
Record *record = [self.records objectAtIndex:indexPath.row];

if ([record.imageURL is equalToString:@""]) {
     cell.cdView.hidden = YES;
}

내 cell.cdView를 숨기고 있습니다. 레이블이 왼쪽으로 이동하지만 셀의 동일한 위치에 머물러 있기를 바랍니다. superview에서 cell.cdView를 제거하려고했으나 작동하지 않았습니다. 나는 내가 무엇에 관한 것인지 밝히기 위해 이미지를 첨부했다.

이 방법을 프로그램 방식으로 수행하는 방법을 알고 있으며 그 해결책을 찾고 있지 않습니다. 내가 원하는 것은 IB에서 제약 조건을 설정하는 것이고 다른 뷰가 제거되거나 숨겨지면 내 하위 뷰가 동적으로 움직일 것으로 기대합니다. IB에서 자동 레이아웃으로이 작업을 수행 할 수 있습니까?

.....



uiview와 레이블 사이의 제약 조건을 IBOutlet으로 연결하고 우선 순위 멤버를 hidden = YES로 설정하면 더 적은 값으로 설정합니다.




no_scene이 제안했듯이, 런타임시 제약 조건의 우선 순위를 변경하여 확실히이 작업을 수행 할 수 있습니다. 제거해야 할 차단보기가 두 개 이상 있으므로이 작업이 훨씬 쉬워졌습니다.

다음은 ReactiveCocoa를 사용하는 스 니펫입니다.

RACSignal* isViewOneHiddenSignal = RACObserve(self.viewModel, isViewOneHidden);
RACSignal* isViewTwoHiddenSignal = RACObserve(self.viewModel, isViewTwoHidden);
RACSignal* isViewThreeHiddenSignal = RACObserve(self.viewModel, isViewThreeHidden);
RAC(self.viewOne, hidden) = isViewOneHiddenSignal;
RAC(self.viewTwo, hidden) = isViewTwoHiddenSignal;
RAC(self.viewThree, hidden) = isViewThreeHiddenSignal;

RAC(self.viewFourBottomConstraint, priority) = [[[[RACSignal
    combineLatest:@[isViewOneHiddenSignal,
                    isViewTwoHiddenSignal,
                    isViewThreeHiddenSignal]]
    and]
    distinctUntilChanged]
    map:^id(NSNumber* allAreHidden) {
        return [allAreHidden boolValue] ? @(780) : @(UILayoutPriorityDefaultHigh);
    }];

RACSignal* updateFramesSignal = [RACObserve(self.viewFourBottomConstraint, priority) distinctUntilChanged];
[updateFramesSignal
    subscribeNext:^(id x) {
        @strongify(self);
        [self.view setNeedsUpdateConstraints];
        [UIView animateWithDuration:0.3 animations:^{
            [self.view layoutIfNeeded];
        }];
    }];



수평 스택 뷰를 사용하겠습니다. 하위보기가 숨겨져 있으면 프레임을 제거 할 수 있습니다.

아래 이미지에서 빨간색보기는 내용물의 실제 컨테이너이며 주황색 수퍼 뷰 (ShowHideView)에 10pt 후행 공백을두고 ShowHideView를 IBOutlet에 연결하고 프로그래밍 방식으로 표시 / 숨기기 / 제거합니다.

  1. 보기가 표시 / 설치되는 경우입니다.

  1. 보기가 숨겨져 있거나 설치되지 않은 경우입니다.




스택의 일부 하위보기가 숨겨져있을 때 두 개의 UIStackView 가로 및 세로 사용 다른 스택 하위보기가 이동 될 때 두 개의 UILabel이있는 세로 스택에 대해 배분 -> 채우기 프로퍼티를 사용하고 첫 번째 UIView의 너비 및 높이 제한을 설정해야합니다.




UIStackViewhidden 속성이 하위 뷰 (iOS 9 이상)에서 변경되면 자동으로 뷰의 위치를 ​​변경합니다.

UIView.animateWithDuration(1.0) { () -> Void in
   self.mySubview.hidden = !self.mySubview.hidden
}

데모를 보려면이 WWDC 비디오에서 11:48 로 이동하십시오.

11:48




솔루션을 얻으려면 uiviews를 재정렬하는 방법은 다음과 같습니다.

  1. 하나의 UIImageView를 끌어다 놓고 왼쪽으로 옮깁니다.
  2. 하나의 UIView를 드래그하여 UIImageView의 오른쪽에 배치하십시오.
  3. 선행 및 후행 제약 조건이 0 인 UIView 내부에 두 개의 UILabels을 놓습니다.
  4. UIImagView 대신 슈퍼 뷰로 두 레이블을 포함하는 UIView의 선행 제약 조건을 설정하십시오.
  5. UIImageView가 숨겨져있는 경우 선행 제약 조건을 10px로 설정하여 수퍼바이저에게 보냅니다. ELSE의 경우 선행 제약 조건을 상수 값을 10 px + UIImageView.width + 10 px로 설정합니다.

내 엄지 규칙을 만들었 어. 제약 조건이 영향을받을 수있는 뷰를 숨기거나 표시해야 할 때마다 uiview 내에 영향을받는 종속 뷰를 모두 추가하고 프로그래밍 방식으로 선행 / 후행 / 위 / 아래 제약 조건 상수를 업데이트합니다.




Google 직원에게 : Max의 답변을 바탕으로 많은 사람들이 알아챈 패딩 문제를 해결하기 위해 간단히 라벨 높이를 높이고 실제 패딩 대신 구분 기호로 높이를 사용했습니다. 이 아이디어는보기가 포함 된 모든 시나리오에서 확장 될 수 있습니다.

다음은 간단한 예입니다.

이 경우 작성자 레이블의 높이를 적절한 IBOutlet 매핑합니다.

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

제약 조건의 높이를 0.0f 설정하면 재생 버튼의 높이가 허용하기 때문에 "패딩"을 유지합니다.




적절한 방법은 isActive = false를 사용하여 제약 조건을 해제하는 것입니다. 그러나 제약 조건을 비활성화하면 제거되고 해제되므로 강력한 아웃렛이 있어야합니다.




Related