เป็นไปได้หรือไม่ที่จะปิดการใช้งานส่วนหัวลอยใน UITableView ด้วย UITableViewStylePlain


177

ฉันใช้UITableView'หน้า' เพื่อจัดวางเนื้อหา ฉันใช้ส่วนหัวในมุมมองของตารางเพื่อรูปแบบบางภาพ ฯลฯ และฉันต้องการมันหากพวกเขาไม่ได้ลอยอยู่ UITableViewStyleGroupedแต่คงเป็นพวกเขาจะทำอย่างไรเมื่อรูปแบบที่ถูกกำหนดเป็น

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

ขอบคุณมาก,



59
ใช้สไตล์ตารางUITableViewStyleGrouped - นี่คือคำตอบสำหรับทุกคนที่กำลังมองหาการปิดการใช้งานส่วนหัวลอยและไม่ได้อ่านคำถามทั้งหมด (มันเกิดขึ้นกับฉัน ... )
ค่าเฉลี่ย Joe

@Kasztan นี่เป็นวิธีแก้ปัญหาเส้นศูนย์ที่ทำงานได้ดี! ขอบคุณ
Lee Fastenau

คำตอบ:


27

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

คุณเพียงแค่ต้องเพิ่มตรรกะในของคุณ cellForRowAtIndexPathเพื่อส่งกลับประเภทเซลล์ที่ถูกต้องเมื่อมันเป็นแถวส่วนหัว

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


11
ใช่ ... ดูเหมือนว่าจะเป็นแฮ็ค ดูเหมือนว่าการกำกับดูแลส่วนของ Apple เนื่องจากเห็นได้ชัดว่ามีรหัสที่จะทำเราเพียงแค่ต้องสามารถตั้งค่าสถานะ
Tricky

2
ตรวจสอบคำตอบของฉันด้านล่างเพื่อหาวิธีที่ถูกต้องในการสร้างเอฟเฟกต์โดยไม่ต้องแฮ็คพิเศษเพียงแค่จัดการเซลล์แรกของทุกส่วนให้เป็นส่วนหัวของส่วน!
Sumit Anantwar

338

วิธีที่ง่ายกว่าในการบรรลุเป้าหมายนี้:

Objective-C:

CGFloat dummyViewHeight = 40;
UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, dummyViewHeight)];
self.tableView.tableHeaderView = dummyView;
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0);

สวิฟท์:

let dummyViewHeight = CGFloat(40)
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight))
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0)

ส่วนหัวของส่วนนี้จะเลื่อนเหมือนเซลล์ทั่วไป


5
Friggin นี้ใช้งานได้อย่างมีเสน่ห์ !! การปรากฏตัวของส่วนหัวของมุมมองตารางหยุดส่วนหัวจากลอย และส่วนหัวที่มองไม่เห็นที่มีส่วนเสริมเนื้อหาที่เหมาะสมสำหรับตารางนั้นเป็นเคล็ดลับ .. ขอบคุณมาก! สงสัยว่าทำไมคำตอบนี้ไม่ได้รับความสนใจมากนัก
Shyam Bhat

4
ยังไม่เชื่อ! ไม่มี API ส่วนตัวไม่ต้องเจาะเข้าไปในชั้นเรียนไม่มีอะไร! ฉันประสบปัญหานี้มานานแล้วและได้เพิ่มการดูตารางบนมุมมองเลื่อน (โดยที่ปิดใช้งานการเลื่อนดูตาราง) ซึ่งจะทำให้ส่วนหัวของตารางเลื่อนตามปกติ แต่เพิ่งเริ่มค้นหาว่าแอปเปิ้ลได้ให้วิธีการใหม่เมื่อเร็ว ๆ นี้เพื่อแก้ไขปัญหานี้หรือไม่ .. ดีใจที่ฉันสะดุดกับคำตอบของคุณ ขอบคุณอีกครั้ง
Shyam Bhat

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

5
คุณยังสามารถแสดง tableHeaderView ของตารางได้โดยการเพิ่มความสูงของมันไว้ที่ด้านบนโดยตัวเลขเท่ากับความสูงของส่วนหัวของส่วนและลดส่วนแทรกเนื้อหาด้วยหมายเลขเดียวกัน
Shyam Bhat

