การตั้งค่าความสูงของแถวเซลล์ที่กำหนดเองในกระดานเรื่องราวไม่ตอบสนอง


213

ฉันกำลังพยายามปรับความสูงของเซลล์สำหรับหนึ่งในเซลล์ในมุมมองตารางของฉัน ฉันกำลังปรับขนาดจากการตั้งค่า "ความสูงของแถว" ภายใน "ตัวตรวจสอบขนาด" ของเซลล์ที่เป็นปัญหา เมื่อฉันเรียกใช้แอปบน iPhone เซลล์จะมีการตั้งค่าขนาดเริ่มต้นจาก "ขนาดแถว" ในมุมมองตาราง

ถ้าฉันเปลี่ยน "ขนาดแถว" ของมุมมองตารางขนาดของเซลล์ทั้งหมดจะเปลี่ยนไป ฉันไม่ต้องการทำเช่นนั้นเพราะฉันต้องการขนาดที่กำหนดเองสำหรับเซลล์เดียวเท่านั้น ฉันเคยเห็นโพสต์มากมายที่มีวิธีแก้ปัญหาแบบเป็นโปรแกรม แต่ฉันต้องการทำผ่านกระดานเรื่องราวถ้าเป็นไปได้

คำตอบ:


295

บนเซลล์แบบไดนามิกrowHeightตั้งค่าบน UITableView จะแทนที่แถวของแต่ละเซลล์ความสูง

แต่สำหรับเซลล์สแตติกการrowHeightตั้งค่าในแต่ละเซลล์สามารถแทนที่ UITableView ได้

ไม่แน่ใจว่าเป็นปัญหาหรือไม่ Apple อาจตั้งใจทำสิ่งนี้หรือไม่


36
คำตอบที่ถูกต้อง # 3 และโดยเฉพาะเพราะคำตอบนี้ใช้กับตัวสร้างส่วนติดต่อ / กระดานเรื่องราว หากคุณเลือกเซลล์ใน IB จากนั้นตัวตรวจสอบขนาดจะแสดงความสูงของแถวที่ด้านบน (ด้วยช่องทำเครื่องหมาย "กำหนดเอง") แต่ถ้าคุณเลือกมุมมองตารางทั้งหมดตัวตรวจสอบขนาดจะแสดงความสูงของแถวที่ด้านบนด้วย " ในกรณีนี้). ดังที่ pixelfreak กล่าวว่าจะใช้เฉพาะการตั้งค่ามุมมองตารางสำหรับเซลล์แบบไดนามิก (ไม่แน่ใจว่ามันเป็นความตั้งใจ)
Rhubarb

8
คำตอบนี้บอกเป็นนัยว่าทางออกจะเป็นเพียงการเปลี่ยนUITableViewเนื้อหาจากDynamic Prototypesเป็นStatic Cellsฉันทำอย่างนั้นและโครงการทั้งหมดของฉันก็ระเบิดขึ้น .. เกือบจะถูกฆ่าตัวตาย
abbood

4
มีวิธีการรับหมายเลขนี้หรือไม่? วิธีเดียวที่จะขุดมันลึกลงไปคือการดำดิ่งสู่กระดานเรื่องราวและดึงมันออกมาจากที่นั่น?
Biclops

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

ดูเหมือนจะยังเป็นปัญหาถ้าคุณแรกตั้งค่ามุมมองตารางเป็น "เซลล์แบบคงที่" จากนั้นเปลี่ยนเป็น "ต้นแบบแบบไดนามิก." ฉันมีปัญหาที่แม้แต่วิธีการมอบหมายสำหรับ rowHeight ก็ถูกละเว้น ฉันแก้ไขมันเป็นครั้งแรกโดยการแก้ไข XML สตอรีบอร์ดโดยตรงจากนั้นก็สร้างฉากสตอรี่บอร์ดใหม่ตั้งแต่ต้นโดยใช้ต้นแบบแบบไดนามิกตั้งแต่เริ่มต้น
Eric Goldberg

84

หากคุณใช้ UITableViewController ให้ใช้วิธีนี้:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

ในฟังก์ชั่นของแถวคุณสามารถเลือกความสูง ตัวอย่างเช่น,

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) {
       return 100;
    } 
    else {
       return 60;
    }
}

