ปรับขนาด UITableView ให้พอดีกับเนื้อหา


170

ฉันกำลังสร้างแอพที่จะมีคำถามในUILabelคำตอบแบบหลายตัวเลือกและแสดงในUITableViewแต่ละแถวแสดงทางเลือกที่หลากหลาย คำถามและคำตอบจะแตกต่างกันไปดังนั้นฉันต้องการUITableViewให้สิ่งนี้มีความสูงแบบไดนามิก

ฉันต้องการหาsizeToFitงานทำสำหรับโต๊ะ ตำแหน่งที่เฟรมของตารางถูกตั้งค่าเป็นความสูงของเนื้อหาทั้งหมด

ใครสามารถให้คำแนะนำเกี่ยวกับวิธีที่ฉันสามารถบรรลุสิ่งนี้


สำหรับผู้ที่ต้องการทำสิ่งที่คล้ายกันใน OSX ดูคำถามนี้: stackoverflow.com/questions/11322139/ …
Michael Teper

1
@MiMo สวัสดีคุณช่วยอธิบายว่ามีอะไรผิดปกติกับวิธี "sizeToFit" ได้มั้ย :)
iamdavidlam

“ผมอยากที่จะหา 'sizeToFit' งานรอบ” คุณเคยลอง- sizeToFitวิธีของ UIView แล้วหรือยัง
Slipp D. Thompson

คำตอบ:


155

ที่จริงฉันพบคำตอบเอง

ฉันเพิ่งสร้างใหม่CGRectสำหรับtableView.frameด้วยheightของtable.contentSize.height

ที่กำหนดความสูงของUITableViewถึงheightเนื้อหา เนื่องจากรหัสจะปรับเปลี่ยน 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;
    });

3
เป็นไปได้ที่จะพบปัญหาเกี่ยวกับวิธีนี้ หากคุณมีรายการใหญ่อาจเป็นไปได้ว่าความสูงของเฟรมจะตัดบางส่วนของเซลล์ คุณสามารถเห็นสิ่งนี้เกิดขึ้นหากคุณเปิดใช้งานการตีกลับและเลื่อนไปที่ด้านล่างเพื่อดูบางเซลล์ที่เด้งออกมาจากมุมมอง
Whyoz

คุณระบุความสูงได้ที่ไหน คุณได้ทำการโทรเพื่อโหลดข้อมูลใหม่และปรับขนาดภายหลังหรือไม่
James

27
ที่ที่ดีที่สุดในการวางรหัสนี้อยู่ที่ไหน ฉันลองใช้ใน viewDidLoad และมันใช้งานไม่ได้เพราะสันนิษฐานว่าวิธีการมอบสิทธิ์ tableview ไม่ได้เริ่มทำงาน วิธีการมอบสิทธิ์ใดดีที่สุด
Kyle Clegg

4
ฉันทำสิ่งนี้คือ viewDidAppear และดูเหมือนว่าจะใช้ได้ โปรดทราบว่ามุมมองตารางอาจสูงกว่าเนื้อหาเล็กน้อยเนื่องจากมีพื้นที่ว่างสำหรับส่วนหัวและส่วนท้าย
เล็กน้อย

2
ฉันพบว่า viewDidAppear เป็นสถานที่ที่เหมาะสำหรับการวางสิ่งที่คุณต้องการให้เกิดขึ้นหลังจากการเรียก tableView cellForRowAtIndexPath เริ่มต้นทั้งหมดเสร็จสิ้นแล้ว
rigdonmr

120

โซลูชัน Swift 5 และ 4.2 ที่ไม่มี KVO, DispatchQueue หรือตั้งค่าข้อ จำกัด ด้วยตัวคุณเอง

การแก้ปัญหานี้จะขึ้นอยู่กับคำตอบของ 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รูปแบบของคุณและตั้งข้อ จำกัด ในทุกด้าน ContentSizedTableViewตั้งค่าระดับของมันไป

3) คุณจะเห็นข้อผิดพลาดบางเพราะ Storyboard ไม่ได้ใช้ subclass ของเราintrinsicContentSizeเข้าบัญชี แก้ไขสิ่งนี้โดยการเปิดตัวตรวจสอบขนาดและแทนที่ intrinsicContentSize เป็นค่าตัวยึดตำแหน่ง นี่คือการแทนที่สำหรับเวลาการออกแบบ ที่ runtime มันจะใช้ override ในContentSizedTableViewคลาสของเรา


