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


333

IB에서 사용자 정의 셀을 디자인하고 서브 클래스 화하고 콘센트를 사용자 정의 클래스에 연결했습니다. 셀 내용에 세 가지 하위보기가 있습니다 : UIView (cdView)와 두 개의 레이블 (titleLabel 및 emailLabel). 각 행에 사용 가능한 데이터에 따라 때로는 셀에 UIView와 두 개의 레이블이 표시되고 때로는 두 개의 레이블 만 표시하려고합니다. 내가하려고하는 것은 UIView 속성을 숨김으로 설정하면 제약 조건을 설정하는 것입니다. 또는 슈퍼 뷰에서 제거하면 두 레이블이 왼쪽으로 이동합니다. UIView 주요 제약 조건을 10px의 Superview (Cell content)로 설정하고 UILabels 주요 제약 조건을 10px의 다음보기 (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를 숨기고 레이블을 왼쪽으로 옮기고 싶지만 Cell에서 동일한 위치에 있습니다. superview에서 cell.cdView를 제거하려고 시도했지만 작동하지 않았습니다. 나는 내가 무엇에 관한 것인지 명확히하기 위해 이미지를 첨부했다.

세포

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

.....

제약 조건 값 런타임 변경-이 답변
Kampai

이 특정 경우에는 UIStackView를 사용할 수도 있습니다. 당신이 CD를 숨길 때, 라벨은 자신의 공간을 차지합니다
마르코 파 팔라도

답변:


373

가능하지만 약간의 추가 작업이 필요합니다. 먼저 해결해야 할 몇 가지 개념이 있습니다.

  • 숨겨진 뷰는 그리지 않더라도 여전히 자동 레이아웃에 참여 하고 일반적으로 프레임을 유지하여 다른 관련 뷰를 제자리 에 둡니다.
  • 수퍼 뷰에서 뷰 를 제거하면 해당 뷰 계층 구조에서 모든 관련 구속 조건 도 제거됩니다.

귀하의 경우 이는 다음을 의미합니다.

  • 왼쪽보기를 숨기도록 설정하면 왼쪽보기가 여전히 공간을 차지하므로 레이블이 그대로 유지됩니다 (보이지 않아도).
  • 왼쪽보기를 제거하면 레이블의 왼쪽 가장자리에 더 이상 제약이 없으므로 레이블이 모호하게 제한 될 수 있습니다.

라벨을 신중하게 과도 하게 제한 해야합니다. 기존 제약 조건 (다른보기에 10pts 공간) 만 남겨두고 다른 제약 조건을 추가하십시오. 레이블의 왼쪽 가장자리를 10views를 슈퍼 뷰의 왼쪽 가장자리에서 10ds의 우선 순위로 두십시오 (기본 우선 순위가 높을 수 있음).

그런 다음 왼쪽으로 이동하려면 왼쪽보기를 모두 제거하십시오. 왼쪽 뷰에 대한 필수 10pt 제약 조건은 관련 뷰와 함께 사라지고 레이블이 상위 뷰에서 10pt 떨어져 있다는 우선 순위가 높은 제약 조건 만 남게됩니다. 다음 레이아웃 패스에서는 슈퍼 뷰의 너비를 채울 때까지 왼쪽으로 확장되지만 가장자리 주위의 간격이 유지됩니다.

한 가지 중요한 경고 : 그림에서 왼쪽보기를 다시 원할 경우 다시보기 계층 구조에 다시 추가해야 할뿐만 아니라 동시에 모든 제약 조건다시 설정해야합니다 . 즉, 해당 뷰가 다시 표시 될 때마다 뷰와 해당 레이블 사이에 10pt 간격 제약 조건을 설정하는 방법이 필요합니다.


8
이 답변은 확실히 작동하지만, 다양한 사용 사례를 처리하기위한 과도한 제약 조건은 코드 냄새로 보입니다. 특히 뷰를 다시 표시하려는 제거 된 뷰에 대한 모든 제약 조건을 다시 설정해야하기 때문에 특히 그렇습니다.
memmons

제 생각에는 이것이 갈 길이 아닙니다. 대신 숨길 뷰에 너비 / 높이 제약 조건을 사용해야합니다.
ullstrm

26
나는 정중하게 동의하지 않습니다. 예를 들어 뷰의 너비를 0으로 설정하면 두 가지 문제가 발생합니다. 먼저, 이제 슈퍼 뷰와 보이는 뷰 사이에 이중 간격이 있습니다 : |-(space)-[hidden(0)]-(space)-[visible]is 효과적으로 |-(2*space)-[visible]. 둘째, 해당 뷰는 자체 뷰 하위 트리 및 제약 조건에 따라 제약 조건 위반이 발생하기 시작할 수 있습니다. 뷰의 너비를 임의로 0으로 제한하고 계속 작동하도록 보장 할 수는 없습니다.
Tim

1
고유 한 콘텐츠 크기로보기를 사용하는 경우 Tim의 대답은 독특한 방법으로 보입니다.
balkoth

고마워 팀 제약 조건 비 호환성을 피하기 위해 우선 순위가 높은 제약 조건 0을 설정했지만 이제는 이중 간격에 문제가 있음을 알았습니다. 두 가지 견해를 함께 보여주지 않기 때문에 그 문제가 없었습니다 (내 경우 |-[otherViews]-[eitherThis][orThis]-|:).하지만 결국 그 문제에 부딪 쳤습니다.
Ferran Maylinch

207

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

숨길 뷰에 너비 제한을 설정하십시오. 다른 뷰를 해당 뷰와의 수평 간격으로 제한합니다.

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

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

런타임 중에 레이블 제약 조건을 변경하는 방법은 무엇입니까?


29
이 솔루션의 유일한 문제는 왼쪽 여백이 원하는 것의 두 배가 될 것이므로 이러한 제약 조건 중 하나도 업데이트하지만 하위 뷰를 제거하는 것보다 덜 효과적이라고 생각합니다.
José Manuel Sánchez

2
@ skinsfan00atg 고유 한 콘텐츠 크기의보기를 사용하는 경우이 솔루션을 사용할 수 없습니다.
balkoth

@balkoth 왜 안돼? 콘텐츠 포옹 우선 순위를 줄일 수 있습니다
Max MacLeod

2
@MaxMacLeod 컨텐츠 껴안기 우선 순위를 줄이면 고유 컨텐츠 크기를 사용하지 않고 제약 조건으로 표시된 크기를 사용하고있는 것입니다.
balkoth

2
@MaxMacLeod 자, 무슨 말인지 알았습니다. 뷰를 숨기거나 해당 값을 다시 표시하려는 경우 코드에서 압축 저항 우선 순위를 0 (콘텐츠 포옹이 아님)으로 설정해야합니다. 그 외에도 인터페이스 빌더에서 제약 조건을 추가하여 뷰의 크기를 0으로 설정해야합니다. 코드에서이 제약 조건을 건드릴 필요가 없습니다.
balkoth

87

iOS 8 이상 만 지원하는 사용자에게는 새로운 부울 속성이 활성화되어 있습니다. 필요한 제약 조건 만 동적으로 활성화하는 데 도움이됩니다.

PS 제약 조건 출구는 약하지 않고 강해야 합니다

. 예 :

@IBOutlet weak var optionalView: UIView!
@IBOutlet var viewIsVisibleConstraint: NSLayoutConstraint!
@IBOutlet var viewIsHiddenConstraint: NSLayoutConstraint!

func showView() {
    optionalView.isHidden = false
    viewIsVisibleConstraint.isActive = true
    viewIsHiddenConstraint.isActive = false
}

func hideView() {
    optionalView.isHidden = true
    viewIsVisibleConstraint.isActive = false
    viewIsHiddenConstraint.isActive = true
}

또한 스토리 보드의 오류를 수정하려면 Installed이러한 제약 조건 중 하나에 대한 확인란 을 선택 취소해야합니다 .

UIStackView (iOS 9+)
또 다른 옵션은에서 뷰를 래핑하는 것입니다 UIStackView. 보기가 숨겨지면 UIStackView레이아웃이 자동으로 업데이트됩니다


활성 부분적으로 작동합니다. 그러나 재사용 가능한 셀 내에서 활성화에서 비활성화까지 사용하면 작동하지만 비활성화를 위해 활성화하지는 않습니다. 어떤 아이디어? 아니면 예를 들어 줄 수 있습니까?
Aoke Li

10
비활성화 된 구속 조건이로드 또는 할당 해제되지 않았기 때문에 발생합니다. 귀하의 제약 콘센트, 약한하지 강해야한다
Silmaril

"활성"속성을 어디에서 찾을 수 있습니까?
Lakshmi Reddy


과도한 제약 + 설정된 구속 조건 활동이 가장 합리적인 답이 될 수 있습니다.
Ting Yi Shih

68

UIStackViewhidden하위 뷰 (iOS 9+) 에서 속성이 변경 되면 뷰가 자동으로 재배치됩니다 .

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

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

자동 레이아웃의 미스터리, 1 부


중첩 스택 뷰를 숨기고 전체 스택 뷰가 사라졌습니다.
Ian Warburton

5
이것은 정답입니다. 인터페이스 빌더 디자인에 대한 wwdc 2015의 애플 명령에 따름
thibaut noah

@thibautnoah 그리고 iOS 8 지원은 어떻습니까?
bagage

5
@bagage 페이스 북이나 구글이 아니라면 드롭 할 수 있습니다. iOS 9 이후의 범위를 사용하면 장치의 90 % 이상을 충분히 지원할 수 있습니다. 아래 지원하는 것은 개발 과정을 무력화 당신은 IMO 최신 기능을 사용하지 못하도록 할 것이다
의 Thibaut 노아

16

내 프로젝트는 (컬러, 글꼴, 삽입 등의 일관성을 보장하기 위해) 사용자 정의 @IBDesignable하위 클래스를 사용하며 UILabel다음과 같은 것을 구현했습니다.

override func intrinsicContentSize() -> CGSize {
    if hidden {
        return CGSizeZero
    } else {
        return super.intrinsicContentSize()
    }
}

이를 통해 레이블 서브 클래스가 자동 레이아웃에 참여할 수 있지만 숨겨진 경우 공간을 차지하지 않습니다.


13

Google 직원의 경우 : Max의 답변을 바탕으로 많은 사람들이 발견 한 패딩 문제를 해결하기 위해 레이블 높이를 높이고 실제 패딩 대신 높이를 구분자로 사용했습니다. 이 아이디어는 뷰를 포함하는 모든 시나리오에서 확장 될 수 있습니다.

다음은 간단한 예입니다.

IB 스크린 샷

이 경우 Author 레이블 의 높이를 적절한 IBOutlet다음에 매핑합니다 .

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

구속 조건의 높이를로 설정 0.0f하면 '패딩'이 유지됩니다. 재생 버튼의 높이가 허용하기 합니다.


새로운 사람들을 위해 귀하 NSLayoutConstraintconstant속성 을 업데이트하고 싶다고 생각 합니다 authorLabelHeight.
Kyle

8

uiview와 레이블 사이의 제한 조건을 IBOutlet으로 연결하고 hidden = YES로 설정하면 우선 순위 멤버를 더 작은 값으로 설정하십시오.


3
NSLayoutConstraint가 설정되면 우선 순위를 조정할 수 없습니다. 우선 순위가 다른 새 구속 조건을 제거하고 읽어야합니다.
Tim

7
이 방법을 사용했습니다. 레이블과 버튼을 사용하는 경우가 있는데 버튼을 숨기고 레이블을 확장해야합니다. 우선 두 가지 제약 조건이 있습니다. 하나는 우선 순위가 751이고 다른 하나는 750입니다. 그런 다음 단추를 숨기면 우선 순위가 바뀌고 레이블 길이가 늘어납니다. 더 높은 우선 순위를 1000으로 설정하려고하면 "설치된 제한 조건에서 우선 순위를 변경하는 것 (또는 그 반대)은 지원되지 않습니다."라는 오류가 발생합니다. 그러지 마라. 그러면 괜찮아 보인다. Xcode 5.1 / viewDidLoad.
John Bushnell

8

내가 한 일은 2 개의 xib를 만드는 것이 었습니다. 하나는 왼쪽보기이고 다른 하나는없는 것입니다. 컨트롤러에 둘 다 등록한 다음 cellForRowAtIndexPath 중에 사용할 것을 결정했습니다.

동일한 UITableViewCell 클래스를 사용합니다. 단점은 xib 사이에 내용이 일부 중복된다는 것입니다. 그러나이 셀은 매우 기본적입니다. 단점은 뷰 제거, 제약 조건 업데이트 등을 수동으로 관리하는 많은 코드가 없다는 것입니다.

일반적으로 이것은 기술적으로 다른 레이아웃이므로 다른 xib를 가져야하므로 더 나은 솔루션 일 것입니다.

[self.table registerNib:[UINib nibWithNibName:@"TrackCell" bundle:nil] forCellReuseIdentifier:@"TrackCell"];
[self.table registerNib:[UINib nibWithNibName:@"TrackCellNoImage" bundle:nil] forCellReuseIdentifier:@"TrackCellNoImage"];

TrackCell *cell = [tableView dequeueReusableCellWithIdentifier:(appDelegate.showImages ? @"TrackCell" : @"TrackCellNoImage") forIndexPath:indexPath];

7

이 경우 Author 레이블의 높이를 적절한 IBOutlet에 매핑합니다.

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

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

cell.authorLabelHeight.constant = 0;

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오


6

두 개의 UIStackView 가로 및 세로를 사용하십시오. 스택의 일부 하위보기가 숨겨지면 다른 스택 하위보기가 이동합니다. 분포-> 두 개의 UILabels가있는 세로 스택에 비례로 채우기를 사용하고 첫 번째 UIView에 너비 및 높이 제한을 설정해야합니다여기에 이미지 설명을 입력하십시오


2

이것을 시도하십시오, 나는 아래 코드를 구현했습니다.

ViewController 에 하나의 View가있어 다른 세 개의보기가 추가되었습니다.보기가 숨겨지면 다른 두보기가 이동합니다. 아래 단계를 따르십시오. ,

1. ViewController.h 파일

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *viewOne;
@property (strong, nonatomic) IBOutlet UIView *viewTwo;
@property (strong, nonatomic) IBOutlet UIView *viewThree;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewOneWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewTwoWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewThreeWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewBottomWidth;
@end

2. ViewController.m

 #import "ViewController.h"
 @interface ViewController ()
{
  CGFloat viewOneWidthConstant;
  CGFloat viewTwoWidthConstant;
  CGFloat viewThreeWidthConstant;
  CGFloat viewBottomWidthConstant;
}
@end

@implementation ViewController
@synthesize viewOne, viewTwo, viewThree;

- (void)viewDidLoad {
  [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a 
  nib.

  /*
   0  0   0
   0  0   1
   0  1   0
   0  1   1
   1  0   0
   1  0   1
   1  1   0
   1  1   1
   */

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:YES];


  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

 //    [viewOne setHidden:YES];
 //    [viewTwo setHidden:YES];
 //    [viewThree setHidden:NO];

//    [viewOne setHidden:YES];
//    [viewTwo setHidden:YES];
//    [viewThree setHidden:YES];

 [self hideShowBottomBar];
  }

- (void)hideShowBottomBar
{
  BOOL isOne = !viewOne.isHidden;
  BOOL isTwo = !viewTwo.isHidden;
  BOOL isThree = !viewThree.isHidden;

  viewOneWidthConstant = _viewOneWidth.constant;
  viewTwoWidthConstant = _viewTwoWidth.constant;
  viewThreeWidthConstant = _viewThreeWidth.constant;
  viewBottomWidthConstant = _viewBottomWidth.constant;

   if (isOne && isTwo && isThree) {
    // 0    0   0
    _viewOneWidth.constant = viewBottomWidthConstant / 3;
    _viewTwoWidth.constant = viewBottomWidthConstant / 3;
    _viewThreeWidth.constant = viewBottomWidthConstant / 3;
    }
    else if (isOne && isTwo && !isThree) {
     // 0    0   1
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = 0;
    }
   else if (isOne && !isTwo && isThree) {
    // 0    1   0
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
    }
    else if (isOne && !isTwo && !isThree) {
    // 0    1   1
    _viewOneWidth.constant = viewBottomWidthConstant;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && isTwo && isThree) {
    // 1    0   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
   }
   else if (!isOne && isTwo && !isThree) {
    // 1    0   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && !isTwo && isThree) {
    // 1    1   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant;
   }
   else if (isOne && isTwo && isThree) {
    // 1    1   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
  }

 - (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
 }
 @end

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

희망이 논리는 어떤 것이 도움이 될 것입니다.


1

내 경우에는 내가의 일정하게 높이 제한 에를 0.0f또한 설정 hidden속성을YES .

뷰 (하위 뷰와 함께)를 다시 표시하려면 반대를 수행했습니다. 높이 상수를 0이 아닌 값으로 설정하고 hidden속성을로 설정 했습니다 NO.


1

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

아래 이미지에서 빨간색보기는 콘텐츠의 실제 컨테이너이며 10pt 후행 공간이 주황색 슈퍼 뷰 (ShowHideView)에 있고 ShowHideView를 IBOutlet에 연결하고 프로그래밍 방식으로 표시 / 숨기기 / 제거하십시오.

  1. 보기가 보이거나 설치 될 때입니다.

보기가 보인다

  1. 뷰가 숨겨 지거나 설치되지 않은 경우입니다.

보기가 숨겨 지거나 제거되었습니다


1

이것은 우선 순위 제약 조건을 사용하는 또 다른 솔루션입니다. 아이디어는 너비를 0으로 설정합니다.

  1. 컨테이너보기 (주황색)를 만들고 너비를 설정하십시오. 여기에 이미지 설명을 입력하십시오

  2. 컨텐츠 뷰 (빨간색)를 만들고 후행 공간 10pt를 슈퍼 뷰 (주황색)로 설정합니다. 후행 공간 제약 조건에 주목하십시오. 우선 순위가 다른 두 개의 후행 제약 조건이 있습니다. 낮음 (= 10) 및 높음 (<= 10). 모호성을 피하기 위해 중요합니다. 여기에 이미지 설명을 입력하십시오

  3. 보기를 숨기려면 주황색보기의 너비를 0으로 설정하십시오. 여기에 이미지 설명을 입력하십시오


0

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];
        }];
    }];

