[ios] 내용에 맞게 UITableView 크기 조정

에 질문이 UILabel있고에 객관식 답변이 표시 되는 앱을 만들고 있습니다. UITableView각 행 에는 객관식 선택이 표시됩니다 . 질문과 답변은 다양하므로 UITableView동적으로 높이 가 필요합니다 .

sizeToFit테이블에 대한 해결 방법 을 찾고 싶습니다 . 표의 프레임이 모든 내용의 높이로 설정되는 경우.

아무도 내가 이것을 달성 할 수있는 방법에 대해 조언 할 수 있습니까?



답변

실제로 나는 스스로 답을 찾았습니다.

난 그냥 새를 만들 CGRect에 대한 tableView.frameheighttable.contentSize.height

즉,의 높이를 설정 UITableView받는 height내용의. 코드가 UI를 수정하므로 기본 스레드에서 UI를 실행하는 것을 잊지 마십시오.

dispatch_async(dispatch_get_main_queue(), ^{
        //This code will run in the main thread:
        CGRect frame = self.tableView.frame;
        frame.size.height = self.tableView.contentSize.height;
        self.tableView.frame = frame;
    });


답변

KVO, DispatchQueue 또는 제약 조건 설정이없는 Swift 5 및 4.2 솔루션.

이 솔루션은 Gulz의 답변을 기반으로합니다. 합니다.

1)의 서브 클래스를 생성합니다 UITableView:

import UIKit

final class ContentSizedTableView: UITableView {
    override var contentSize:CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }
}

2) UITableView레이아웃에 a 를 추가하고 모든면에 제약 조건을 설정하십시오. 그것의 클래스를 설정ContentSizedTableView .

3) 스토리 보드는 하위 클래스 intrinsicContentSize를 고려 하지 않기 때문에 약간의 오류가 표시 됩니다. 크기 관리자를 열고 intrinsicContentSize를 자리 표시 자 값으로 재정 의하여이 문제를 해결하십시오. 이것은 디자인 타임에 대한 재정의입니다. 런타임에 ContentSizedTableView클래스 에서 재정의를 사용합니다.


업데이트 : Swift 4.2 코드가 변경되었습니다. 이전 버전을 사용 UIViewNoIntrinsicMetric하는 경우 대신UIView.noIntrinsicMetric


답변

스위프트 솔루션

다음과 같이하세요:

1- 스토리 보드에서 테이블의 높이 제한을 설정하십시오.

2- 스토리 보드에서 높이 구속 조건을 끌어 뷰 컨트롤러 파일에서 @IBOutlet을 만듭니다.

    @IBOutlet weak var tableHeight: NSLayoutConstraint!

3- 그런 다음이 코드를 사용하여 테이블 동적 분석의 높이를 변경할 수 있습니다.

override func viewWillLayoutSubviews() {
    super.updateViewConstraints()
    self.tableHeight?.constant = self.table.contentSize.height
}

최신 정보

마지막 행이 잘린 경우 willDisplay 셀 함수에서 viewWillLayoutSubviews ()를 호출하십시오.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    self.viewWillLayoutSubviews()
}


답변

나는 iOS 7에서 이것을 시도했고 그것은 나를 위해 일했다.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView sizeToFit];
}


답변

테이블보기에서 contentSize 속성에 대한 관찰자를 추가하고 그에 따라 프레임 크기를 조정하십시오.

[your_tableview addObserver:self forKeyPath:@"contentSize" options:0 context:NULL];

콜백에서 :

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
         CGRect frame = your_tableview.frame;
         frame.size = your_tableview.contentSize;
         your_tableview.frame = frame;
    }

이것이 도움이되기를 바랍니다.


답변

스크롤보기 안에 테이블보기가 있었고 tableView의 높이를 계산하고 그에 따라 크기를 조정해야했습니다. 내가 취한 단계는 다음과 같습니다.

0) scrollView에 UIView를 추가하십시오 (아마도이 ​​단계없이 작동하지만 가능한 충돌을 피하기 위해 수행했습니다)-이것은 테이블 뷰의 컨테이너 뷰입니다. 이 단계를 수행하면 뷰 경계를 테이블 뷰의 경계로 바로 설정하십시오.

1) UITableView의 하위 클래스를 만듭니다.

class IntrinsicTableView: UITableView {

    override var contentSize:CGSize {
        didSet {
            self.invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        self.layoutIfNeeded()
        return CGSize(width: UIViewNoIntrinsicMetric, height: contentSize.height)
    }

}

2) 스토리 보드의 테이블 뷰 클래스를 IntrinsicTableView로 설정하십시오. http://joxi.ru/a2XEENpsyBWq0A

3) heightConstraint를 테이블 뷰로 설정하십시오.

4) 테이블의 IBoutlet을 ViewController로 드래그하십시오.

5) 테이블 높이 제약 조건의 IBoutlet을 ViewController로 드래그하십시오.

6)이 메소드를 ViewController에 추가하십시오.

override func viewWillLayoutSubviews() {
        super.updateViewConstraints()
        self.yourTableViewsHeightConstraint?.constant = self.yourTableView.intrinsicContentSize.height
    }

도움이 되었기를 바랍니다


답변

테이블 뷰의 컨텐츠 크기 변경을 직접 추적하지 않으려는 경우이 서브 클래스가 유용 할 수 있습니다.

protocol ContentFittingTableViewDelegate: UITableViewDelegate {
    func tableViewDidUpdateContentSize(_ tableView: UITableView)
}

class ContentFittingTableView: UITableView {

    override var contentSize: CGSize {
        didSet {
            if !constraints.isEmpty {
                invalidateIntrinsicContentSize()
            } else {
                sizeToFit()
            }

            if contentSize != oldValue {
                if let delegate = delegate as? ContentFittingTableViewDelegate {
                    delegate.tableViewDidUpdateContentSize(self)
                }
            }
        }
    }

    override var intrinsicContentSize: CGSize {
        return contentSize
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        return contentSize
    }
}