อัปเดต:เปลี่ยนรหัสสำหรับ Swift 4.2 หากคุณใช้รุ่นก่อนหน้าให้ใช้UIViewNoIntrinsicMetricแทนUIView.noIntrinsicMetric


1
คำตอบที่ดีมากมันใช้ได้สำหรับฉันขอบคุณ แต่สิ่งหนึ่งที่ - ในกรณีของฉันฉันจำเป็นต้องเปลี่ยนคลาสของการtableViewเป็น IntrinsicTableViewในกระดานเรื่องราว UIViewฉันไม่จำเป็นต้องฝังมุมมองตารางของฉันภายในอีก
dvp.petrov

ใช่คุณถูก. ฉันปรับปรุงคำตอบของฉัน สามารถอ่านขั้นตอนที่ 2 ได้ตามที่คุณพูด แน่นอนผมหมายถึงการตั้งค่าไปtableView IntrinsicTableViewการห่อพิเศษUIViewก็ไม่จำเป็นเช่นกัน คุณสามารถใช้มุมมองพาเรนต์ใด ๆ ที่มีอยู่ของหลักสูตร :)
fl034

1
Swift 4มันใช้งานได้ดีสำหรับฉันtableView.sizeToFit()
Souf ROCHDI

ใช่ว่าอาจเป็นทางออกที่ดีถ้าเนื้อหาของคุณเป็นแบบคงที่ ด้วยวิธีการของฉันคุณสามารถใช้เค้าโครงอัตโนมัติเพื่อฝัง tableView ที่มีเนื้อหาแบบไดนามิกในมุมมองอื่น ๆ และทำให้มันเต็มความสูงตลอดเวลาโดยไม่ต้องคิดเกี่ยวกับสถานที่ที่sizeToFit()จะต้องเรียก
fl034

2
ขอขอบคุณ Wonderful! สุดท้ายจับคู่เนื้อหาหลักและตัดคำสำหรับ tableview ...
แอมเบอร์เค

79

โซลูชันที่รวดเร็ว

ทำตามขั้นตอนเหล่านี้:

1- ตั้งค่าการจำกัดความสูงของตารางจากกระดานเรื่องราว

2- ลากข้อจำกัดความสูงจากกระดานเรื่องราวและสร้าง @IBOutlet ไว้ในไฟล์ควบคุมมุมมอง

    @IBOutlet weak var tableHeight: NSLayoutConstraint!

3- จากนั้นคุณสามารถเปลี่ยนความสูงสำหรับตาราง dynamicaly โดยใช้รหัสนี้:

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

ปรับปรุง

หากแถวสุดท้ายถูกตัดให้คุณลองเรียกใช้ viewWillLayoutSubviews () ในฟังก์ชันเซลล์ willDisplay:

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

1
ทำงานให้ฉัน !! ขอบคุณ
Pushpa Y

5
โซลูชันนี้จะตัดแถวสุดท้ายใน Xcode 8.3 ให้ฉันเสมอ
เจน C

@Jec C: ไม่ใช่สำหรับฉันเช่นกัน
KMC

ทำงานให้ฉันด้วย !!
Antony Raphel

1
ฉันต้องใส่สิ่งนี้ในวิธี cellForRowAtIndexPath: หากฉันวางไว้ในเมธอด viewWillLayoutSubviews เนื้อหาที่คำนวณขนาดความสูงจะขึ้นอยู่กับความสูงโดยประมาณไม่ใช่ความสูงเนื้อหาจริง
มนู Mateos

21

ฉันลองสิ่งนี้ใน iOS 7 แล้วและมันก็ใช้ได้ผลสำหรับฉัน

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

3
หาก UITableView ของคุณเป็นแบบไดนามิก (หมายถึงข้อมูลที่โหลดเข้าและออกจากการเดินทาง) คุณจะต้องวางสิ่งนี้ไว้ที่อื่นไม่ใช่ใน viewDidLoad สำหรับฉันฉันใส่ไว้ใน cellForRowAtIndexPath ต้องเปลี่ยน "tableView" เป็นชื่อของคุณสมบัติ IBOutlet ของฉันเพื่อหลีกเลี่ยงข้อผิดพลาด "คุณสมบัติ tableView not found" ข้อผิดพลาด
jeremytripp