0

이것이 누군가를 돕기 위해 시각적 형식 제약 조건 을 사용하기위한 도우미 클래스를 만들었습니다 . 현재 앱에서 사용하고 있습니다.

자동 레이아웃 도우미

그것은 내 요구에 맞게 조정되었을 수도 있지만, 유용하다고 생각하거나 수정하고 자신의 도우미를 만들고 싶을 수도 있습니다.

위의 답변 , UIScrollView 및이 자습서에 대한답변에 대해 Tim에게 감사해야합니다 .


0

솔루션을 얻기 위해 uiview를 다시 정렬하는 방법은 다음과 같습니다.

  1. 하나의 UIImageView를 끌어다 놓고 왼쪽에 배치하십시오.
  2. 하나의 UIView를 끌어다 놓고 UIImageView의 오른쪽에 배치하십시오.
  3. 해당 UIView 내부에 선행 및 후행 제한 조건이 0 인 두 개의 UILabels를 끌어다 놓습니다.
  4. UIImagView 대신 2 개의 레이블을 포함하는 UIView의 주요 제한 조건을 슈퍼 뷰로 설정하십시오.
  5. UIImageView가 숨겨져 있으면 선행 제약 조건 상수를 10px로 설정하여 슈퍼 뷰하십시오. 그렇지 않으면 선행 제약 조건 상수를 10px + UIImageView.width + 10px로 설정하십시오.

