UITableView ตั้งค่าเป็นเซลล์แบบคงที่ เป็นไปได้ไหมที่จะซ่อนเซลล์บางเซลล์โดยทางโปรแกรม?


คำตอบ:


48

คุณกำลังมองหาโซลูชันนี้:

StaticDataTableViewController 2.0

https://github.com/xelvenone/StaticDataTableViewController

ซึ่งสามารถแสดง / ซ่อน / โหลดเซลล์แบบคงที่โดยมีหรือไม่มีภาพเคลื่อนไหวก็ได้!

[self cell:self.outletToMyStaticCell1 setHidden:hide]; 
[self cell:self.outletToMyStaticCell2 setHidden:hide]; 
[self reloadDataAnimated:YES];

หมายเหตุให้ใช้เท่านั้น (reloadDataAnimate: YES / NO) (อย่าเรียก [self.tableView reloadData] โดยตรง)

วิธีนี้ไม่ใช้วิธีแก้ปัญหาแฮ็กกี้ด้วยการตั้งค่าความสูงเป็น 0 และช่วยให้คุณเคลื่อนไหวการเปลี่ยนแปลงและซ่อนส่วนทั้งหมดได้


6
ปัญหาหนึ่งของการแก้ปัญหานั้นคือการทิ้งช่องว่างที่เซลล์ที่ซ่อนอยู่
แจ็ค

คุณหมายถึงช่องว่างอย่างไร? คุณช่วยอธิบายสถานการณ์ให้ดีขึ้นได้ไหมอาจจะเป็นบน github โดยตรง คุณเรียกใช้ตัวอย่างหรือไม่
Peter Lapisu

1
ฉันหมายความว่าถ้าคุณมีตัวอย่างสามส่วนและคุณซ่อนเซลล์จากส่วนตรงกลางช่องว่างที่ส่วนนั้นยังคงอยู่ ฉันไม่ได้ลองโครงการตัวอย่าง แต่ฉันได้ลองใช้รหัส ฉันจะลองดูตัวอย่าง
แจ็ค

1
ลองดูตัวอย่างมีการอัปเดตที่ใหญ่ขึ้นบางทีคุณอาจมีรหัสเก่า ... ทำงานได้ดีสำหรับฉัน
Peter Lapisu

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

165

ในการซ่อนเซลล์แบบคงที่ใน UITable:

  1. เพิ่มวิธีนี้ :

ในคลาสผู้ร่วมประชุมคอนโทรลเลอร์ UITableView ของคุณ:

วัตถุประสงค์ -C:

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

    if(cell == self.cellYouWantToHide)
        return 0; //set the hidden cell's height to 0

    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

รวดเร็ว:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    var cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    if cell == self.cellYouWantToHide {
        return 0
    }

    return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

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

  1. ในตัวออกแบบสร้างเต้าเสียบสำหรับเซลล์ที่คุณต้องการซ่อนทางออกของเซลล์ดังกล่าวเรียกว่า "cellYouWantToHide" ด้านบน
  2. ตรวจสอบ "Clip Subviews" ใน IB สำหรับเซลล์ที่คุณต้องการซ่อน เซลล์ที่คุณซ่อนอยู่จำเป็นต้องมี ClipToBounds = YES มิฉะนั้นข้อความจะกองอยู่ใน UITableView

10
ทางออกที่ดี เพื่อหลีกเลี่ยงClipToBoundsปัญหานี้คุณสามารถตั้งค่าเซลล์เป็นซ่อนได้ สิ่งนี้ดูเหมือนจะสะอาดกว่าสำหรับฉัน ;-)
MonsieurDart

13
+1 สำหรับ ClipToBounds = ใช่ โซลูชัน Numeorus ในเธรดอื่นพลาดไปแล้ว
Jeff

2
ความคิดที่ดี. นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุดที่ฉันพบ โซลูชันอื่น ๆ มีรหัสในสถานที่ตั้งแต่สองแห่งขึ้นไป BTW ใน IB ClipToBounds จะแสดงเป็น "Clip Subviews"
VaporwareWolf

1
แก้ไขเพียงเล็กน้อยให้ใช้self .cellYouWantToHide แทนสิ่งนี้ .cellYouWantToHide
Zoltan Vinkler

2
โดยไม่ต้องสร้างวัตถุเซลล์เรายังสามารถใช้ "index.row" เพื่อซ่อน "uitableviewcell"
g212gs

39

วิธีที่ดีที่สุดคือตามที่อธิบายไว้ในบล็อกต่อไปนี้ http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/

ออกแบบมุมมองตารางแบบคงที่ของคุณตามปกติในตัวสร้างอินเทอร์เฟซ - พร้อมด้วยเซลล์ที่ซ่อนอยู่ แต่มีสิ่งหนึ่งที่คุณต้องทำสำหรับทุกเซลล์ที่มีศักยภาพที่คุณต้องการซ่อน - ตรวจสอบคุณสมบัติ "คลิปมุมมองย่อย" ของเซลล์มิฉะนั้นเนื้อหาของเซลล์จะไม่หายไปเมื่อคุณพยายามซ่อนมัน (โดยการลดขนาดความสูง - เพิ่มเติมในภายหลัง)