ขอบคุณมีปัญหากับการปรับขนาด tableview ใน popover มันทำงานได้
Zaporozhchenko Oleksandr

19

เพิ่มผู้สังเกตการณ์สำหรับคุณสมบัติ 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;
    }

หวังว่านี่จะช่วยคุณได้


2
คุณควรเพิ่มอีกหนึ่งสิ่ง คุณควรลบผู้สังเกตการณ์สำหรับมุมมองตาราง เพราะมันจะผิดพลาดถ้าเซลล์จัดสรรคืน
Mahesh Agrawal

12

ฉันมีมุมมองตารางภายในมุมมองเลื่อนและต้องคำนวณความสูงของ tableView และปรับขนาดตามความเหมาะสม นี่คือขั้นตอนที่ฉันได้ทำ:

0) เพิ่ม UIView ให้กับ scrollView ของคุณ (อาจจะทำงานได้โดยไม่มีขั้นตอนนี้ แต่ฉันทำเพื่อหลีกเลี่ยงความขัดแย้งที่อาจเกิดขึ้นได้) - นี่จะเป็นมุมมอง containr สำหรับมุมมองตารางของคุณ หากคุณทำตามขั้นตอนนี้ให้ตั้งค่าเส้นขอบมุมมองไปทางขวาของมุมมองตาราง

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) กำหนดคลาสของมุมมองตารางใน Storyboard เป็น IntrinsicTableView: สกรีนช็อต : http://joxi.ru/a2XEENpsyBWq0A

3) ตั้งค่าความสูงข้อ จำกัด เป็นมุมมองตารางของคุณ

4) ลาก IBoutlet ของตารางของคุณไปยัง ViewController ของคุณ

5) ลาก IBoutlet ของข้อจำกัดความสูงของตารางของคุณไปยัง ViewController ของคุณ

6) เพิ่มวิธีนี้ใน ViewController ของคุณ:

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

หวังว่านี่จะช่วยได้


ดูคำตอบของฉันซึ่งขึ้นอยู่กับคลาสย่อยของคุณ แต่ไม่จำเป็นต้องมีการจำกัดความสูง
fl034

@ fl034 มีลิงก์หรือไม่
Gulz

@ fl034 ฉันไม่คิดว่าคุณสามารถหลีกเลี่ยงการใช้ข้อ จำกัด เมื่อองค์ประกอบของคุณถูกฝังลงในมุมมองเลื่อน) กรณีของฉันอยู่กับ ScrollView
Gulz

ฉันยังมีมุมมองที่โต๊ะของเราภายในมุมมองเลื่อนและการทำงานอย่างสมบูรณ์ :)
fl034

ใช้งานได้กับฉันใน iOS 13 / Xcode 11 คุณหมดเวลาไปแล้ว 3 วันสำหรับความเมตตากรุณาขอขอบคุณ
Mehdi S.

8

ในกรณีที่คุณไม่ต้องการติดตามขนาดเนื้อหาของการเปลี่ยนแปลงตารางคุณอาจพบว่าคลาสย่อยนี้มีประโยชน์

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
    }
}

1
สำหรับ swift 3, intrinsicContentSize ได้กลายเป็น var, เช่นoverride public var intrinsicContentSize: CGSize { //... return someCGSize }
xaphod

ไม่ทำงานสำหรับฉัน ยังคงซ่อนด้านล่างของตาราง
Gulz

5

ในกรณีที่ contentSize ของคุณไม่ถูกต้องสิ่งนี้จะเป็นเพราะมันขึ้นอยู่กับการประเมินโดยรอบสูง (อัตโนมัติ) ให้ใช้สิ่งนี้ก่อน

tableView.estimatedRowHeight = 0;

แหล่งที่มา: https://forums.developer.apple.com/thread/81895


4

Swift 3, iOS 10.3

โซลูชันที่ 1: เพียงแค่ใส่self.tableview.sizeToFit()ในcellForRowAt indexPathฟังก์ชั่น ตรวจสอบให้แน่ใจว่าตั้งค่าความสูงของ tableview สูงขึ้นจากนั้นคุณต้อง นี่เป็นทางออกที่ดีหากคุณไม่มีมุมมองด้านล่างของตาราง อย่างไรก็ตามหากคุณมีข้อ จำกัด ของ tableview ด้านล่างจะไม่ได้รับการอัปเดต (ฉันไม่ได้พยายามแก้ไขเพราะฉันพบโซลูชัน 2)

ตัวอย่าง:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell", for: indexPath) as? TestCell {
        cell.configureCell(data: testArray[indexPath.row])
        self.postsTableView.sizeToFit()
        return cell
    }

    return UITableViewCell()
}