2
ฉันหวังว่าฉันจะสามารถโหวตได้อีกครั้งฉันค่อนข้างแน่ใจว่านี่เป็นอย่างน้อยครั้งที่สามที่ฉันได้ลงเอยด้วยคำถามนี้และสิ่งนี้ได้แก้ไขปัญหาของฉันแล้ว
Ell Neal

252

(สำหรับผู้ที่เคยมาที่นี่เนื่องจากรูปแบบตารางที่ไม่ถูกต้อง) เปลี่ยนรูปแบบตารางจากธรรมดาเป็นจัดกลุ่มผ่านทางผู้ตรวจสอบคุณสมบัติหรือผ่านรหัส:

let tableView = UITableView(frame: .zero, style: .grouped)

3
นี่คือสิ่งที่ฉันกำลังมองหา ขอบคุณ!
ninjudd

4
"อื่น ๆ จากนั้นใช้ UITableViewStyleGrouped มีวิธีทำเช่นนี้หรือไม่"
Michael Peterson

27
สิ่งที่ดีที่ผมได้เรียนรู้ที่จะตรวจสอบคำตอบทั้งหมดก่อนที่จะดำเนินการอย่างใดอย่างหนึ่ง upvoted ที่สุด :)
ตุง Fam

1
ตอนนี้พวกนี้คือคำตอบที่คุณกำลังมองหา โปรดทราบว่าคุณสามารถค้นหาTableView Styleคุณสมบัติได้ใน AttributesInspector เช่นกัน
Cristian Holdunu

4
คำถามเฉพาะกล่าวถึงการมองหาวิธี "อื่น ๆ แล้วใช้ UITableViewStyleGrouped"
Ferdz

73

คำเตือน : โซลูชันนี้ใช้วิธีการ API ที่สงวนไว้ สิ่งนี้สามารถป้องกันไม่ให้แอปได้รับการอนุมัติจาก Apple เพื่อจำหน่ายใน AppStore

ฉันได้อธิบายวิธีการส่วนตัวที่เปลี่ยนส่วนหัวที่ลอยอยู่ในบล็อกของฉัน

โดยทั่วไปคุณเพียงแค่ต้อง subclass UITableViewและกลับมาNOในสองวิธี:

- (BOOL)allowsHeaderViewsToFloat;
- (BOOL)allowsFooterViewsToFloat;

40
คำตอบไม่สมควรได้รับ downvote เพียงเพราะมันอ้างถึง API ส่วนตัว (ไม่ใช่ทุกคนที่เขียนโค้ดเพื่อส่งไปยัง AppStore) นี่เป็นความจริงทวีคูณเมื่อคำตอบนั้นถูกต้อง การแบ่งคลาสย่อย (หรือง่ายขึ้นทำให้หมวดหมู่ UITableView) ที่ส่งคืนค่า NO สำหรับวิธีการเหล่านี้จะหยุดไม่ให้ส่วนหัวลอย หากคุณต้องการที่จะเห็นสิ่งนี้เพิ่มเป็น API สาธารณะโปรดยื่นรายงานข้อผิดพลาด: bugreport.apple.com
jemmons

5
หากเราใช้ฟังก์ชั่นนั้นในแอพ Apple จะรู้ได้อย่างไรว่าคุณใช้ API ส่วนตัว จากทั้งหมดที่พวกเขารู้ฉันเพิ่งใช้วิธีใน subclass ของ UITableView และพวกเขาไม่สามารถแม้แต่จะเห็นว่าไม่มี de-assembling รหัสและมันจะไม่ง่าย มันไม่ได้เรียกวิธีการใน API ส่วนตัวมันเป็นเพียงแค่การดำเนินการอย่างใดอย่างหนึ่ง ....
Javier Soto

3
@jemmons หากคุณไม่ต้องการให้ฉันลงคะแนนคำตอบของคุณให้ทำเครื่องหมายว่า "ใช้ API ส่วนตัวที่นี่" ประเภทของการปฏิเสธความรับผิดชอบ :)
kas-kad