나는 내 자신의 엄지 손가락 규칙을 만들었습니다. 구속 조건이 영향을받을 수있는 uiview를 숨기거나 표시해야 할 때마다 영향을받는 / 종속 서브 뷰를 uiview 내부에 추가하고 선행 / 후행 / 상단 / 하단 제약 조건을 프로그래밍 방식으로 업데이트하십시오.


0

이것은 오래된 질문이지만 여전히 도움이되기를 바랍니다. Android에서 제공되는이 플랫폼에는 편리한 방법이 있습니다.isVisible 에서는 뷰에서 숨길 수 이 있지만 자동 레이아웃이 뷰를 그릴 때 프레임을 고려하지 않아도됩니다.

확장 및 "확장"uiview를 사용하면 ios에서 비슷한 기능을 수행 할 수 있습니다 (이미 UIKit에없는 이유는 확실하지 않음).

    func isVisible(_ isVisible: Bool) {
        self.isHidden = !isVisible
        self.translatesAutoresizingMaskIntoConstraints = isVisible
        if isVisible { //if visible we remove the hight constraint 
            if let constraint = (self.constraints.filter{$0.firstAttribute == .height}.first){
                self.removeConstraint(constraint)
            }
        } else { //if not visible we add a constraint to force the view to have a hight set to 0
            let height = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal , toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 0)
            self.addConstraint(height)
        }
        self.layoutIfNeeded()
    }

0

올바른 방법은 isActive = false로 제약 조건을 비활성화하는 것입니다. 그러나 구속 조건을 비활성화하면 구속 조건이 제거 및 해제되므로 강력한 콘센트가 있어야합니다.


0

가장 쉬운 해결책은 UIStackView (가로)를 사용하는 것입니다. 스택보기에 추가 : 레이블이있는 첫 번째보기 및 두 번째보기. 그런 다음 첫 번째보기의 isHidden 속성을 false로 설정하십시오. 모든 구속 조건이 계산되고 자동으로 업데이트됩니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.