2014-12-28 2 views
1

나는 하루 종일 검색했지만 작동하지 못했습니다.가변 높이 및 레이아웃이있는 UILabel을 프로그래밍 방식으로 추가하는 방법

나는 왼쪽에 두 개의 레이블이 있고 오른쪽에 하나의 버튼이있는 UIView입니다. autolayout에 따라보기의 크기를 조정할 수 있도록 제약 조건을 추가했습니다. UIView (두 개의 높이에 대한 제약 조건이 하나도 없음)의 높이에 대해 하나의 제약 조건을 설정했지만 모두 UILabel의 내용이 다를 수 있기 때문에 모든 것이 완벽하게 작동했습니다.이 제약 조건을 제거하고 다음과 같은 두 가지 제약 조건을 설정했습니다. UILabel (위쪽은 UILabel, 나머지는 더 크다)은 UILabel이고, 다른 하나는 아래쪽의 값인 UILabelUIView 사이의 값을 고정합니다. 그것은 자동 레이아웃과 같은

은 10px 위의 높이를 증가하지 않기 때문에 UILabel 아래의 내용에도 불구하고, UILabel 아래의 intrinsicContentSize을 계산 할 수 없습니다.

UIView *miView = [[UIView alloc] init]; 
UILabel *miLabel = [[UILabel alloc] init]; 
[miLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[miDetailsLabel setNumberOfLines:1]; 
[miDetailsLabel setText:@"Just one line."]; 
[miView addSubview:miLabel]; 
UILabel *miDetailsLabel = [[UILabel alloc] init]; 
[miDetailsLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[miDetailsLabel setNumberOfLines:0]; 
[miDetailsLabel setText:@"Enough text to show 3 lines on an IP4, except first of three UILabels on my test code, with no content"]; 
[miView addSubview:miDetailsLabel]; 
UIButton *miButton = [[UIButton alloc] init]; 
[miButton setTranslatesAutoresizingMaskIntoConstraints:NO]; 
[miView addSubview:miButton]; 

NSArray *constraint_inner_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[label]-(10)-[button(52)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"button":miButton}]; 
NSArray *constraint_inner2_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[details]-(10)-[button]-(0)-|" options:0 metrics:nil views:@{@"details":miDetailsLabel, @"button":miButton}]; 
NSArray *constraint_label_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[label(18)]-(2)-[details(>=10)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"details":miDetailsLabel}]; 
NSArray *constraint_button_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button(22)]" options:0 metrics:nil views:@{@"button":miButton}]; 
[miView addConstraint:[NSLayoutConstraint constraintWithItem:miButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:miView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]]; 
[miView addConstraints:constraint_inner_h]; 
[miView addConstraints:constraint_inner2_h]; 
[miView addConstraints:constraint_label_v]; 
[miView addConstraints:constraint_button_v]; 

코드의 축소 버전을 넣었습니다.

내가 누락 된 아이디어가 있습니까?

감사

업데이트 : 내가 말했듯이 매트 조언 덕분에, 나는 코드를 설명하기 위해 preferredMawLayoutWidth:

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 

    NSArray *allKeys = [dictOpcionesTickets allKeys]; 
    for (NSString *key in allKeys) { 
     NSArray *tmpArray = [dictOpcionesTickets objectForKey:key]; 
     if (![[tmpArray objectAtIndex:0] isEqual:@""]) { 
      UILabel *tmpLabel = [tmpArray objectAtIndex:3]; 
      tmpLabel.preferredMaxLayoutWidth = tmpLabel.frame.size.width; 
      NSLog(@"width: %f",tmpLabel.frame.size.width); 
     } 
    } 
    [self.view layoutIfNeeded]; 
} 

에 적절한 값을 설정하기 위해이 솔루션을 시도했습니다, 나는 그것을하고 있어요 동적으로, UILabel (다른 흥미로운 정보 중에서)에 대한 참조가있는 배열로 사전을 만들었습니다. 나는이 코드를 실행하면, 나는 (내용이없는로 3 UILabel, 첫 번째 레이블을 구문 분석 코드) 다음 로그를 얻을 :

2014-12-28 20:40:42.898 myapp[5419:60b] width: 0.000000 
2014-12-28 20:40:42.912 myapp[5419:60b] width: 0.000000 
2014-12-28 20:40:43.078 myapp[5419:60b] width: 229.000000 
2014-12-28 20:40:43.080 myapp[5419:60b] width: 229.000000 
2014-12-28 20:40:43.326 myapp[5419:60b] width: 229.000000 
2014-12-28 20:40:43.327 myapp[5419:60b] width: 229.000000 