ดังนั้น - คุณมีสวิตช์ในเซลล์และสวิตช์ควรจะซ่อนและแสดงเซลล์คงที่ เชื่อมต่อกับ IBAction และทำสิ่งนี้:

[self.tableView beginUpdates];
[self.tableView endUpdates];

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

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 1 && indexPath.row == 1) { // This is the cell to hide - change as you need
    // Show or hide cell
        if (self.mySwitch.on) {
            return 44; // Show the cell - adjust the height as you need
        } else {
            return 0; // Hide the cell
        }
   }
   return 44;
}

และนั่นแหล่ะ พลิกสวิตช์แล้วเซลล์จะซ่อนและปรากฏขึ้นอีกครั้งด้วยภาพเคลื่อนไหวที่ราบรื่นและสวยงาม


อัปเดต: คุณต้องตั้งค่า Cell Label ให้เป็นซ่อน / แสดงด้วย Cell Hide / Show มิฉะนั้นป้ายกำกับจะยุ่ง
Mohamed Saleh

1
คุณควรสังเกตว่าหาก UIView ใด ๆ ภายในเนื้อหาของเซลล์คงที่ของคุณมีข้อ จำกัด ใด ๆ ต่อเซลล์เนื้อหาคุณอาจได้รับข้อผิดพลาดรันไทม์หากข้อ จำกัด เหล่านั้นไม่ถูกต้องสำหรับความสูงของเซลล์ใหม่ของคุณ
Pedro Borges

1
คำตอบที่ดีที่สุด ขอบคุณ.
Eric Chen

1
ฉันรู้ว่าเคล็ดลับนี้ใช้ได้กับเนื้อหาแบบไดนามิก ใช้งานได้ดีกับแบบคงที่ด้วย เรียบง่ายเกินไป
มด

2
อันนี้ใช้งานได้จริง แต่เพื่อปกปิดจุดที่ขาดหายไป: ถ้าแถวที่จะซ่อน / แสดงมีตัวเลือกวันที่ให้ทำเฉพาะ [self.tableView beginUpdates]; [self.tableView endUpdates]; จะยังคงทิ้งความผิดพลาดขณะซ่อนมัน เพื่อกำจัดความผิดพลาดคุณควรเรียกใช้ [self.tableView reloadRowsAtIndexPaths: @ [indexPathOfTargetRow] withRowAnimation: UITableViewRowAnimationNone]; นอกจากนี้โปรดสังเกตว่าภาพเคลื่อนไหวของแถวถูก "ปิดใช้งาน" ที่นี่
คริส

34

วิธีแก้ปัญหาของฉันไปในทิศทางเดียวกันกับ Gareth แม้ว่าฉันจะทำบางอย่างที่แตกต่าง

ที่นี่:

1. ซ่อนเซลล์

ไม่มีทางที่จะซ่อนเซลล์โดยตรง UITableViewControllerเป็นแหล่งข้อมูลที่ให้เซลล์คงที่และปัจจุบันไม่มีวิธีใดที่จะบอกได้ว่า "ไม่ต้องระบุเซลล์ x" ดังนั้นเราจึงต้องจัดหาแหล่งข้อมูลของเราเองซึ่งมอบหมายให้UITableViewControllerเพื่อรับเซลล์คงที่

ง่ายที่สุดคือการ subclass UITableViewControllerและแทนที่วิธีการทั้งหมดที่จำเป็นต้องมีการทำงานแตกต่างกันเมื่อเซลล์หลบซ่อนตัวอยู่

ในกรณีที่ง่ายที่สุด (ตารางส่วนเดียวเซลล์ทั้งหมดมีความสูงเท่ากัน) สิ่งนี้จะเป็นดังนี้:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section    
{
    return [super tableView:tableView numberOfRowsInSection:section] - numberOfCellsHidden;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Recalculate indexPath based on hidden cells
    indexPath = [self offsetIndexPath:indexPath];

    return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}

- (NSIndexPath*)offsetIndexPath:(NSIndexPath*)indexPath
{
    int offsetSection = indexPath.section; // Also offset section if you intend to hide whole sections
    int numberOfCellsHiddenAbove = ... // Calculate how many cells are hidden above the given indexPath.row
    int offsetRow = indexPath.row + numberOfCellsHiddenAbove;

    return [NSIndexPath indexPathForRow:offsetRow inSection:offsetSection];
}

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

นอกจากนี้โปรดทราบว่าพารามิเตอร์ indexPath สำหรับวิธีการเช่นdidSelectRowAtIndexPath:จะแตกต่างกันสำหรับเซลล์เดียวกันขึ้นอยู่กับสถานะ (เช่นจำนวนเซลล์ที่ซ่อนอยู่) ดังนั้นจึงเป็นความคิดที่ดีที่จะหักล้างพารามิเตอร์ indexPath และทำงานกับค่าเหล่านี้เสมอ

