2014-11-25 2 views
3

iOS 7 및 8에서 동적으로 크기가 조정 된 셀을 사용하여 테이블 뷰를 작성하는 데 어려움을 겪고 있습니다. 다른 "조정", "해결 방법"을 사용하여 제작할 수있는 iOS 7과 8 사이에서 ("깨진 레이아웃 방법"으로) 여기에서 찾을 수 있습니다. 그러나 결국 레이아웃 시스템이 사용자 지정 제약 조건 중 하나를 "복구"하기 때문에 iOS 7 또는 iOS 8 (둘 다 아닌 경우)에서 일부 또는 모든 셀의 내용이 잘못 정렬됩니다.iOS 7 및 iOS 8의 동적 UITableViewCell 높이

기본적으로 세 가지 유형의 콘텐츠가 있습니다. 그리고 위의 테이블보기뿐만 아니라이 내용을 UIView의 세 하위 클래스로 래핑했습니다. SummaryView s 테이블 뷰의 경우 UITableViewCell의 세 하위 클래스를 만들고 각각이 SummaryViewcontentView에 따라 추가하고 self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight을 설정합니다. updateViewConstraints에 나는 일반적으로 tableView:estimatedHeightForRowAtIndexPath:에서

- (void)updateConstraints 
{ 
    // ...removed custom constraints before 
    NSDictionary *views = NSDictionaryOfVariableBindings(_summaryView); 

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_summaryView]-|" 
                     options:0 
                     metrics:nil 
                     views:views] 
         toView:self.contentView]; 

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_summaryView]-|" 
                     options:0 
                     metrics:nil 
                     views:views] 
         toView:self.contentView]; 
    [super updateConstraints]; 
} 

내가 내용의 유형에 따라 정적 추정치를 반환 ... 이전에 추가되었을 수있는 모든 "내"제약 조건을 제거 할. 내가의 방식으로 "프로토 타입"세포를 사용 tableView:heightForRowAtIndexPath:에서 ... 여기 보통 디버거 나누기 UIViewAlertForUnsatisfiableConstraints에 ([prototypeCell layoutIfNeeded]에) <NSLayoutConstraint:0x17409f180 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x17019f070(44)]>이 제약의 나머지 부분과 충돌로

// ..set content on prototype cell before 
[prototypeCell setNeedsUpdateConstraints]; 
[prototypeCell layoutIfNeeded]; 
CGSize size = [prototypeCell systemLayoutSizeFittingSize:UILayoutFittingExpandedSize]; 
return size.height; 

.

그래서 나는 셀의 내용을 적용하기 전에 ...

  • 테이블 뷰의 사용 tableView:estimatedHeightForRowAtIndexPath:
  • 을 구현하지 viewDidLoad

  • ...

    if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) { 
        cell.contentView.frame = cell.bounds; 
        cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; 
    } 
    

    에서 tableView.rowHeight = UITableViewAutomaticDimension 설정 ... 시도 레이아웃 계산하기

  • 세포 초기화시 self.contentView.bounds = CGRectMake(0.0, 0.0, 1000, 1000);을 수행 중
  • 아마도 지금 당장 이틀 동안은 기억할 수없는 다른 것들이있을 것입니다.

불만족스러운 제약 조건에 대해 불평하지 않는 변형을 구현하면 항상 레이아웃이 엉망입니다. 그리고 비록 "default"<NSLayoutConstraint:0x17409f180 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x17019f070(44)]> 제약 조건을 설정하지 않는 테이블 뷰를 얻었지만 제약 조건 세트는 (tableView:heightForRowAtIndexPath:에 의해 반환 된 높이를 기준으로) 레이아웃 시스템에 적합하지 않습니다.

이 게시물은 최후의 수단입니다. 구체적인 클래스의 제약이 없다면 다시 확인할 수 없다는 것을 알고 있습니다. 그러나 이러한 뷰를 문제없이 테이블 뷰 외부에서 사용할 수 있으므로 하위 뷰의 제약 조건의 문제가되어서는 안됩니다.

모든 뷰 요소의 크기를 수동으로 ([UIScreen mainScreen].bounds 기준) 계산하고 모든 서브 뷰에 직접 (너비와 높이로) 설정해야 할 것 같습니다. 그래서 저는 셀의 구체적인 높이를 얻을 수 있고 contentView의 프레임을 수동으로 설정할 수 있습니다. 그것은 레이아웃 코드를 현저하게 엉망으로 만든다.

감사합니다, 결국 가브리엘

+1

잘못된 경로에있는 셀의 높이는'-tableView : heightForRowAtIndexPath :'메서드를 통해 반환하는 값을 기반으로합니다. 화면의 실제 높이를 정의합니다. 자동 레이아웃이나 auto-resizemask로 놀아도 도움이되지 않습니다. – holex

+2

@ 홀렉스 사냥 명성 이요? ** A ** : _correct_ 경로가 무엇인지에 대해 나에게 (그리고 다른 사람들에게) 가르쳐 주시기 바랍니다. ** B ** :'tableView : heightForRowAtIndexPath'가 무엇인지 의심의 여지가 없다고 생각합니다. ** C ** : 자동 레이아웃으로 _ 주위를 둘러보고 있지 않습니다. 실제로 사용하고 있습니다. ** D ** :'autoresizingMask'로 _playing_하면 다른 사람들을 도왔습니다. http://stackoverflow.com/a/19154287/981728. – dergab

