[ios] FlowLayout으로 UICollectionView의 높이를 결정하는 방법

나는있어 UICollectionView과를 UICollectionViewFlowLayout, 그리고 난 (에 반환 컨텐츠 크기를 계산하려면 intrinsicContentSize자동 레이아웃을 통해 높이를 조정 필요).

문제는 다음과 같습니다. 모든 셀에 대해 높이가 고정되어 있어도 .NET 파일에 “행”/ 줄이 몇 개 있는지 알 수 없습니다 UICollectionView. 또한 데이터 항목을 나타내는 셀의 너비가 다르기 때문에 데이터 소스의 항목 수로 개수를 결정할 수 없으며 결과적으로 UICollectionView.

공식 문서에서이 주제에 대한 힌트를 찾을 수없고 인터넷 검색이 더 이상 나에게 가져 오지 않았기 때문에 어떤 도움과 아이디어라도 대단히 감사하겠습니다.



답변

우와! 어떤 이유에서인지 몇 시간 동안 조사한 끝에 내 질문에 대한 매우 쉬운 대답을 찾았습니다. 잘못된 곳에서 완전히 검색하고 찾을 수있는 모든 문서를 파헤 치고있었습니다 UICollectionView.

간단하고 쉬운 해결책은 기본 레이아웃 collectionViewContentSize에 있습니다. myCollectionView.collectionViewLayout속성을 호출 하기 만하면 콘텐츠의 높이와 너비를 CGSize. 그것만큼 쉽습니다.


답변

자동 레이아웃을 사용하는 경우 다음 하위 클래스를 만들 수 있습니다.UICollectionView

아래 코드를 사용하면 컬렉션 뷰의 내용에 따라 달라 지므로 컬렉션 뷰에 대한 높이 제약 조건을 지정할 필요가 없습니다.

다음은 구현입니다.

@interface DynamicCollectionView : UICollectionView

@end

@implementation DynamicCollectionView

- (void) layoutSubviews
{
    [super layoutSubviews];

    if (!CGSizeEqualToSize(self.bounds.size, [self intrinsicContentSize]))
    {
        [self invalidateIntrinsicContentSize];
    }
}

- (CGSize)intrinsicContentSize
{
    CGSize intrinsicContentSize = self.contentSize;

    return intrinsicContentSize;
}

@end


답변

에서 viewDidAppear당신은 그것을으로 얻을 수 있습니다 :

float height = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;

데이터를 다시로드 한 다음 새 데이터로 새 높이를 계산해야 할 때 다음 방법으로 가져올 수 있습니다. 다음 위치 CollectionView에서 데이터를 다시로드 할 때 수신 할 관찰자를 추가합니다 viewdidload.

[self.myCollectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL];

그런 다음 벨로우즈 기능을 추가하여 새로운 높이를 얻거나 collectionview가 다시로드 된 후 무엇이든 수행하십시오.

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary  *)change context:(void *)context
{
    //Whatever you do here when the reloadData finished
    float newHeight = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;
}

관찰자를 제거하는 것을 잊지 마십시오.

[self.myCollectionView removeObserver:self forKeyPath:@"contentSize" context:NULL];


답변

스위프트의 user1046037 답변 …

class DynamicCollectionView: UICollectionView {
    override func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize() {
            invalidateIntrinsicContentSize()
        }
    }

    override func intrinsicContentSize() -> CGSize {
        return self.contentSize
    }
}


답변

user1046037 답변에 대한 Swift 3 코드

import UIKit

class DynamicCollectionView: UICollectionView {

    override func layoutSubviews() {
        super.layoutSubviews()
        if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
            self.invalidateIntrinsicContentSize()
        }

    }

    override var intrinsicContentSize: CGSize {
        return contentSize
    }

}


답변

스위프트 4

class DynamicCollectionView: UICollectionView {
  override func layoutSubviews() {
    super.layoutSubviews()
    if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
      self.invalidateIntrinsicContentSize()
    }
  }

  override var intrinsicContentSize: CGSize {
    return collectionViewLayout.collectionViewContentSize
  }
}


답변

스위프트 4.2

class DynamicCollectionView: UICollectionView {
    override func layoutSubviews() {
        super.layoutSubviews()
        if bounds.size != intrinsicContentSize {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        return self.contentSize
    }
}