2. ทำให้เกิดการเปลี่ยนแปลง

ตามที่ Gareth ได้กล่าวไว้แล้วคุณจะได้รับความผิดพลาดที่สำคัญหากคุณเคลื่อนไหวการเปลี่ยนแปลงโดยใช้reloadSections:withRowAnimation:วิธีการ

ฉันพบว่าถ้าคุณโทรหาreloadData:ทันทีหลังจากนั้นภาพเคลื่อนไหวจะดีขึ้นมาก (เหลือเพียงจุดบกพร่องเล็กน้อย) ตารางจะแสดงอย่างถูกต้องหลังภาพเคลื่อนไหว

สิ่งที่ฉันกำลังทำคือ:

- (void)changeState
{
     // Change state so cells are hidden/unhidden
     ...

    // Reload all sections
    NSIndexSet* reloadSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self numberOfSectionsInTableView:tableView])];

    [tableView reloadSections:reloadSet withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView reloadData];
}

2
อวยพรคุณคนหวาน
guptron

คุณพบวิธีแก้ปัญหาสำหรับภาพเคลื่อนไหวที่บกพร่องเล็กน้อยหรือไม่? สำหรับฉันเส้นคั่นระหว่างเซลล์จะไม่เคลื่อนไหวอย่างถูกต้องและ id แทนที่จะใช้ไม่มีภาพเคลื่อนไหวมากกว่าเส้น gliched ทางออกที่ดีแม้ว่า!
Maximilian Körner

ปัญหาของฉันคือเซลล์แบบคงที่numberOfRowsInSection:จะถูกเรียกเมื่อตารางโหลดครั้งแรกเท่านั้น เมื่อฉันเรียก [self.tableView reloadData] numberOfRowsInSection:จะไม่ถูกเรียกอีกเลย เฉพาะcellForRowAtIndexPath:ที่เรียกว่า ฉันขาดอะไรไป?
โรมัน

13
  1. ในตัวออกแบบสร้างเต้าเสียบสำหรับเซลล์ที่คุณต้องการซ่อน ตัวอย่างเช่นคุณต้องการซ่อน 'cellOne' ดังนั้นใน viewDidLoad () ให้ทำเช่นนี้

cellOneOutlet.hidden = true

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

override func tableView(tableView: UITableView, heightForRowAtIndexPathindexPath: NSIndexPath) -> CGFloat 
{

let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)

        if tableViewCell.hidden == true
        {
            return 0
        }
        else{
             return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
        }

}

ทางออกที่ดีที่สุด!
derdida

เพิ่ม tableView.reloadData () หลังจากทำการเปลี่ยนแปลงและสมบูรณ์แบบ ช่วยฉันได้มากในการเปลี่ยนวิธีแก้ปัญหา! ขอบคุณ
Shayan C

1
สวิฟท์ 4 let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)ไม่ให้ฉันใช้ let tableViewCell = tableView.cellForRow(at: indexPath as IndexPath)ฉันคิดว่ามันจะถูกแทนที่ด้วย
Clifton Labrum

เนื่องจากฉันใช้เซลล์แบบคงที่ใน a UITableViewControllerฉันจึงไม่มีUITableViewวิธีการมอบสิทธิ์ใด ๆ เพื่อให้โทรheightForRowได้ต้องมีวิธีอื่นด้วยหรือไม่?
Clifton Labrum

@CliftonLabrum ไม่คุณสามารถแทนที่วิธีนี้เท่านั้น
Alexander Ershov

11

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

ก่อนอื่นฉันประกาศคุณสมบัติ NSMutableArray

@property (nonatomic, strong) NSMutableArray *hiddenSections;

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

- (void)viewDidLoad
{
    hiddenSections = [NSMutableArray new];

    if(some piece of data is empty){
        // Add index of section that should be hidden
        [self.hiddenSections addObject:[NSNumber numberWithInt:1]];
    }

    ... add as many sections to the array as needed

    [self.tableView reloadData];
}

จากนั้นใช้วิธีการมอบหมาย TableView ต่อไปนี้

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
        return nil;
    }

    return [super tableView:tableView titleForHeaderInSection:section];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
        return 0;
    }

    return [super tableView:tableView heightForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
        [cell setHidden:YES];
    }
}

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

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{
    CGFloat height = [super tableView:tableView heightForHeaderInSection:section];

    if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
        height = 1; // Can't be zero
    }
    else if([self tableView:tableView titleForHeaderInSection:section] == nil){ // Only adjust if title is nil
        // Adjust height for previous hidden sections
        CGFloat adjust = 0;

        for(int i = (section - 1); i >= 0; i--){
            if([self.hiddenSections containsObject:[NSNumber numberWithInt:i]]){
                adjust = adjust + 2;
            }
            else {
                break;
            }
        }

        if(adjust > 0)
        {                
            if(height == -1){
                height = self.tableView.sectionHeaderHeight;
            }

            height = height - adjust;

            if(height < 1){
                height = 1;
            }
        }
    }

    return height;
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{   
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
        return 1;
    }
    return [super tableView:tableView heightForFooterInSection:section];
}