2
ลิงก์ "บล็อกของฉัน" ของคุณเสีย
MartinMoizard

12
@jemmons "ไม่ใช่ทุกคนที่เขียนโค้ดเพื่อส่งไปยัง AppStore" Appstore ไม่ใช่ปัญหาจริงๆ ปัญหาคือแอปเปิ้ลสามารถเปลี่ยน API ส่วนตัวโดยไม่ต้องสื่อสารหรือเลิกใช้ซึ่งจะทำลายแอปของคุณ นั่นเป็นเหตุผลที่ดีกว่าว่าทำไมคุณไม่ควรใช้ API ส่วนบุคคลมากกว่าการถูกปฏิเสธโดย Apple
aryaxt

29

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

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

ดังนั้นขั้นตอนคือ

  1. ใช้ UITableView ด้วยสไตล์ UITableViewStylePlain

    -(void) loadView
    {
        [super loadView];
    
        UITableView *tblView =[[UITableView alloc] initWithFrame:CGRectMake(0, frame.origin.y, frame.size.width, frame.size.height-44-61-frame.origin.y) style:UITableViewStylePlain];
        tblView.delegate=self;
        tblView.dataSource=self;
        tblView.tag=2;
        tblView.backgroundColor=[UIColor clearColor];
        tblView.separatorStyle = UITableViewCellSeparatorStyleNone;
    }
  2. ใช้ titleForHeaderInSection ตามปกติ (คุณสามารถรับค่านี้ได้โดยใช้ตรรกะของคุณเอง แต่ฉันต้องการใช้ผู้รับมอบสิทธิ์มาตรฐาน)

    - (NSString *)tableView: (UITableView *)tableView titleForHeaderInSection:(NSInteger)section
    {
        NSString *headerTitle = [sectionArray objectAtIndex:section];
        return headerTitle;
    }
  3. ไม่ใช้ numberOfSectionsInTableView ตามปกติ

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    {
        int sectionCount = [sectionArray count];
        return sectionCount;
    }
  4. ใช้ numberOfRowsInSection ตามปกติ

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    {
        int rowCount = [[cellArray objectAtIndex:section] count];
        return rowCount +1; //+1 for the extra row which we will fake for the Section Header
    }
  5. ส่งคืนความสูง 0.0f สำหรับส่วนหัวส่วนต่อท้าย

    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
    {
        return 0.0f;
    }
  6. ห้ามใช้ viewForHeaderInSection ลบเมธอดทั้งหมดแทนการคืนค่าศูนย์

  7. ใน heightForRowAtIndexPath ตรวจสอบว่า (indexpath.row == 0) และส่งกลับความสูงของเซลล์ที่ต้องการสำหรับส่วนหัวของส่วนอื่น ๆ กลับความสูงของเซลล์

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row == 0)
        {
            return 80; //Height for the section header
        }
        else
        {
            return 70; //Height for the normal cell
        }
    }
  8. ตอนนี้ใน cellForRowAtIndexPath ตรวจสอบว่า (indexpath.row == 0) และใช้เซลล์ตามที่คุณต้องการให้ส่วนหัวของส่วนนั้นเป็นและตั้งค่าสไตล์การเลือกให้เป็น none ELSE ใช้เซลล์ตามที่คุณต้องการให้เซลล์ปกติเป็น

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0)
        {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SectionCell"];
            if (cell == nil)
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SectionCell"] autorelease];
                cell.selectionStyle = UITableViewCellSelectionStyleNone; //So that the section header does not appear selected
    
                cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SectionHeaderBackground"]];
            }
    
            cell.textLabel.text = [tableView.dataSource tableView:tableView titleForHeaderInSection:indexPath.section];
    
            return cell;
        }
        else
        {
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    
            if (cell == nil) 
            {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"] autorelease];
                cell.selectionStyle = UITableViewCellSelectionStyleGray; //So that the normal cell looks selected
    
                cell.backgroundView =[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"CellBackground"]]autorelease];
                cell.selectedBackgroundView=[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SelectedCellBackground"]] autorelease];
            }
    
            cell.textLabel.text = [[cellArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row -1]; //row -1 to compensate for the extra header row
    
            return cell;
        }
    }
  9. ตอนนี้ใช้ willSelectRowAtIndexPath และคืนค่าศูนย์ถ้า indexpath.row == 0 สิ่งนี้จะสนใจว่า didSelectRowAtIndexPath จะไม่ถูกเรียกใช้สำหรับแถวส่วนหัว

    - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row == 0)
        {
            return nil;
        }
    
        return indexPath;
    }
  10. และในที่สุดก็ didSelectRowAtIndexPath ตรวจสอบว่า (indexpath.row! = 0) และดำเนินการต่อ

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.row != 0)
        {
            int row = indexPath.row -1; //Now use 'row' in place of indexPath.row
    
            //Do what ever you want the selection to perform
        }
    }

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