ในตัวอย่างนี้ความสูงของแถวแรกคือ 100 พิกเซลและอื่น ๆ คือ 60 พิกเซล

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


2
ข้อผิดพลาดคือต้องทำทั้งสองอย่าง (ตรวจสอบกำหนดเองและแก้ไขค่าความสูงของแถวในสตอรีบอร์ด && ระบุไว้ในส่วนสูง ForRowAtIndexPath) หรือไม่
marciokoko

คุณสามารถช่วยฉันเกี่ยวกับเรื่องนี้? ฉันต้องมีเซลล์แบบไดนามิกที่มีความสูงแบบไดนามิก แต่ถ้าฉันใช้วิธีนี้ไม่ว่าฉันจะส่งกลับเซลล์ทั้งหมดหายไปแทน ยกเว้นใน iPhone 5 ซึ่งเป็นอุปกรณ์ที่ใช้งานได้ตามที่คาดหวัง คุณเข้าใจไหมว่าทำไม
Ostmeistro

34

สำหรับเซลล์แบบไดนามิกให้rowHeightตั้งค่าให้UITableViewแทนที่แต่ละเซลล์ ' rowHeightเสมอ

พฤติกรรมนี้คือ IMO ข้อบกพร่อง เมื่อใดก็ตามที่คุณต้องจัดการ UI ของคุณในสองสถานที่มีแนวโน้มที่จะเกิดข้อผิดพลาด ตัวอย่างเช่นหากคุณเปลี่ยนขนาดมือถือของคุณในกระดานเรื่องราวคุณต้องจำไว้ว่าต้องเปลี่ยนขนาดเซลล์heightForRowAtIndexPath:ด้วยเช่นกัน จนกระทั่งแอปเปิ้ลช่วยแก้ไขข้อผิดพลาดที่วิธีแก้ปัญหาที่ดีที่สุดในปัจจุบันคือการแทนที่heightForRowAtIndexPath:แต่ใช้เซลล์ต้นแบบที่เกิดขึ้นจริงจากกระดานเพื่อตรวจสอบความสูงมากกว่าการใช้หมายเลขมายากล นี่คือตัวอย่าง:

- (CGFloat)tableView:(UITableView *)tableView 
           heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    /* In this example, there is a different cell for
       the top, middle and bottom rows of the tableView.
       Each type of cell has a different height.
       self.model contains the data for the tableview 
    */
    static NSString *CellIdentifier;
    if (indexPath.row == 0) 
        CellIdentifier = @"CellTop";
    else if (indexPath.row + 1 == [self.model count] )
        CellIdentifier = @"CellBottom";
    else
        CellIdentifier = @"CellMiddle";

    UITableViewCell *cell = 
              [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    return cell.bounds.size.height;
}

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


2
ฉันโพสต์คำตอบพร้อมรหัสเต็มรวมถึงแคช; ดูstackoverflow.com/a/16881312/292166
JosephH

1
ว้าวว้าวว้าว! ฉันตอบคำตอบแล้ว แต่ต้องระวัง! วิธีการนี้ไม่เพียง แต่ทำให้เกิดการลงโทษอย่างมีประสิทธิภาพตามที่ @Brennan แสดงความคิดเห็น แต่ยังทำให้การจัดสรรหน่วยความจำเพิ่มขึ้นในแต่ละครั้งที่โหลดซ้ำข้อมูลบางอย่างเช่นหน่วยความจำรั่ว! จำเป็นต้องใช้วิธีการแก้ปัญหาของ lensove ด้านบน! ใช้เวลาทั้งวันเพื่อจับความจำรั่ว!
skywinder

ไม่ทำงานใน Swift เพราะ cell.bounds.size.height ส่งคืนค่าเสมอ 0.0
King-Wizard

1
เซลล์ยังไม่มีอยู่ในขณะที่ระบบเรียกเมธอด tableView: heightForRowAtIndexPath ของคุณ คุณควรจะสามารถใช้ indexPath ที่ส่งให้คุณเพื่อจัดทำดัชนีลงในตัวแบบข้อมูลของคุณและดูว่าจะใช้เซลล์ประเภทใดจากนั้นคำนวณความสูงสำหรับเซลล์นั้นและส่งคืน ที่ช่วยให้ระบบจัดโครงสร้างเซลล์ในตารางก่อนที่จะสร้างเซลล์ใด ๆ
King-Wizard