จากนั้นหากคุณมีแถวที่ต้องการซ่อนคุณสามารถปรับ numberOfRowsInSection และแถวใดที่จะส่งคืนใน cellForRowAtIndexPath ในตัวอย่างนี้ที่นี่ฉันมีส่วนที่มีสามแถวซึ่งสามแถวใด ๆ อาจว่างเปล่าและจำเป็นต้องลบออก

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger rows = [super tableView:tableView numberOfRowsInSection:section];

    if(self.organization != nil){
        if(section == 5){ // Contact
            if([self.organization objectForKey:@"Phone"] == [NSNull null]){     
                rows--;
            }

            if([self.organization objectForKey:@"Email"] == [NSNull null]){     
                rows--;
            }

            if([self.organization objectForKey:@"City"] == [NSNull null]){     
                rows--;
            }
        }
    }

    return rows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    return [super tableView:tableView cellForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}

ใช้ offsetIndexPath นี้เพื่อคำนวณ indexPath สำหรับแถวที่คุณกำลังลบแถวตามเงื่อนไข ไม่จำเป็นหากคุณซ่อนเฉพาะส่วน

- (NSIndexPath *)offsetIndexPath:(NSIndexPath*)indexPath
{
    int row = indexPath.row;

    if(self.organization != nil){
        if(indexPath.section == 5){
            // Adjust row to return based on which rows before are hidden
            if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){     
                row++;
            }
            else if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Address"] != [NSNull null]){     
                row = row + 2;
            }
            else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] != [NSNull null] && [self.organization objectForKey:@"Email"] == [NSNull null]){     
                row++;
            }
            else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){     
                row++;
            }
        }
    }

    NSIndexPath *offsetPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];

    return offsetPath;
}

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


1
ฉันอาจจะใช้NSMutableSetสำหรับhiddenSectionsแทน เร็วกว่ามากเนื่องจากคุณทดสอบการเป็นสมาชิกเป็นส่วนใหญ่
pixelfreak

คำตอบที่ดีออสติน ฉันโหวตคำตอบนั้นและจะใช้เป็นข้อมูลอ้างอิงสำหรับโครงการของฉันในอนาคต pixelfreak ยังเป็นจุดที่ดีเกี่ยวกับการใช้NSMutableSetสำหรับhiddenSectionsแม้ว่าฉันจะเข้าใจว่าประเด็นของคำตอบของคุณเป็นแนวคิดมากกว่าที่จู้จี้จุกจิกว่าคุณควรใช้โครงสร้างข้อมูลประเภทใด
BigSauce

11

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

โครงการสาธิต

วิดีโอสาธิตโครงการ

สาระสำคัญ:

  1. Use tableView:heightForRowAtIndexPath: เพื่อระบุความสูงของเซลล์แบบไดนามิกตามสถานะบางอย่าง
  2. เมื่อสถานะเปลี่ยนเซลล์เคลื่อนไหวแสดง / ซ่อนโดยการโทร tableView.beginUpdates();tableView.endUpdates()
  3. อย่าเรียกภายในtableView.cellForRowAtIndexPath: tableView:heightForRowAtIndexPath:ใช้ cached indexPaths เพื่อแยกความแตกต่างของเซลล์
  4. อย่าซ่อนเซลล์ ตั้งค่าคุณสมบัติ "Clip Subviews" ใน Xcode แทน
  5. ใช้เซลล์แบบกำหนดเอง (ไม่ใช่ธรรมดาเป็นต้น) เพื่อให้ได้ภาพเคลื่อนไหวที่ซ่อนอยู่ที่ดี นอกจากนี้ให้จัดการเค้าโครงอัตโนมัติอย่างถูกต้องสำหรับกรณีที่ความสูงของเซลล์ == 0

ข้อมูลเพิ่มเติมในบล็อกของฉัน (ภาษารัสเซีย)


1
จุดนี้สำคัญสำหรับฉัน: "อย่าซ่อนเซลล์ตั้งค่าคุณสมบัติ" Clip Subviews "ใน Xcode แทน"
balkoth

8

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

ฉันซ่อนแถวตามสถานะของสวิตช์เปิด / ปิดในแถวแรกของส่วนแรก หากสวิตช์เปิดอยู่จะมี 1 แถวด้านล่างในส่วนเดียวกันมิฉะนั้นจะมี 2 แถวที่ต่างกัน

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

[[self tableView] reloadData];

ฉันแทนที่tableView: willDisplayCell: forRowAtIndexPath: function และถ้าเซลล์ควรจะถูกซ่อนฉันจะทำสิ่งนี้:

[cell setHidden:YES];

ซึ่งจะซ่อนเซลล์และเนื้อหา แต่ไม่ได้ลบเนื้อที่ที่มีอยู่ออกไป