โซลูชันที่ 2: ตั้งค่าข้อจำกัดความสูงของ tableview ในกระดานเรื่องราวแล้วลากไปยัง ViewController หากคุณทราบความสูงเฉลี่ยของเซลล์ของคุณและคุณรู้ว่ามีองค์ประกอบหลายอย่างที่อาร์เรย์ของคุณมีอยู่คุณสามารถทำสิ่งนี้:

tableViewHeightConstraint.constant = CGFloat(testArray.count) * 90.0     // Let's say 90 is the average cell height

* แก้ไข:

หลังจากคำตอบทั้งหมดที่ฉันลองและทุกคนแก้ไขบางอย่าง แต่ไม่สมบูรณ์นี่คือคำตอบที่อธิบายและแก้ไขปัญหานี้อย่างสมบูรณ์


นี่เป็นวิธีแก้ปัญหาที่ง่ายมากมันใช้ได้ผลสำหรับฉันขอบคุณ @Dorde Nilovic
R. Mohan

1

คำตอบของ MimoและคำตอบของAnooj VMทั้งสองนั้นยอดเยี่ยม แต่มีปัญหาเล็ก ๆ ถ้าคุณมีรายการขนาดใหญ่อาจเป็นไปได้ว่าความสูงของเฟรมจะตัดเซลล์บางส่วนของคุณ

ดังนั้น. ฉันได้แก้ไขคำตอบเล็กน้อย:

dispatch_async(dispatch_get_main_queue()) {
    //This code will run in the main thread:
    CGFloat newHeight=self.tableView.contentSize.height;
    CGFloat screenHeightPermissible=(self.view.bounds.size.height-self.tableView.frame.origin.y);
    if (newHeight>screenHeightPermissible)
    {
        //so that table view remains scrollable when 'newHeight'  exceeds the screen bounds
        newHeight=screenHeightPermissible;
    }

    CGRect frame = self.tableView.frame;
    frame.size.height = newHeight;
    self.tableView.frame = frame;
}

1

มีวิธีที่ดีกว่ามากในการทำถ้าคุณใช้ AutoLayout: เปลี่ยนข้อ จำกัด ที่กำหนดความสูง เพียงคำนวณความสูงของเนื้อหาตารางของคุณจากนั้นค้นหาข้อ จำกัด และเปลี่ยนมัน นี่คือตัวอย่าง (สมมติว่าข้อ จำกัด ที่กำหนดความสูงของตารางของคุณนั้นเป็นข้อ จำกัด ความสูงที่สัมพันธ์กับ "เท่ากับ"):

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    for constraint in tableView.constraints {
        if constraint.firstItem as? UITableView == tableView {
            if constraint.firstAttribute == .height {
                constraint.constant = tableView.contentSize.height
            }
        }
    }
}

คุณสามารถปรับปรุงเกี่ยวกับเรื่องนี้ เพิ่มข้อ จำกัด เพิ่มเติมใน tableview ของคุณพูดความสูง <= 10,000 ใช้การลากตัวควบคุมจากตัวสร้างส่วนติดต่อไปยังไฟล์. h ของคุณเพื่อทำให้ข้อ จำกัด นี้เป็นคุณสมบัติของตัวควบคุมมุมมองของคุณ จากนั้นคุณสามารถหลีกเลี่ยงการวนซ้ำผ่านข้อ จำกัด และการค้นหา เพิ่งตั้งค่าโดยตรงmyTableHeightConstraint.constant = tableView.contentSize.height
RobP