하지만 여전히 같은 결과를 받고 있어요 ...의 UIView는 여전히 게재되고 높이는 제약 조건에 의해 설정된 최소 높이와 같으며 UILabel의 내용을 표시하지 않습니다.

업데이트 2 여전히 바보짓을하고 있습니다.

나는 나의 초기 코드를 테스트하지만, iOS7에와 실제 아이폰 4에서 실행, 엑스 코드 (6)에서 새로운 프로젝트를 단순화, 그리고 UILabel, 심지어는 부모 뷰에 layoutIfNeeded를 호출하지 않고 preferredMaxLayoutWidth 또는 서브 클래스를 설정하지 않고 완벽하게 일했습니다.

- (void)addLabelsDinamically { 
    self.labelFixed.text = @"Below this IB label goes others added dinamically..."; 

    UIButton *miBoton = [[UIButton alloc] init]; 
    miBoton.translatesAutoresizingMaskIntoConstraints = NO; 
    [miBoton setTitle:@"Hola" forState:UIControlStateNormal]; 
    [self.viewLabels addSubview:miBoton]; 
    [self.viewLabels addConstraint:[NSLayoutConstraint constraintWithItem:miBoton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.viewLabels attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[boton(22)]" options:0 metrics:nil views:@{@"boton":miBoton}]]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[boton(40)]" options:0 metrics:nil views:@{@"boton":miBoton}]]; 

    UILabel *miLabel = [[UILabel alloc] init]; 
    miLabel.translatesAutoresizingMaskIntoConstraints = NO; 
    miLabel.backgroundColor = [UIColor redColor]; 
    miLabel.numberOfLines = 0; 
    miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn"; 
    [self.viewLabels addSubview:miLabel]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":self.labelFixed}]]; 
    UIView *pre = miLabel; 

    miLabel = [[UILabel alloc] init]; 
    miLabel.translatesAutoresizingMaskIntoConstraints = NO; 
    miLabel.backgroundColor = [UIColor greenColor]; 
    miLabel.numberOfLines = 0; 
    miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn"; 
    [self.viewLabels addSubview:miLabel]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]]; 
} 

아 하나 UILabelnumberOfLines 세트, IB에 추가, 같은 화면에 내가있다 : 그것은 실제 프로젝트에 관해서 그러나이 작동하지 않습니다 (나는 원래 엑스 코드 4에서 사례 한 5 생각) '0', 수직 구속 조건 '보다 크거나 같음'및 수평 구속 조건을 비슷한 방식으로 설정합니다 (그러나 IB에 설정된 두 구속 조건 모두 ...). 그러면 완벽하게 작동합니다. 어떤 도움 ???

+0

코드를 사용해 본적이 없지만 두 가지 라벨의'preferredMaxLayoutWidth'를 실제 폭으로 설정하여 도움이되는지 확인해보십시오. 그것이 세로로 커지는 방법을 레이블에 알려주는 설정입니다. – matt

+0

그래, 내 연구에서 그 자산을 보았지만 내 레이블 너비 또한 superview의 너비에 달려 있기 때문에 그것을 사용하지 않았다. "preferredMaxLayoutWidth"에 무엇을 넣어야합니까? – raululm

+0

글쎄, 우리가 들어가기 전에 실제로 작동하는 코드부터 시작해 보도록하겠습니다. 라벨에'numberOfLines' 값을 할당하지 않았기 때문에 여러분이 제공 한 코드는 완전히 무의미합니다. 그것 없이는 어떤 경우에도 포장하지 않을 것입니다. 따라서 실제로 랩/성장할 항목이있을 때까지 코드 코드를 수정 한 다음 더 많이 이야기 할 수있는 기회를 제공하겠습니다. 또한 레이블이 어떤 텍스트인지 알려 주어 실제로 일어나는 것이 있는지 확인할 수 있도록하십시오. – matt

답변

3

글쎄, 마침내 내가 "업데이트 2"에서 말했듯이 오류를 발견했습니다. 매우 이상한 일이었습니다. UILabel이 IB를 통해 추가되었지만 동적으로 추가 된 것은 아닙니다.

그래서, 난 IB 내 화면으로 다시보고, 나는 "동일한"관계를 가진 높이 제약 조건이 발견, 내가 그것을 변경하는 경우에 모든 작업 시작 "보다 크거나 같은"!!!! 왜 제가 제약 조건이 "보다 크거나 같지 않다"는 것을 눈치 채지 못했습니까? 레이블이있는 뷰를 추가 할 때 제약 조건이있는 뷰가 점점 더 커지기 때문입니다. 그게 버그 야? 다른 사람이 유용하게 찾을 경우