หากต้องการลบช่องว่างให้แทนที่ฟังก์ชันtableView: heightForRowAtIndexPath:และส่งคืน 0 สำหรับแถวที่ควรซ่อน

นอกจากนี้คุณยังต้องแทนที่tableView: numberOfRowsInSection:และส่งคืนจำนวนแถวในส่วนนั้น คุณต้องทำอะไรแปลก ๆ ที่นี่เพื่อที่ว่าถ้าตารางของคุณเป็นสไตล์ที่จัดกลุ่มมุมโค้งมนจะเกิดขึ้นในเซลล์ที่ถูกต้อง ในตารางคงที่ของฉันมีชุดเซลล์เต็มสำหรับส่วนดังนั้นจึงมีเซลล์แรกที่มีตัวเลือกจากนั้น 1 เซลล์สำหรับตัวเลือกสถานะเปิดและอีก 2 เซลล์สำหรับตัวเลือกสถานะปิดรวมเป็น 4 เซลล์ เมื่อตัวเลือกเปิดอยู่ฉันต้องส่งคืน 4 ซึ่งรวมถึงตัวเลือกที่ซ่อนอยู่เพื่อให้ตัวเลือกสุดท้ายที่แสดงมีกล่องกลม เมื่อปิดตัวเลือกสองตัวเลือกสุดท้ายจะไม่ปรากฏขึ้นดังนั้นฉันจึงกลับ 2 ทั้งหมดนี้รู้สึกอึดอัด ขออภัยหากสิ่งนี้ไม่ชัดเจนมากนักอธิบายยาก เพื่อแสดงการตั้งค่านี่คือโครงสร้างของส่วนตารางใน IB:

  • แถว 0: ตัวเลือกพร้อมสวิตช์เปิด / ปิด
  • แถวที่ 1: แสดงเมื่อตัวเลือกเปิดอยู่
  • แถวที่ 2: แสดงเมื่อตัวเลือกปิดอยู่
  • แถวที่ 3: แสดงเมื่อตัวเลือกปิดอยู่

ดังนั้นเมื่อตัวเลือกอยู่บนตารางรายงานสองแถวซึ่ง ได้แก่ :

  • แถว 0: ตัวเลือกพร้อมสวิตช์เปิด / ปิด
  • แถวที่ 1: แสดงเมื่อตัวเลือกเปิดอยู่

เมื่อตัวเลือกปิดอยู่ตารางจะรายงานสี่แถว ได้แก่ :

  • แถว 0: ตัวเลือกพร้อมสวิตช์เปิด / ปิด
  • แถวที่ 1: แสดงเมื่อตัวเลือกเปิดอยู่
  • แถวที่ 2: แสดงเมื่อตัวเลือกปิดอยู่
  • แถวที่ 3: แสดงเมื่อตัวเลือกปิดอยู่

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

  • รู้สึกผิดที่ต้องบอกตารางว่าจำนวนแถวแตกต่างจากที่สันนิษฐานไว้ในข้อมูลพื้นฐาน

  • ฉันไม่สามารถทำให้การเปลี่ยนแปลงเคลื่อนไหวได้ ฉันได้ลองใช้tableView: reloadSections: withRowAnimation:แทนที่จะเป็น reloadData และผลลัพธ์ดูเหมือนจะไม่สมเหตุสมผลฉันยังคงพยายามทำให้มันใช้งานได้ ขณะนี้สิ่งที่ดูเหมือนจะเกิดขึ้นคือ tableView ไม่อัปเดตแถวที่ถูกต้องดังนั้นจึงยังคงซ่อนอยู่ซึ่งควรจะแสดงและช่องว่างจะถูกทิ้งไว้ใต้แถวแรก ฉันคิดว่านี่อาจเกี่ยวข้องกับประเด็นแรกเกี่ยวกับข้อมูลพื้นฐาน

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


ฉันค่อนข้างแน่ใจว่าคุณควรโทรหา[[self tableView] reloadData];อีกครั้งหลังจากซ่อนเซลล์
Shmidt

ขออภัยที่ต้องรื้อฟื้นสิ่งนี้ แต่คุณสามารถซับคลาส UITableViewController และใช้กับเซลล์แบบคงที่ได้อย่างไร Xcode ไม่ยอมให้ฉัน
Dany Joumaa

Nessup คุณไม่จำเป็นต้อง subclass UITableView ในกระดานเรื่องราวให้เลือก TableViewController ของคุณจากนั้นคลิกที่ TableView ตอนนี้คุณสามารถเลือกระหว่างเซลล์แบบไดนามิก / คงที่
Shmidt

1
ฉันพบวิธีแก้ปัญหาในการทำให้เซลล์คงที่เคลื่อนไหวซ่อน / แสดง เพียงแค่เรียกreturn [super tableView:tableView cellForRowAtIndexPath:indexPath];ในUITableViewControllerคลาสย่อยสำหรับการสร้างเซลล์แบบคงที่ เส้นทางดัชนีมีการจัดทำดัชนีแบบคงที่ไม่ใช่แบบไดนามิก ...
k06a