1
นอกจากนี้คุณไม่ควรเรียกวิธี cellForRowAtIndexPath ของคุณเอง มุมมองตารางมีเมธอด cellForRowAtIndexPath ที่จะส่งคืนเซลล์สำหรับพา ธ ดัชนีนั้นหากปรากฏบนหน้าจอในปัจจุบัน แต่บ่อยครั้งที่พา ธ ดัชนีไม่มีเซลล์ที่เกี่ยวข้อง
King-Wizard

22

ฉันได้สร้างรหัสสำหรับคำตอบ / ความคิดเห็นที่หลากหลายเพื่อให้สามารถใช้กับกระดานเรื่องราวที่ใช้เซลล์ต้นแบบได้

รหัสนี้:

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

ขอบคุณ Answerbot, Brennan และ lensovet

- (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = nil;

    switch (indexPath.section)
    {
        case 0:
            cellIdentifier = @"ArtworkCell";
            break;
         <... and so on ...>
    }

    return cellIdentifier;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];
    static NSMutableDictionary *heightCache;
    if (!heightCache)
        heightCache = [[NSMutableDictionary alloc] init];
    NSNumber *cachedHeight = heightCache[cellIdentifier];
    if (cachedHeight)
        return cachedHeight.floatValue;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    CGFloat height = cell.bounds.size.height;
    heightCache[cellIdentifier] = @(height);
    return height;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    <... configure cell as usual...>

ฉันรู้ว่านี่เป็นคำตอบเก่า แต่ไม่มีใครพบว่าสิ่งนี้ส่งผลให้สแตกล้น? เมื่อมุมมองโหลดฉันได้รับ UISectionRowData refreshWithSection: tableViewRowData: ซึ่งเรียก tableView: heightForRowAtIndexPath: ซึ่งเรียก dequeueReusableCellWithIdentifier: ซึ่งเรียก [UISectionRowData ... ] ดังนั้นฉันจึงเรียกซ้ำซ้อนล้น ฉันต้องการใช้โซลูชันนี้จริงๆ แต่ดูเหมือนจะไม่ทำงานกับ iOS7
sbaker

ไม่ทำงานใน Swift เพราะ cell.bounds.size.height ส่งคืนค่าเสมอ 0.0
King-Wizard

เซลล์ยังไม่มีอยู่ในขณะที่ระบบเรียกเมธอด tableView: heightForRowAtIndexPath ของคุณ คุณควรจะสามารถใช้ indexPath ที่ส่งให้คุณเพื่อจัดทำดัชนีลงในตัวแบบข้อมูลของคุณและดูว่าจะใช้เซลล์ประเภทใดจากนั้นคำนวณความสูงสำหรับเซลล์นั้นและส่งคืน ที่ช่วยให้ระบบจัดโครงสร้างเซลล์ในตารางก่อนที่จะสร้างเซลล์ใด ๆ
King-Wizard

นอกจากนี้คุณไม่ควรเรียกวิธี cellForRowAtIndexPath ของคุณเอง มุมมองตารางมีเมธอด cellForRowAtIndexPath ที่จะส่งคืนเซลล์สำหรับพา ธ ดัชนีนั้นหากปรากฏบนหน้าจอในปัจจุบัน แต่บ่อยครั้งที่พา ธ ดัชนีไม่มีเซลล์ที่เกี่ยวข้อง
King-Wizard

@ snow-tiger ฉันไม่ได้ลองอย่างรวดเร็ว แต่ฉันไม่เข้าใจความคิดเห็นของคุณ ฉันไม่ได้เรียก 'cellForRowAtIndexPath' ของตัวเอง [method] และมันก็ตั้งใจว่าฉันจะไม่ทำ ฉันยังทราบด้วยว่าเซลล์ไม่มีอยู่ ณ เวลา tableView: heightForRowAtIndexPath ถูกเรียกนั่นคือจุดทั้งหมดของรหัสนี้และทำไมมันจึงใช้ dequeueReusableCellWithIdentifier เพื่อรับเซลล์ รหัสที่โพสต์ในคำตอบนี้ใช้งานได้ อาจมีบางสิ่งที่ไม่ถูกต้องในการแปลงที่รวดเร็วหรือกำลังพยายามแก้ไขปัญหาอื่นที่เป้าหมาย / คำถามนี้ตอบ
JosephH