음, 요약합니다. "어떻게 그 내용에 적응 UILabel의 멀티 라인을 추가?"

아이폰 OS 6 버전 그것은 "preferredMaxLayoutWidth"가 "layouted", 프로그래머가 코드를 통해 설정해야한다는의 결과로 일단 폭을받지 (가장 좋은 방법은 그것을하고있다 버그이었다 동적으로, 내가 위의 질문에 넣었다는 예입니다).

덕분에 iOS7 이상에이 문제가 해결되어 제약 조건에만 의존 할 수 있습니다. UILabel을 추가하고 '0'에 "라인의 수"로 설정

  • IB

    를 통해 추가

    1. (이것은 필요로 이것은 UILabel 사용에게 많은 라인을 만들 것입니다).

    2. 이 경우, 네 번째는 "크거나 같"관계와 높이가 될 것이다 (위 또는 아래로 핀, 양측)에 3 개 이상의 제약이 필요 제약 조건을 추가한다. 뷰 컨테이너가 충분한 공간을 가지고, 나 또한 관계 "크거나 같"을 높이 제약 조건이보다
    3. 은해야합니다.
  • 코드를 통해 추가 (바로 위의 코드 게시 붙여 넣기) : 날 수 있도록 노력하고 있습니다 사람들에게

    UILabel *miLabel = [[UILabel alloc] init]; // Initialitze the UILabel 
    miLabel.translatesAutoresizingMaskIntoConstraints = NO; // Mandatory to disable old way of positioning 
    miLabel.backgroundColor = [UIColor redColor]; 
    miLabel.numberOfLines = 0; // Mandatory to allow multiline behaviour 
    miLabel.text = @"ñkhnaergñsdbmnñgwn"; // big test to test 
    [self.viewLabels addSubview:miLabel]; // Add subview to the parent view 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[label]-(10)-|" options:0 metrics:nil views:@{@"label":miLabel}]]; // horizontal constraint 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(10)-[label]" options:0 metrics:nil views:@{@"label":miLabel}]]; 
    UIView *pre = miLabel; 
    
    // Adding a second label to test the separation 
    miLabel = [[UILabel alloc] init]; 
    miLabel.translatesAutoresizingMaskIntoConstraints = NO; 
    miLabel.backgroundColor = [UIColor greenColor]; 
    miLabel.numberOfLines = 0; 
    miLabel.text = @"ñkhnaermgñlkafmbnoetñnngñsdbmnñgwn"; 
    [self.viewLabels addSubview:miLabel]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[label]-(10)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]]; 
    [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(10)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]]; 
    
  • 감사합니다! 이 사이트는 동적으로 텍스트 정보를 추가 할 때

    +0

    miLabel.translatesAutoresizingMaskIntoConstraints = NO;'나를 구 했어요. 이것이 설정되지 않으면 내 제약 조건이 작동하지 않습니다. – user1282637

    +0

    물론 이것은 제약 조건을 추가하기 전에 텍스트 정보를 제공함에 따라 작동합니다. 그러나 그 후에 텍스트를 추가한다면 다른 방법이 필요합니다. – elliotrock

    0

    이 답변이 프로그래밍 상황에서 작동합니다 :) 놀라운이며,이 위 UICollectionViewCell 또는 UITableViewCell A의 경우. 당신이 contentView에 레이아웃과 제약을 업데이트해야합니다 이러한 상황에서

    는 다음 preferedWidth을 설정

    -(void) layoutSubviews 
    { 
    
    [super layoutSubviews]; 
    
    [self.contentView setNeedsLayout]; 
    [self.contentView layoutIfNeeded]; 
    
    //locationName.preferredMaxLayoutWidth = locationName.frame.size.width; 
    //locationDetails.preferredMaxLayoutWidth = locationDetails.frame.size.width; 
    
    [super layoutSubviews]; 
    } 
    

    이 유가 그 새로운 프레임 정보를 얻고 사용하는 다른 답변과 유사 preferredMaxLayoutWidth는 뷰를 갱신합니다. 경우

    당신은 layoutSubViews에서 그에게 preferredMaxLayoutWidth 설정 다른 생각에 자신의 numberOfLines = 0

    필요 시작점과 수직에 대한 그 전망과 UILabel에 추가 제약 조건이 필요합니다 가난한 솔루션입니다 귀하의 폭의 변화뿐만 아니라, 같은 신장. 그 셀에 대한 init과 같은 부분을 설정하는 것이 가장 좋습니다. 너비를 제한하는 경우 어떤면에서는 필요하지 않을 수도 있습니다. 나의 상황에서 이것은 세포가 설정 될 때마다 변경 preferredMaxLayoutWidth로 이어집니다.

    관련 문제