8

ตามคำตอบของ Justas แต่สำหรับ Swift 4:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let cell = super.tableView(tableView, cellForRowAt: indexPath)

    if cell == self.cellYouWantToHide {
        return 0
    }

    return super.tableView(tableView, heightForRowAt: indexPath)
}

1
คุณอาจต้องtableView.reloadRows(at:, with:)อัปเดตเซลล์หากคุณเปลี่ยนความสูงในขณะที่แถวนั้นมองเห็นได้แล้ว
Frost-Lee

7

เอาล่ะหลังจากพยายามฉันมีคำตอบที่ไม่ธรรมดา ฉันกำลังใช้ตัวแปร "isHidden" หรือ "hidden" เพื่อตรวจสอบว่าควรซ่อนเซลล์นี้หรือไม่

  1. สร้าง IBOutlet ไปยังตัวควบคุมมุมมองของคุณ @IBOutlet weak var myCell: UITableViewCell!

  2. อัปเดตmyCellในฟังก์ชันที่กำหนดเองของคุณตัวอย่างเช่นคุณสามารถเพิ่มใน viewDidLoad:

override func viewDidLoad() { super.viewDidLoad() self.myCell.isHidden = true }

  1. ในวิธีการมอบหมายของคุณ:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let cell = super.tableView(tableView, cellForRowAt: indexPath) guard !cell.isHidden else { return 0 } return super.tableView(tableView, heightForRowAt: indexPath) }

วิธีนี้จะลดตรรกะของคุณในวิธีการมอบหมายงานและคุณจะต้องมุ่งเน้นไปที่ความต้องการทางธุรกิจของคุณเท่านั้น


4

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

สำหรับตารางคงที่ธรรมดาสิ่งที่ได้ผลดีที่สุดสำหรับฉันคือ:

  1. สร้างเต้าเสียบสำหรับทุกเซลล์ในตารางแบบคงที่
  2. สร้างอาร์เรย์ที่มีช่องของเซลล์ที่จะแสดงเท่านั้น
  3. แทนที่ cellForRowAtIndexPath เพื่อส่งคืนเซลล์จากอาร์เรย์
  4. แทนที่ numberOfRowsInSection เพื่อส่งคืนจำนวนอาร์เรย์
  5. ใช้เมธอดเพื่อกำหนดว่าเซลล์ใดต้องอยู่ในอาร์เรย์นั้นและเรียกใช้เมธอดนั้นทุกครั้งที่ต้องการจากนั้นโหลดข้อมูลซ้ำ

นี่คือตัวอย่างจากตัวควบคุมมุมมองตารางของฉัน:

@IBOutlet weak var titleCell: UITableViewCell!
@IBOutlet weak var nagCell: UITableViewCell!
@IBOutlet weak var categoryCell: UITableViewCell!

var cellsToShow: [UITableViewCell] = []

override func viewDidLoad() {
    super.viewDidLoad()
    determinCellsToShow()
}

func determinCellsToShow() {
    if detail!.duration.type != nil {
        cellsToShow = [titleCell, nagCell, categoryCell]
    }
    else {
        cellsToShow = [titleCell,  categoryCell]
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return cellsToShow[indexPath.row]
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return cellsToShow.count
}

สิ่งนี้ได้ผลดีแม้ 5 ปีต่อมา! ขอบคุณมาก.
Schrockwell

2020 และนี่คือทางออกที่ดีที่สุดสำหรับสิ่งนี้ ไม่จำเป็นต้องแฮ็ค
mdonati

4

วิธีการใช้งานร่วมกับ iOS 11 และ IB / Storyboard แบบง่าย

สำหรับ iOS 11 ฉันพบว่าคำตอบของMohamed Salehเวอร์ชันแก้ไขทำงานได้ดีที่สุดโดยมีการปรับปรุงบางอย่างตามเอกสารของ Apple มันเคลื่อนไหวอย่างหลีกเลี่ยง hacks น่าเกลียดหรือค่า hardcoded และใช้ความสูงของแถวตั้งอยู่แล้วใน Interface Builder

แนวคิดพื้นฐานคือการตั้งค่าความสูงของแถวเป็น 0 สำหรับแถวที่ซ่อนอยู่ จากนั้นใช้tableView.performBatchUpdatesเพื่อทริกเกอร์ภาพเคลื่อนไหวที่ทำงานอย่างสม่ำเสมอ

ตั้งค่าความสูงของเซลล์

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath == indexPathOfHiddenCell {
        if cellIsHidden {
            return 0
        }
    }
    // Calling super will use the height set in your storyboard, avoiding hardcoded values
    return super.tableView(tableView, heightForRowAt: indexPath)
}