1
ดำเนินการ 'willSelectRowAtIndexPath' เพื่อให้การควบคุมไม่ถึง 'didSelectRowAtIndexPath' ในการเลือกแถวส่วนหัว
Sumit Anantwar

ที่จริงแล้วฉันพับ + คลี่แถวออกเมื่อเลือกส่วนหัว แต่ดีที่รู้ว่าคุณสามารถทำได้
Yariv Nissim

คำตอบที่ดี แต่ทำไม 'if (indexPath.row! = 0)' check in 'didSelectRowAtIndexPath' ปลอดภัยหรือไม่? แถวต้องไม่เป็น 0 ด้วยการใช้งาน 'willSelectRowAtIndexPath' ของคุณใช่ไหม
Glenn85

1
@ Glenn85 ขออภัยที่ตอบช้า ใช่มันเป็นเพียงเพื่อความปลอดภัยเพิ่มเติม
Sumit Anantwar

28

ในเครื่องมือสร้างส่วนต่อประสานคลิกที่มุมมองตารางปัญหาของคุณ

มุมมองตารางปัญหา

จากนั้นไปที่แอททริบิวตัวตรวจสอบและเปลี่ยนสไตล์ธรรมดาเป็นจัดกลุ่ม;) ง่าย

ง่าย


17

สิ่งที่น่าสนใจเกี่ยวกับ UITableViewStyleGrouped คือ tableView จะเพิ่มสไตล์ให้กับเซลล์ไม่ใช่ไปที่ TableView

สไตล์ถูกเพิ่มเป็น backgroundView ให้กับเซลล์เป็นคลาสที่ชื่อว่า UIGroupTableViewCellBackground ซึ่งจัดการการวาดพื้นหลังที่แตกต่างกันตามตำแหน่งของเซลล์ในส่วน

ดังนั้นวิธีแก้ปัญหาที่ง่ายมากคือการใช้ UITableViewStyleGrouped ตั้งค่า backgroundColor ของตารางเป็น clearColor และเพียงแค่เปลี่ยน backgroundView ของเซลล์ใน cellForRow:

cell.backgroundView = [[[UIView alloc] initWithFrame:cell.bounds] autorelease];

1
นี่ควรเป็นคำตอบที่ดีที่สุด มีโพสต์บล็อกเกี่ยวกับที่นี่: corecocoa.wordpress.com/2011/09/17/…
Sam

วิธีนี้ไม่ได้ผลจริงๆ ฉันได้รับพื้นที่เพิ่มเติมรอบเซลล์รอบ ๆ ความคิดใด ๆ
gsempe

2
contentView ของเซลล์จะไม่ถูกเลื่อนไปทางขวาหรือไม่
Piotr Tomasik

15

เปลี่ยนสไตล์ TableView ของคุณ:

self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];

ตามเอกสารของ apple สำหรับ UITableView:

UITableViewStylePlain- มุมมองตารางธรรมดา ส่วนหัวหรือท้ายกระดาษของส่วนใด ๆ จะแสดงเป็นตัวคั่นอินไลน์และลอยเมื่อมุมมองตารางถูกเลื่อน

UITableViewStyleGrouped- มุมมองตารางที่มีส่วนนำเสนอกลุ่มของแถวที่แตกต่างกัน ส่วนหัวและท้ายกระดาษไม่ลอย


5