1

สิ่งนี้ใช้ได้กับฉันโดยใช้เค้าโครงอัตโนมัติพร้อมมุมมองตารางที่มีเพียงส่วนเดียว

func getTableViewContentHeight(tableView: UITableView) -> CGFloat {
        tableView.bounds = CGRect(x: 0, y: 0, width: 300, height: 40)
        let rows = tableView.numberOfRows(inSection: 0)
        var height = CGFloat(0)
        for n in 0...rows - 1 {
            height = height + tableView.rectForRow(at: IndexPath(row: n, section: 0)).height
        }
        return height
    }

ฉันเรียกใช้ฟังก์ชันนี้เมื่อตั้งค่าเค้าโครงอัตโนมัติ (ตัวอย่างที่นี่ใช้ SnapKit แต่คุณได้แนวคิด):

    let height = getTableViewContentHeight(tableView: myTableView)
    myTableView.snp.makeConstraints {
        ...
        ...
        $0.height.equalTo(height)
    }

ฉันต้องการให้ UITableView สูงเท่าความสูงรวมของเซลล์เท่านั้น ฉันวนรอบเซลล์และสะสมความสูงทั้งหมดของเซลล์ เนื่องจากขนาดของมุมมองตารางเป็น CGRect.zero ณ จุดนี้ฉันจึงต้องกำหนดขอบเขตเพื่อให้สามารถปฏิบัติตามกฎการจัดวางอัตโนมัติที่กำหนดโดยเซลล์ ฉันตั้งค่าขนาดเป็นค่าโดยพลการที่ควรมีขนาดใหญ่พอ ขนาดจริงจะถูกคำนวณภายหลังโดยระบบเลย์เอาต์อัตโนมัติ


1

ฉันทำในลักษณะที่แตกต่างออกไปเล็กน้อยจริง ๆ แล้ว TableView ของฉันอยู่ใน scrollview ดังนั้นฉันจึงต้องจำกัดความสูงเป็น 0

จากนั้นที่รันไทม์ฉันทำการติดตามการเปลี่ยนแปลง

       func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            self.viewWillLayoutSubviews()
       }
    
       override func viewWillLayoutSubviews() {
            super.updateViewConstraints()
             DispatchQueue.main.async {
               self.tableViewHeightConstraint?.constant = self.myTableView.contentSize.height
               self.view.layoutIfNeeded()
          }
       }

0

ในฐานะที่เป็นส่วนขยายของคำตอบของ Anooj VM ฉันขอแนะนำสิ่งต่อไปนี้เพื่อรีเฟรชขนาดเนื้อหาเฉพาะเมื่อมีการเปลี่ยนแปลง

วิธีนี้ยังปิดการเลื่อนอย่างถูกต้องและรองรับรายการและการหมุนที่ใหญ่ขึ้น ไม่จำเป็นต้อง dispatch_async เนื่องจากการเปลี่ยนแปลงขนาดเนื้อหาถูกส่งไปที่เธรดหลัก

- (void)viewDidLoad {
        [super viewDidLoad];
        [self.tableView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:NULL]; 
}


- (void)resizeTableAccordingToContentSize:(CGSize)newContentSize {
        CGRect superviewTableFrame  = self.tableView.superview.bounds;
        CGRect tableFrame = self.tableView.frame;
        BOOL shouldScroll = newContentSize.height > superviewTableFrame.size.height;
        tableFrame.size = shouldScroll ? superviewTableFrame.size : newContentSize;
        [UIView animateWithDuration:0.3
                                    delay:0
                                    options:UIViewAnimationOptionCurveLinear
                                    animations:^{
                            self.tableView.frame = tableFrame;
        } completion: nil];
        self.tableView.scrollEnabled = shouldScroll;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    if ([change[NSKeyValueChangeKindKey] unsignedIntValue] == NSKeyValueChangeSetting &&
        [keyPath isEqualToString:@"contentSize"] &&
        !CGSizeEqualToSize([change[NSKeyValueChangeOldKey] CGSizeValue], [change[NSKeyValueChangeNewKey] CGSizeValue])) {
        [self resizeTableAccordingToContentSize:[change[NSKeyValueChangeNewKey] CGSizeValue]];
    } 
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    [self resizeTableAccordingToContentSize:self.tableView.contentSize]; }