คุณจะต้องตรวจสอบให้แน่ใจcellIsHiddenและindexPathOfHiddenCellตั้งค่าให้เหมาะสมกับกรณีการใช้งานของคุณ สำหรับรหัสของฉันเป็นคุณสมบัติบนตัวควบคุมมุมมองตารางของฉัน

กำลังสลับเซลล์

ไม่ว่าด้วยวิธีใดก็ตามที่ควบคุมการมองเห็น (อาจเป็นการทำงานของปุ่มหรือdidSelectRow) ให้สลับเซลล์ IsHidden state ภายในperformBatchUpdatesบล็อก:

tableView.performBatchUpdates({
                // Use self to capture for block
                self.cellIsHidden = !self.cellIsHidden 
            }, completion: nil)

Apple แนะนำให้ทำperformBatchUpdatesซ้ำbeginUpdates/endUpdatesทุกครั้งที่ทำได้


1

ฉันพบวิธีแก้ปัญหาสำหรับการซ่อนเซลล์แบบเคลื่อนไหวในตารางแบบคงที่

// Class for wrapping Objective-C block
typedef BOOL (^HidableCellVisibilityFunctor)();
@interface BlockExecutor : NSObject
@property (strong,nonatomic) HidableCellVisibilityFunctor block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block;
@end
@implementation BlockExecutor
@synthesize block = _block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block
{
    BlockExecutor * executor = [[BlockExecutor alloc] init];
    executor.block = block;
    return executor;
}
@end

จำเป็นต้องมีพจนานุกรมเพิ่มเติมเพียงชุดเดียว:

@interface MyTableViewController ()
@property (nonatomic) NSMutableDictionary * hidableCellsDict;
@property (weak, nonatomic) IBOutlet UISwitch * birthdaySwitch;
@end

และดูการใช้งาน MyTableViewController เราต้องการสองวิธีในการแปลง indexPath ระหว่างดัชนีที่มองเห็นและมองไม่เห็น ...

- (NSIndexPath*)recoverIndexPath:(NSIndexPath *)indexPath
{
    int rowDelta = 0;
    for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
    {
        BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
        if (ip.section == indexPath.section
            && ip.row <= indexPath.row + rowDelta
            && !executor.block())
        {
            rowDelta++;
        }
    }
    return [NSIndexPath indexPathForRow:indexPath.row+rowDelta inSection:indexPath.section];
}

- (NSIndexPath*)mapToNewIndexPath:(NSIndexPath *)indexPath
{
    int rowDelta = 0;
    for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
    {
        BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
        if (ip.section == indexPath.section
            && ip.row < indexPath.row - rowDelta
            && !executor.block())
        {
            rowDelta++;
        }
    }
    return [NSIndexPath indexPathForRow:indexPath.row-rowDelta inSection:indexPath.section];
}

IBAction หนึ่งรายการในค่า UISwitch เปลี่ยน:

- (IBAction)birthdaySwitchChanged:(id)sender
{
    NSIndexPath * indexPath = [self mapToNewIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]];
    if (self.birthdaySwitch.on)
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    else
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

บางวิธี UITableViewDataSource และ UITableViewDelegate:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int numberOfRows = [super tableView:tableView numberOfRowsInSection:section];
    for (NSIndexPath * indexPath in [self.hidableCellsDict allKeys])
        if (indexPath.section == section)
        {
            BlockExecutor * executor = [self.hidableCellsDict objectForKey:indexPath];
            numberOfRows -= (executor.block()?0:1);
        }
    return numberOfRows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    indexPath = [self recoverIndexPath:indexPath];
    return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    indexPath = [self recoverIndexPath:indexPath];
    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // initializing dictionary
    self.hidableCellsDict = [NSMutableDictionary dictionary];
    [self.hidableCellsDict setObject:[BlockExecutor executorWithBlock:^(){return self.birthdaySwitch.on;}] forKey:[NSIndexPath indexPathForRow:1 inSection:1]];
}

- (void)viewDidUnload
{
    [self setBirthdaySwitch:nil];
    [super viewDidUnload];
}

@end

1

ตอบอย่างรวดเร็ว :

เพิ่มวิธีการต่อไปนี้ใน TableViewController ของคุณ:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return indexPathOfCellYouWantToHide == indexPath ? 0 : super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

หาก tableView พยายามวาดเซลล์ที่คุณต้องการซ่อนก็จะไม่แสดงผลเนื่องจากความสูงจะถูกตั้งค่าเป็น 0pt ด้วยวิธีการด้านบนทุกอย่างจะไม่เปลี่ยนแปลง

โปรดทราบว่า indexPathOfCellYouWantToHideสามารถเปลี่ยนแปลงได้ตลอดเวลา :)


1

ใน> Swift 2.2 ฉันได้รวมคำตอบไว้สองสามคำไว้ที่นี่

สร้างทางออกจากสตอรีบอร์ดเพื่อเชื่อมโยงไปยัง staticCell ของคุณ

@IBOutlet weak var updateStaticCell: UITableViewCell!

override func viewDidLoad() {
    ...
    updateStaticCell.hidden = true
}

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if indexPath.row == 0 {
        return 0
    } else {
        return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
    }
}