มีอีกวิธีที่ยุ่งยาก แนวคิดหลักคือการเพิ่มหมายเลขส่วนเป็นสองเท่าและส่วนแรกจะแสดงส่วนหัวเท่านั้นขณะที่ส่วนที่สองแสดงเซลล์จริง

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return sectionCount * 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section%2 == 0) {
        return 0;
    }
    return _rowCount;
}

สิ่งที่ต้องทำคือการใช้ผู้รับมอบสิทธิ์ headerInSection:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        //return headerview;
    }
    return nil;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        //return headerheight;
    }
    return 0;
}

วิธีการนี้มีผลกระทบเพียงเล็กน้อยต่อแหล่งข้อมูลของคุณ:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    int real_section = (int)indexPath.section / 2;
    //your code
}

เมื่อเปรียบเทียบกับวิธีอื่นวิธีนี้ปลอดภัยในขณะที่ไม่เปลี่ยนเฟรมหรือ contentInsets ของ tableview หวังว่ามันจะช่วยได้


5

วิธีที่ง่ายที่สุดในการได้รับสิ่งที่คุณต้องการคือการกำหนดรูปแบบตารางของคุณเป็นUITableViewStyleGroupedตัวคั่นสไตล์เป็นUITableViewCellSeparatorStyleNone:

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return CGFLOAT_MIN; // return 0.01f; would work same 
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    return [[UIView alloc] initWithFrame:CGRectZero];
}

อย่าลองมุมมองท้ายกระดาษกลับมาnilอย่าลืมตั้งค่าความสูงส่วนหัวและมุมมองส่วนหัวหลังจากคุณต้องได้รับสิ่งที่คุณต้องการ


4

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


ความคิดที่ดี. ฉันรักแฮ็คนี้
Steve Moser

ค่อนข้างตลก ซาบซึ้งความคิด แต่การแฮ็คก็คือการแฮ็ค ส่วนหัวจะเริ่มลอยที่ด้านล่างดังนั้นจึงไม่ได้แก้ปัญหาจริงๆ
Shyam Bhat

4

สำหรับ Swift 3+

เพียงใช้UITableViewStyleGroupedและตั้งค่าความสูงของท้ายกระดาษให้เป็นศูนย์ด้วยสิ่งต่อไปนี้:

override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return .leastNormalMagnitude
}

1
คุณสามารถกลับ 0 .leastNormalMagnitudeแทน นอกจากนี้คุณต้องดำเนินการtableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
Ilias Karim

@IliasKarim ตั้งค่าเป็น 0 casues เพื่อให้มีความสูงไม่เป็นศูนย์ นอกจากนี้ยังไม่จำเป็นต้องใช้viewForFooterInSectionฟังก์ชั่นในกรณีนี้
Tamás Sengel

0และ.leastNormalMagnitudeมีผลเช่นเดียวกัน การใช้viewForFooterSectionวิธีการเป็นสิ่งที่จำเป็น คุณควรกลับศูนย์ นี่คือ Swift 5.1 พร้อม Xcode 11.3.1
Ilias Karim

3

ในขณะที่คิดวิธีจัดการกับปัญหานี้ฉันจำรายละเอียดที่สำคัญมากเกี่ยวกับ UITableViewStyleGrouped วิธีที่ UITableView ใช้สไตล์ที่มีการจัดกลุ่ม (เส้นขอบที่ล้อมรอบเซลล์) คือการเพิ่ม backgroundView แบบกำหนดเองให้กับ UITableViewCells และไม่ให้กับ UITableView แต่ละเซลล์จะถูกเพิ่ม backgroundView ตามตำแหน่งในส่วน (แถวด้านบนจะได้รับส่วนบนของเส้นขอบส่วนส่วนที่อยู่ตรงกลางจะได้รับเส้นขอบด้านข้างและด้านล่างจะได้รับ - ดีส่วนด้านล่าง) ดังนั้นหากเราต้องการสไตล์ธรรมดาและเราไม่มี backgroundView ที่กำหนดเองสำหรับเซลล์ของเรา (ซึ่งเป็นกรณีใน 90% ของเวลา) ดังนั้นสิ่งที่เราต้องทำคือใช้ UITableViewStyleGrouped และลบพื้นหลังที่กำหนดเอง . ซึ่งสามารถทำได้โดยทำตามสองขั้นตอนเหล่านี้:

เปลี่ยนสไตล์ tableView ของเราเป็น UITableViewStyleGrouped เพิ่มบรรทัดต่อไปนี้เป็น cellForRow ก่อนที่เราจะส่งคืนเซลล์:

cell.backgroundView = [[[UIView alloc] initWithFrame: cell.bounds] autorelease];

และนั่นคือมัน สไตล์ tableView จะกลายเป็นเหมือนกับ UITableViewStylePlain ยกเว้นส่วนหัวลอย

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


2

บางทีคุณสามารถใช้scrollViewDidScrollบน tableView และเปลี่ยนcontentInsetตามส่วนหัวที่มองเห็นได้ในปัจจุบัน

ดูเหมือนว่าจะใช้งานได้กับกรณีการใช้งานของฉัน!

extension ViewController : UIScrollViewDelegate{

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard   let tableView = scrollView as? UITableView,
            let visible = tableView.indexPathsForVisibleRows,
            let first = visible.first else {
            return
        }

        let headerHeight = tableView.rectForHeader(inSection: first.section).size.height
        let offset =  max(min(0, -tableView.contentOffset.y), -headerHeight)
        self.tableView.contentInset = UIEdgeInsetsMake(offset, 0, -offset, 0)
   }
}

1

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


1

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


FooterViews จะลอยเช่นเดียวกับ HeaderViews พวกมันลอยที่ด้านล่างของหน้าจอไม่ใช่ด้านบน
Mark A. Donohoe

0

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

วิธีนี้ง่ายที่สุดถ้าคุณใช้ตัวสร้างส่วนต่อประสาน คุณจะเพิ่ม UIView ที่ด้านบนของมุมมอง (ภาพจะไปที่ไหน) จากนั้นเพิ่มมุมมองตารางของคุณด้านล่าง IB ควรปรับขนาดให้เหมาะสม นั่นคือมุมมองด้านบนของตารางสัมผัสด้านล่างของ UIView ที่คุณเพิ่งเพิ่มเข้าไปและความสูงนั้นครอบคลุมส่วนที่เหลือของหน้าจอ

ความคิดที่นี่คือถ้า UIView นั้นไม่ได้เป็นส่วนหนึ่งของมุมมองตารางมันจะไม่เลื่อนด้วยมุมมองของตาราง ie ละเว้นส่วนหัวของ tableview

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


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

0

ตรวจสอบคำตอบวิธีใช้ส่วนหัวด้วย StoryBoard: Table Header Views ใน StoryBoards

โปรดสังเกตด้วยว่าหากคุณไม่ได้ใช้งาน

viewForHeaderInSection:(NSInteger)section

มันจะไม่ลอยซึ่งเป็นสิ่งที่คุณต้องการ


0

ในการลบส่วนหัวของส่วนที่ลอยออกมาอย่างสมบูรณ์คุณสามารถทำได้:

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return [[UIView alloc] init];
}

return nil ไม่ทำงาน

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


0

รูปแบบเกี่ยวกับโซลูชันของ @ samvermette:

/// Allows for disabling scrolling headers in plain-styled tableviews
extension UITableView {

    static let shouldScrollSectionHeadersDummyViewHeight = CGFloat(40)

    var shouldScrollSectionHeaders: Bool {
        set {
            if newValue {
                tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: bounds.size.width, height: UITableView.shouldScrollSectionHeadersDummyViewHeight))
                contentInset = UIEdgeInsets(top: -UITableView.shouldScrollSectionHeadersDummyViewHeight, left: 0, bottom: 0, right: 0)
            } else {
                tableHeaderView = nil
                contentInset = .zero
            }
        }

        get {
            return tableHeaderView != nil && contentInset.top == UITableView.shouldScrollSectionHeadersDummyViewHeight
        }
    }

}

0

ตัวอย่างแสดงส่วนหัวที่เหนียวสำหรับส่วนแรกเท่านั้น ส่วนหัวอื่น ๆ จะลอยด้วยเซลล์

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    if section == 1 {
        tableView.contentInset = .zero
    }

}

