programing

레이블 너비에 따른 UICollectionView의 동적 셀 너비

telebox 2023. 9. 4. 19:44
반응형

레이블 너비에 따른 UICollectionView의 동적 셀 너비

UICollectionView는 라벨이 포함된 재사용 가능한 셀에서 셀을 로드합니다.배열은 해당 레이블의 내용을 제공합니다.sizeToFit으로 내용 너비에 따라 레이블 너비를 쉽게 조정할 수 있습니다.하지만 나는 라벨에 맞는 셀을 만들 수 없습니다.

여기 코드가 있습니다.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    arrayOfStats =  @[@"time:",@"2",@"items:",@"10",@"difficulty:",@"hard",@"category:",@"main"];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:     (NSInteger)section{
    return [arrayOfStats count];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    return CGSizeMake(??????????);
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    return 1;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    Cell *cell = (Cell *) [collectionView dequeueReusableCellWithReuseIdentifier:@"qw" forIndexPath:indexPath];
    cell.myLabel.text = [NSString stringWithFormat:@"%@",[arrayOfStats objectAtIndex:indexPath.item]];
    // make label width depend on text width
    [cell.myLabel sizeToFit];

    //get the width and height of the label (CGSize contains two parameters: width and height)
    CGSize labelSize = cell.myLbale.frame.size;

    NSLog(@"\n width  = %f height = %f", labelSize.width,labelSize.height);

    return cell;
}

sizeForItemAtIndexPath텍스트 크기를 반환합니다.

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    return [(NSString*)[arrayOfStats objectAtIndex:indexPath.row] sizeWithAttributes:NULL];
}

Swift 4.2+

원칙은 다음과 같습니다.

  1. 위임이 설정되었는지 확인합니다(예:collectionView.delegate = self)

  2. 시행하다UICollectionViewDelegateFlowLayout(필요한 메서드 서명이 포함되어 있습니다.)

  3. 불러collectionView...sizeForItemAt방법.

  4. 브리지 캐스트 필요 없음String로.NSString부르는 것size(withAttributes:방법.스위프트String상자에서 꺼낸 것입니다.

  5. 속성은 사용자가 설정한 것과 동일합니다.(NS)AttributedString예: 글꼴 패밀리, 크기, 무게 등선택적 매개 변수.


샘플 솔루션:

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return "String".size(withAttributes: nil)
    }
}

그러나 셀에 대한 구체적인 문자열 속성을 지정할 가능성이 높기 때문에 최종 반환은 다음과 같습니다.

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        // dataArary is the managing array for your UICollectionView.
        let item = dataArray[indexPath.row]
        let itemSize = item.size(withAttributes: [
            NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 14)
        ])
        return itemSize
    }
}

크기를 계산할 때 UI 레이블을 사용하면 안 되는 이유는 무엇입니까?제안된 솔루션은 다음과 같습니다.

let label = UILabel(frame: CGRect.zero)
label.text = textArray[indexPath.item]
label.sizeToFit()

예, 같은 결과를 얻을 수 있습니다.단순해 보이고 실행 가능한 솔루션처럼 보일 수 있습니다.하지만 1) 비싸고, 2) 간접비이고, 3) 더럽기 때문에 부적절합니다.

UILabel은 복잡한 UI 개체이기 때문에 비용이 많이 듭니다. 이 개체는 셀이 여기에 필요하지 않더라도 셀이 표시될 때마다 반복적으로 생성됩니다.텍스트 크기만 알면 되지만 전체 UI 개체를 만들기까지 하기 때문에 오버헤드 솔루션입니다.그리고 그 이유로 더럽습니다.

swift 4.2를 위한 작은 트릭을 찾았습니다.

동적 너비 및 고정 높이:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let label = UILabel(frame: CGRect.zero)
        label.text = textArray[indexPath.item]
        label.sizeToFit()
        return CGSize(width: label.frame.width, height: 32)
    }

동적 높이 및 고정 너비의 경우:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            let label = UILabel(frame: CGRect.zero)
            label.text = textArray[indexPath.item]
            label.sizeToFit()
            return CGSize(width: 120, height: label.frame.height)
        }

아래 코드를 확인해 보십시오. CG 사이즈가 매우 짧을 수 있습니다.

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{

    NSString *testString = @"SOME TEXT";
    return [testString sizeWithAttributes:NULL];
}

Swift 5.X에서는 코드 한 줄로 충분합니다.

아래 답변에 동적 너비와 정적 높이를 추가했습니다.요구 사항에 따라 높이 값을 변경합니다.

//MARK: - UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: itemsArray[indexPath.item].size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 17)]).width + 25, height: 30)
}

UICollectionViewDelegateFlowLayout을 대리자에 추가합니다.

텍스트 길이에 기반한 동적 크기와 동일한 셀 공간으로 완벽하게 작동합니다.

아래 PFA 이미지...

enter image description here

내용을 기준으로 집합 뷰(셀이 아님)의 높이를 고정합니다(집합 뷰의 동적 높이).

UICollectionView의 높이를 UICollectionView의 콘텐츠 크기 높이로 조정하는 방법은 무엇입니까?

인 스위프트 3

let size = (arrayOfStats[indexPath.row] as NSString).size(attributes: nil)

스위프트 4

let size = (arrayOfStats[indexPath.row] as NSString).size(withAttributes: nil)

//뷰에 추가 didload

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    [layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    layout.estimatedItemSize = CGSizeMake(self.breadScrumbCollectionView.frame.size.width, 30); 
self.breadScrumbCollectionView.collectionViewLayout = layout;

//UICollection 뷰 작성

lazy var collectionView: UICollectionView = {
    
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    collectionView.translatesAutoresizingMaskIntoConstraints = false
    
    
    //CollectionCellView width autoSize
    layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
    
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
   
    collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: cellId)
   [enter image description here][1]
    return collectionView
}()

나를 위한 이 한 줄.UICollectionViewFlowLayout()나를 위해 속임수를 썼습니다.

collectionViewLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize

언급URL : https://stackoverflow.com/questions/23134986/dynamic-cell-width-of-uicollectionview-depending-on-label-width

반응형