19

ที่จริงแล้วมีสองที่ที่คุณต้องการเปลี่ยนเป็นความสูงของแถวก่อนอื่นเซลล์ (คุณเปลี่ยนไปแล้ว) จากนั้นเลือกมุมมองตารางและตรวจสอบตัวตรวจสอบขนาด


ใน tableview (ไม่ใช่ cellview)> ในแท็บตัวตรวจสอบขนาด> ความสูงของแถว
iman kazemayni

ผลักดันฉันถั่วทุกครั้งที่ฉันลืมรายละเอียดนี้ ไม่มีความคิดว่าทำไมการปรับเซลล์ไม่อัปเดต tableView โดยอัตโนมัติเมื่อใช้กระดานเรื่องราว!
สกูตเตอร์

11

ฉันคิดว่ามันเป็นข้อผิดพลาด

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

ฉันแก้ไขปัญหานี้ด้วยวิธีนี้


10

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

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    if indexPath.row == 0 || indexPath.row == 1{
        let cell = self.tableView.dequeueReusableCellWithIdentifier("section1", forIndexPath: indexPath) as! Section1TableViewCell
        self.tableView.rowHeight = 150
        cell.label1.text = "hiiiiii"
        cell.label2.text = "Huiiilllllll"
        return cell

    } else {

        let cell = self.tableView.dequeueReusableCellWithIdentifier("section2", forIndexPath: indexPath) as! Section2TableViewCell
        self.tableView.rowHeight = 60
        cell.label3.text = "llll"
        return cell
    }

}

วิธีนี้ใช้ได้ผล แต่โดยทั่วไปคุณสามารถทำได้:cell.sizeToFit(); self.tableView.rowHeight = cell.frame.height
Andy Chou

7

คุณสามารถรับความสูงของ UITableviewCell (ใน UITableviewController - เซลล์แบบคงที่) จากกระดานเรื่องราวด้วยความช่วยเหลือของบรรทัดต่อไปนี้

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
   CGFloat height = [super tableView:tableView heightForRowAtIndexPath:indexPath];

    return height;
}

6

เปิดกระดานเรื่องราวในมุมมอง XML แล้วลองแก้ไข rowHeightแอตทริบิวต์ขององค์ประกอบที่ต้องการ

มันทำงานสำหรับฉันเมื่อฉันพยายามตั้งค่าแถวที่กำหนดเองสูงสำหรับแถวต้นแบบของฉัน มันไม่ทำงานผ่านตัวตรวจสอบ แต่ใช้งานผ่าน XML


1
ฉันคลิกขวาแล้วเลือก "open as" -> "source code" RowHeight ถูกตั้งค่าเป็น 120 แล้วฉันเชื่อว่ากระดานเรื่องราวมีข้อบกพร่องที่นั่นและจะละเว้นความสูงของเซลล์ที่กำหนดเอง
zirinisp

6

คุณสามารถใช้ต้นแบบcellsพร้อมกำหนดเองheightจากนั้นเรียกใช้cellForRowAtIndexPath:และส่งคืนต้นแบบframe.height:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self tableView:tableView
                    cellForRowAtIndexPath:indexPath];
    return cell.frame.size.height;
}

การเพิ่มวิธีนี้ทำงานได้ดีมากและตอนนี้ยังคงปรับแต่งทั้งหมดในกระดานเรื่องราวตามที่ควรจะเป็น
daspianist

โดยทางออกที่ดีที่สุด
TheJeff

4

หากคุณต้องการตั้งค่าความสูงของแถวคงที่คุณสามารถทำสิ่งนี้:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 120;
}

4

ฉันเพิ่งต่อสู้กับสิ่งนี้ ปัญหาของฉันคือโซลูชันที่โพสต์ข้างต้นโดยใช้heightForRowAtIndexPath:วิธีการนี้จะใช้งานได้กับ iOS 7.1 ในเครื่องมือจำลองการทำงาน แต่หลังจากนั้นทำให้ผลลัพธ์หมดไปโดยการสลับไปใช้ iOS 8.1