func tableView(_ tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
    if section == 0 {
        tableView.contentInset = .init(top: -tableView.sectionHeaderHeight, left: 0, bottom: 0, right: 0)
    }
}

-1

สิ่งนี้สามารถทำได้โดยการกำหนดมุมมองส่วนหัวด้วยตนเองในเมธอด viewDidLoad ของ UITableViewController แทนการใช้ viewForHeaderInSection และ heightForHeaderInSection ของผู้รับมอบสิทธิ์ ตัวอย่างเช่นในคลาสย่อยของ UITableViewController คุณสามารถทำสิ่งนี้:

- (void)viewDidLoad {
    [super viewDidLoad];

    UILabel *headerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 40)];
    [headerView setBackgroundColor:[UIColor magentaColor]];
    [headerView setTextAlignment:NSTextAlignmentCenter];
    [headerView setText:@"Hello World"];
    [[self tableView] setTableHeaderView:headerView];
}

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


นี่ไม่ใช่สำหรับส่วนนี้มีไว้สำหรับ 1 ส่วนหัวที่ด้านบน
makdad

-1

บางทีคุณสามารถทำให้พื้นหลังมุมมองส่วนหัวโปร่งใสได้:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    view.tintColor = [UIColor clearColor];
}

หรือใช้ทั่วโลก:

    [UITableViewHeaderFooterView appearance].tintColor = [UIColor clearColor];

-2

ฉันมีวิธีแก้ปัญหาที่ง่ายกว่านี้อีกใช้ได้โดยไม่ต้องมีการชำระอัตโนมัติและทุกสิ่งที่ทำผ่าน XIB:

1 / วางส่วนหัวของคุณใน tableview โดยการลากและวางลงบน tableview โดยตรง

2 / ในตัวตรวจสอบขนาดของส่วนหัวที่เพิ่งสร้างใหม่เพียงแค่เปลี่ยนการปรับขนาดอัตโนมัติ: คุณควรปล่อยจุดยึดด้านบนซ้ายและขวารวมทั้งการเติมในแนวนอน

นั่นเป็นวิธีที่ควรตั้งค่าสำหรับส่วนหัว

นั่นควรทำเคล็ดลับ!


-2

ตามคำตอบของ @ samvermette, ฉันได้ติดตั้งโค้ดด้านบนใน Swift เพื่อให้ง่ายสำหรับผู้ใช้รหัสที่จะใช้ swift

let dummyViewHeight = CGFloat(40)
self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.bounds.size.width, height: dummyViewHeight))
self.tableView.contentInset = UIEdgeInsetsMake(-dummyViewHeight, 0, 0, 0)

-2

ref: https://stackoverflow.com/a/26306212

let tableView = UITableView(frame: .zero, style: .grouped)

Pluse

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0 {
        return 40
    }else{
        tableView.sectionHeaderHeight = 0
    }

    return 0
}

สิ่งนี้ช่วยในการใช้พื้นที่ส่วนหัว


กรุณาอย่าทำอย่างนั้น🙏
MQoder

-3

2563 อัพเดทล่าสุด

ทดสอบกับ Xcode 14

สำหรับการซ่อนส่วนหัวของส่วนใด ๆ ส่งคืนศูนย์สำหรับชื่อเรื่องของผู้แทนส่วน

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return nil
}

-4

คุณสามารถทำสิ่งนี้ได้อย่างง่ายดายโดยการใช้เมธอด viewForHeaderInSection ในคลาสผู้รับมอบสิทธิ์ tableview วิธีนี้คาดว่า UIView เป็นวัตถุส่งคืน (ซึ่งเป็นมุมมองส่วนหัวของคุณ) ฉันทำสิ่งเดียวกันในรหัสของฉัน


โปสเตอร์ต้นฉบับไม่ต้องการส่วนหัวที่กำหนดเอง พวกเขาต้องการส่วนหัวที่ไม่ "ลอย" ที่ด้านบนของตาราง ข้อเสนอแนะของคุณยังคงลอยอยู่
jemmons

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