답변

2

나는 많이하지 엉망 레이아웃 코드를 수행 허용 솔루션을 발견했다. 짧게 :

테이블보기 셀의 updateConstraints에서 제한 조건을 _summaryView -bottom에서 superview-bottom으로 제거했습니다. 따라서 콘텐츠보기의 높이 제한은 요약보기의 높이 제한을 방해하지 않습니다. tableView:heightForRowAtIndexPath:에서

- (void)updateConstraints 
{ 
    NSDictionary *views = NSDictionaryOfVariableBindings(_summaryView); 

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_summaryView]-|" 
                     options:0 
                     metrics:nil 
                     views:views] 
         toView:self.contentView]; 

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_summaryView]" 
                     options:0 
                     metrics:nil 
                     views:views] 
         toView:self.contentView]; 
    [super updateConstraints]; 
} 

난 그냥 높이를 얻기 위해 해당 셀의 intrinsicContentSize를 사용

 [prototypeCell.summaryView applyStuff]; 
     [prototypeCell layoutIfNeeded]; 
     height = [prototypeCell intrinsicContentSize].height; 

다음과 같이 말했다 테이블 뷰 셀의 intrinsicContentSize의 구현은 같습니다

- (CGSize)intrinsicContentSize 
{ 
    // Calculate the available content width if not done yet 
    static CGFloat availableWidth = 0.0; 
    if (availableWidth == 0.0) { 
     availableWidth = CGRectGetWidth([UIScreen mainScreen].bounds); 
    } 

    // Check if the contentView's frame needs an update 
    if (CGRectGetWidth(self.contentView.frame) != availableWidth) { 
     CGRect frame = CGRectMake(0.0, 0.0, availableWidth, 100.0); 
     self.contentView.frame = frame; 
    } 

    [_summaryView layoutIfNeeded]; 
    CGSize size = _summaryView.frame.size; 
    size.height += 2.0 * V_PADDING; 
    size.width += 2.0 * H_PADDING; 
    return size; 
} 

가로 및 세로 모드를 지원하는 앱의 경우 availableWidth은 방향 변경시 재설정해야하거나 아니요 static이 아닙니다. * _PADDING_summaryView의 모든면에 필요한 공간입니다.

또한 셀의 초기화 코드에서 self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth을 제거했습니다. 눈에 띄는 효과가없는 것 같습니다.

+0

필자는 좌절감을 설정하지 않고 selfview.frame.width (tableViewCell은 항상'UIView-Encapsulated-Layout-Width'로 인해 ZER0 임)를 적용하여 비슷한 접근 방식을 사용하고 있습니다. 그것의 높이를 계산하는 프레임 ... 누구든지 contentView 프레임이 intrinsicContentSize에 의해 순전히 계산되도록하는 접근법을 생각해 내기를 원한다면 여전히 가능한 해결책이없는 것처럼 보입니다. –

+0

내 tableView 셀은'tableView : heightForRowAtIndexPath :'에 큰 UILabel을 가지고 있는데,'contentLabelHeight = contentLabel.font.sizeOfString (contentLabel.text !, constrainedToWidth : Double (self.view.frame.width - 44))를 사용하고 있습니다. .height' 먼저 높이를 계산하고 (ps 44는'2.0 * H_PADDING') contentLabelHeight + contentLabel.frame.origin.y + 20 (ps 20은 당신의'2.0 * V_PADDING')을 반환합니다. –

+0

네, 거기에있는 것 같습니다. iOS 7에서 "동적 행 높이"를 처리하는 _nice_ 방법이 없습니다. – dergab

0

토론에서 약간 늦어 질지 모르지만 비슷한 문제가있어서 해결책을 찾았습니다.

제약 조건을 추가 할 때 제약 조건을 셀이 아닌 contentView에 추가하십시오. 그렇지 않으면 "| -"및 "- |" 시각적 언어 형식으로 표현하면 셀 자체와 관련된 제약 조건이 만들어지며 열악한 contentView에는 제약 조건이 전혀 없습니다.

[self addConstraints: ...]; 대신 [self.contentView addConstraints: ...];을 사용하십시오.

+0

'_summaryView'는 셀의 'contentView'에 대한 하위 뷰입니다. 제약 조건을 뷰에 추가 할 때 제약 조건이이 바로 뷰 또는 하위 뷰를 참조하는지는 중요하지 않습니다. – dergab

+0

필자는 현재 프로젝트에서 차이점이 있는지 확인하기 위해 두 번 확인했습니다. "| -"또는 "- |"가있는 시각적 언어 제약 조건 addConstraint 메소드를받는 컨테이너를 참조합니다. 또한 "addConstraint"를 셀 대신 contentView로 보내면 얻을 수없는 "tableview 셀의 내용보기에 대해 제약 조건이 애매하게 높이를 제안하는 경우를 감지했습니다."라는 메시지가 나타납니다. iOS8.3 이하. –

+0

글쎄, 이것은 설명이 될 것입니다. 슬프게도 저는 현재 프로젝트를 통해 테스트 할 시간이 없습니다. 그러나 나는 그것을 염두에두고 조만간 그것을 점검 할 것이다 ... – dergab