ฉันต้องการซ่อนเซลล์แรกของฉันดังนั้นฉันจึงตั้งค่าความสูงเป็น 0 ตามที่อธิบายไว้ข้างต้น


1

Swift 4:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    var height = super.tableView(tableView, heightForRowAt: indexPath)
    if (indexPath.row == HIDDENROW) {
        height = 0.0
    }
    return height
}

0

สำหรับสถานการณ์ที่ง่ายที่สุดเมื่อคุณซ่อนเซลล์ที่ด้านล่างสุดของมุมมองตารางคุณสามารถปรับ contentInset ของ tableView หลังจากที่คุณซ่อนเซลล์:

- (void)adjustBottomInsetForHiddenSections:(NSInteger)numberOfHiddenSections
{
    CGFloat bottomInset = numberOfHiddenSections * 44.0; // or any other 'magic number
    self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, -bottomInset, self.tableView.contentInset.right);
}


0

โซลูชันจาก k06a ( https://github.com/k06a/ABStaticTableViewController ) ดีกว่าเพราะซ่อนทั้งส่วนรวมถึงส่วนหัวและส่วนท้ายของเซลล์โดยที่โซลูชันนี้ ( https://github.com/peterpaulis/StaticDataTableViewController ) จะซ่อนทุกอย่างยกเว้นส่วนท้าย

แก้ไข

StaticDataTableViewControllerฉันเพิ่งพบวิธีการแก้ปัญหาถ้าคุณต้องการที่จะซ่อนอยู่ในส่วนท้าย นี่คือสิ่งที่คุณต้องคัดลอกในไฟล์ StaticTableViewController.m:

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    } else {
        return [super tableView:tableView titleForFooterInSection:section];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {

    CGFloat height = [super tableView:tableView heightForFooterInSection:section];

    if (self.originalTable == nil) {
        return height;
    }

    if (!self.hideSectionsWithHiddenRows) {
        return height;
    }

    OriginalSection * os = self.originalTable.sections[section];
    if ([os numberOfVissibleRows] == 0) {
       //return 0;
        return CGFLOAT_MIN;
    } else {
        return height;
    }

    //return 0;
    return CGFLOAT_MIN;
}

0

คุณทำได้แน่นอน ขั้นแรกให้กลับไปที่ tableView ของคุณจำนวนเซลล์ที่คุณต้องการแสดงจากนั้นเรียกใช้superเพื่อให้ได้เซลล์ที่ต้องการจากกระดานเรื่องราวของคุณและส่งคืนสำหรับ tableView:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.mode.numberOfCells()
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = super.tableView(tableView, cellForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))

    return cell
}

หากเซลล์ของคุณมีความแตกต่างกันให้ส่งคืนด้วย:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return super.tableView(tableView, heightForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
}

0

นอกจากโซลูชัน @Saleh Masum แล้ว:

หากคุณได้รับข้อผิดพลาดในการจัดวางอัตโนมัติคุณสามารถลบข้อ จำกัด ออกจากไฟล์tableViewCell.contentView

Swift 3:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let tableViewCell = super.tableView(tableView, cellForRowAt: indexPath)

    if tableViewCell.isHidden == true
    {
        tableViewCell.contentView.removeConstraints(tableViewCell.contentView.constraints)
        return 0
    }
    else{
        return super.tableView(tableView, heightForRowAt: indexPath)
    }

}

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


0

ฉันมีวิธีที่ดีกว่าในการซ่อนเซลล์แบบคงที่และแม้แต่ส่วนต่างๆแบบไดนามิกโดยไม่ต้องแฮ็ก

การตั้งค่าความสูงของแถวเป็น 0 สามารถซ่อนแถวได้ แต่จะไม่ได้ผลหากคุณต้องการซ่อนทั้งส่วนซึ่งจะมีช่องว่างบางส่วนแม้ว่าคุณจะซ่อนแถวทั้งหมดก็ตาม

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

นี่คือโค้ดตัวอย่างบางส่วน:

var tableSections = [[UITableViewCell]]()

private func configTableSections() {
    // seciton A
    tableSections.append([self.cell1InSectionA, self.cell2InSectionA])

    // section B
    if shouldShowSectionB {
        tableSections.append([self.cell1InSectionB, self.cell2InSectionB])
    }

    // section C
    if shouldShowCell1InSectionC {
        tableSections.append([self.cell1InSectionC, self.cell2InSectionC, self.cell3InSectionC])
    } else {
        tableSections.append([self.cell2InSectionC, self.cell3InSectionC])
    }
}

func numberOfSections(in tableView: UITableView) -> Int {
    return tableSections.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tableSections[section].count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    return tableSections[indexPath.section][indexPath.row]
}

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

รหัสนี้ยังดูแลรักษาง่ายมาก ตัวอย่างเช่นหากคุณต้องการเพิ่ม / ลบเซลล์หรือส่วนเพิ่มเติม

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

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