- (void)dealloc {
    [self.tableView removeObserver:self forKeyPath:@"contentSize"];
}

0

รุ่น objc ของ Musa almatri

(void)viewWillLayoutSubviews
{
    [super updateViewConstraints];
    CGFloat desiredHeight = self.tableView.contentSize.height;
    // clamp desired height, if needed, and, in that case, leave scroll Enabled
    self.tableHeight.constant = desiredHeight;
    self.tableView.scrollEnabled = NO;
}

0

คุณสามารถลองใช้งานแบบกำหนดเองนี้ได้ AGTableView

เมื่อต้องการตั้งค่าข้อ จำกัด ของความสูงของ TableView การใช้กระดานเรื่องราวหรือโดยทางโปรแกรม (คลาสนี้ดึงข้อ จำกัด ความสูงโดยอัตโนมัติและตั้งค่าความสูงของมุมมองเนื้อหาเป็นความสูงมุมมองตารางของคุณ)

class AGTableView: UITableView {

    fileprivate var heightConstraint: NSLayoutConstraint!

    override init(frame: CGRect, style: UITableViewStyle) {
        super.init(frame: frame, style: style)
        self.associateConstraints()
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.associateConstraints()
    }

    override open func layoutSubviews() {
        super.layoutSubviews()

        if self.heightConstraint != nil {
            self.heightConstraint.constant = self.contentSize.height
        }
        else{
            self.sizeToFit()
            print("Set a heightConstraint to Resizing UITableView to fit content")
        }
    }

    func associateConstraints() {
        // iterate through height constraints and identify

        for constraint: NSLayoutConstraint in constraints {
            if constraint.firstAttribute == .height {
                if constraint.relation == .equal {
                    heightConstraint = constraint
                }
            }
        }
    }
}

หมายเหตุหากมีปัญหาใด ๆ yourTableView.layoutSubviews()ในการตั้งค่าความสูงแล้ว


0

ขึ้นอยู่กับคำตอบของfl034 แต่สำหรับผู้ใช้Xamarin.iOS :

    [Register("ContentSizedTableView")]
    public class ContentSizedTableView : UITableView
    {
        public ContentSizedTableView(IntPtr handle) : base(handle)
        {
        }

        public override CGSize ContentSize { get => base.ContentSize; set { base.ContentSize = value; InvalidateIntrinsicContentSize(); } }
        public override CGSize IntrinsicContentSize
        {
            get
            {
                this.LayoutIfNeeded();
                return new CGSize(width: NoIntrinsicMetric, height: ContentSize.Height);
            }
        }
    }

0

การปรับใช้ Swift 5 ของฉันคือการตั้งค่าข้อ จำกัด สูงของ tableView เป็นขนาดของเนื้อหา ( contentSize.height) วิธีนี้จะถือว่าคุณใช้เลย์เอาต์อัตโนมัติ รหัสนี้ควรอยู่ในcellForRowAtวิธี tableView

tableView.heightAnchor.constraint(equalToConstant: tableView.contentSize.height).isActive = true

-1

หากคุณต้องการให้ตารางของคุณเป็นแบบไดนามิกคุณจะต้องใช้วิธีการแก้ปัญหาตามเนื้อหาของตารางตามรายละเอียดด้านบน หากคุณต้องการแสดงตารางที่เล็กกว่าคุณสามารถใช้มุมมองคอนเทนเนอร์และฝัง UITableViewController ไว้ภายใน - UITableView จะถูกปรับขนาดตามขนาดคอนเทนเนอร์

นี่เป็นการหลีกเลี่ยงการคำนวณและการเรียกเลย์เอาต์มากมาย


1
อย่าใช้คำaboveเพราะสามารถสับคำตอบได้
Nik Kov

-3

โซลูชัน Mu สำหรับสิ่งนี้ใน swift 3 : เรียกใช้วิธีนี้ในviewDidAppear

func UITableView_Auto_Height(_ t : UITableView)
{
        var frame: CGRect = t.frame;
        frame.size.height = t.contentSize.height;
        t.frame = frame;        
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.