ฉันเริ่มอ่านเพิ่มเติมเกี่ยวกับเซลล์ปรับขนาดตัวเอง (แนะนำใน iOS 8 อ่านที่นี่ ) เห็นได้ชัดว่าการใช้งานUITableViewAutomaticDimensionจะช่วยใน iOS 8 ฉันลองใช้เทคนิคนั้นและลบการใช้งานheightForRowAtIndexPath:และ voila มันทำงานได้ดีใน iOS 8 ตอนนี้ แต่แล้ว iOS 7 ก็ไม่ใช่ ฉันต้องทำอะไร ฉันต้องการheightForRowAtIndexPath:iOS 7 ไม่ใช่ iOS 8

นี่คือทางออกของฉัน (ตัดเพื่อประโยชน์ของความกะทัดรัด) ซึ่งยืมมาจากคำตอบ @JosephH โพสต์ด้านบน:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.estimatedRowHeight = 50.;
    self.tableView.rowHeight = UITableViewAutomaticDimension;

    // ...
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
        return UITableViewAutomaticDimension;

    } else {
        NSString *cellIdentifier = [self reuseIdentifierForCellAtIndexPath:indexPath];
        static NSMutableDictionary *heightCache;
        if (!heightCache)
            heightCache = [[NSMutableDictionary alloc] init];
        NSNumber *cachedHeight = heightCache[cellIdentifier];
        if (cachedHeight)
            return cachedHeight.floatValue;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    CGFloat height = cell.bounds.size.height;
    heightCache[cellIdentifier] = @(height);
    return height;
    }
}

- (NSString *)reuseIdentifierForCellAtIndexPath:(NSIndexPath *)indexPath {
    NSString * reuseIdentifier;
    switch (indexPath.row) {
        case 0:
            reuseIdentifier = EventTitleCellIdentifier;
            break;
        case 2:
            reuseIdentifier = EventDateTimeCellIdentifier;
            break;
        case 4:
            reuseIdentifier = EventContactsCellIdentifier;
            break;
        case 6:
            reuseIdentifier = EventLocationCellIdentifier;
            break;
        case 8:
            reuseIdentifier = NotesCellIdentifier;
            break;
        default:
            reuseIdentifier = SeparatorCellIdentifier;
            break;
    }

    return reuseIdentifier;
}

SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO (@ "8.0") จริง ๆ แล้วมาจากชุดคำจำกัดความของแมโครที่ฉันใช้ซึ่งฉันพบที่ไหนสักแห่ง (มีประโยชน์มาก) พวกเขาถูกกำหนดเป็น:

#define SYSTEM_VERSION_EQUAL_TO(v)                  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v)              ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v)     ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

2

ปัญหาเดียวกันที่เกิดขึ้นเมื่อทำงานบนXCode 9 โดยใช้สวิฟท์ 4

เพิ่ม AutoLayoutสำหรับองค์ประกอบ UI ภายในเซลล์และความสูงของแถวเซลล์ที่กำหนดเองจะทำงานตามที่ระบุ


1
สวัสดีโปรดทำยังไง
Back Packer

คุณเพียงแค่ต้องเพิ่มข้อ จำกัด ที่ด้านล่างของเซลล์
Justin

เมื่อฉันทำสิ่งนี้และเลือก "อัตโนมัติ" ในกระดานเรื่องราวเพื่อความสูงของเซลล์มันต้องการตั้งค่าความสูงทั้งหมดเป็น 44 ในกระดานเรื่องราวแม้ว่ามันจะถูกต้องเมื่อฉันเรียกใช้ ฉันจะทำให้กระดานเรื่องราวแสดงได้อย่างถูกต้องได้อย่างไร
เดวิด

1

สำหรับเซลล์แบบไดนามิกชุด rowHeight บน UITableView จะแทนที่ rowHeight ของแต่ละเซลล์เสมอ เพียงคำนวณความสูงแบบไดนามิกหากเนื้อหาภายในแถว


0

ทางออกที่แท้จริงที่ฉันหาได้คือ

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = ...; // Instantiate with a "common" method you'll use again in cellForRowAtIndexPath:
    return cell.frame.size.height;
}

วิธีนี้ใช้ได้ผลและอนุญาตให้ไม่มีสวิตช์ที่น่ากลัว / หากทำซ้ำตรรกะในกระดานเรื่องราวแล้ว ไม่แน่ใจเกี่ยวกับประสิทธิภาพ แต่ฉันเดาว่าเมื่อมาถึงcellForRow:เซลล์ที่มีการ initalized แล้วมันเป็นไปอย่างรวดเร็ว แน่นอนอาจมีความเสียหายหลักประกันที่นี่ แต่ดูเหมือนว่ามันทำงานได้ดีสำหรับฉันที่นี่

ฉันโพสต์ที่นี่ด้วย: https://devforums.apple.com/message/772464

แก้ไข: Ortwin Gentzเตือนฉันว่าheightForRowAtIndexPath:จะถูกเรียกสำหรับทุกคนเซลล์ของ TableView ไม่เพียง แต่เซลล์ที่มองเห็นได้ ฟังดูมีเหตุผลเนื่องจาก iOS จำเป็นต้องทราบความสูงทั้งหมดเพื่อให้สามารถแสดงแถบเลื่อนด้านขวา หมายความว่ามันอาจจะใช้ได้กับ TableViews ขนาดเล็ก (เช่น 20 Cells) แต่ลืมไปเลยกับ 1000 Cell TableView

นอกจากนี้เคล็ดลับก่อนหน้านี้กับ XML: เหมือนกับความคิดเห็นแรกสำหรับฉัน ค่าที่ถูกต้องมีอยู่แล้ว


0

เพิ่มเป็นความคิดเห็น แต่โพสต์เป็นคำตอบสำหรับการมองเห็น:

ดูเหมือนจะยังเป็นปัญหาถ้าคุณแรกตั้งค่ามุมมองตารางเป็น "เซลล์แบบคงที่" จากนั้นเปลี่ยนเป็น "ต้นแบบแบบไดนามิก." ฉันมีปัญหาที่แม้แต่วิธีการมอบหมายสำหรับheightForRowAtIndexPathการถูกเพิกเฉย ฉันแก้ไขมันเป็นครั้งแรกโดยการแก้ไข XML สตอรีบอร์ดโดยตรงจากนั้นก็สร้างฉากสตอรี่บอร์ดใหม่ตั้งแต่เริ่มต้นโดยใช้ต้นแบบแบบไดนามิกตั้งแต่เริ่มต้น


0

เนื่องจากฉันไม่พบวิธีแก้ไขปัญหาใด ๆ ผ่านทางตัวสร้างส่วนต่อประสานฉันตัดสินใจที่จะโพสต์วิธีแก้ปัญหาแบบเป็นโปรแกรมไปยังปัญหาในSwiftโดยใช้เซลล์ไดนามิกสองเซลล์แม้ว่าคำถามเริ่มต้นจะถามหาวิธีแก้ปัญหาผ่านตัวสร้างส่วนต่อประสาน ไม่ว่าฉันคิดว่ามันจะมีประโยชน์สำหรับชุมชน Stack Overflow หรือไม่:

    import UIKit

    enum SignInUpMenuTableViewControllerCellIdentifier: String {
       case BigButtonCell = "BigButtonCell"
       case LabelCell = "LabelCell"
    }

    class SignInUpMenuTableViewController: UITableViewController {
            let heightCache = [SignInUpMenuTableViewControllerCellIdentifier.BigButtonCell : CGFloat(50),
                              SignInUpMenuTableViewControllerCellIdentifier.LabelCell : CGFloat(115)]

    private func cellIdentifierForIndexPath(indexPath: NSIndexPath) -> SignInUpMenuTableViewControllerCellIdentifier {
        if indexPath.row == 2 {
            return SignInUpMenuTableViewControllerCellIdentifier.LabelCell
        } else {
            return SignInUpMenuTableViewControllerCellIdentifier.BigButtonCell
        }
    }

   override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
       return self.heightCache[self.cellIdentifierForIndexPath(indexPath)]!
   }

   ...

  }

ทั้งหมดนี้เป็นสิ่งที่ดีและดี แต่ถ้าฉันไม่อ่านรหัสผิดมันก็แค่อาศัยเลขอาถรรพ์และไม่สนใจค่าใด ๆ ที่คุณกำหนดไว้ใน IB สำหรับเซลล์แบบไดนามิกดังนั้น ... ไม่ใช่วิธีแก้ปัญหาคำถามของ OP แน่นอน
Danny

0

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.