UITableView: ẩn tiêu đề khỏi phần trống


76

tôi có một UITableView, hiển thị chi phí từ tháng hiện tại (xem ảnh chụp màn hình):

Vấn đề của tôi là với tiêu đề cho các phần trống. có cách nào để ẩn chúng? Dữ liệu được tải từ coredata.

đây là mã tạo tiêu đề tiêu đề:

TitleForHeader

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

NSDate *today = [NSDate date ];
int todayInt = [dataHandler getDayNumber:today].intValue;

NSDate *date = [NSDate dateWithTimeIntervalSinceNow:(-(todayInt-section-1)*60*60*24)];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]]];    
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *formattedDateString = [dateFormatter stringFromDate:date];
    return formattedDateString;}

}

ViewForHeader

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

    UIView *headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 30)];
    UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(4, 9, 312, 20)];
    UIView *top = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 5)];
    UIView *bottom = [[UIView alloc]initWithFrame:CGRectMake(0, 5, 312, 1)];

    [top setBackgroundColor:[UIColor lightGrayColor]];
    [bottom setBackgroundColor:[UIColor lightGrayColor]];

    [title setText:[expenseTable.dataSource tableView:tableView titleForHeaderInSection:section]];
    [title setTextColor:[UIColor darkGrayColor]];
    UIFont *fontName = [UIFont fontWithName:@"Cochin-Bold" size:15.0];
    [title setFont:fontName];


    [headerView addSubview:title];
    [headerView addSubview:top];
    [headerView addSubview:bottom];

    return headerView;

}

}

heightForHeader

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

NSLog(@"Height: %d",[tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0);
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section == 0]) {
    return 0;
} else {
    return 30;
}
}

numberOfRowsInSection

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {

int rows = 0;
for (Expense* exp in [dataHandler allMonthExpenses]) {
    if ([exp day].intValue == section) {
        rows++;
    }
}

return rows;
}

nhập mô tả hình ảnh ở đây sebastian

Câu trả lời:


57

Điều gì xảy ra nếu trong - tableView:viewForHeaderInSection:bạn return nilnếu số phần là 0.

CHỈNH SỬA : Bạn có thể sử dụng numberOfRowsInSectionđể lấy số phần tử trong phần.

CHỈNH SỬA : Có lẽ bạn cũng nên trả về nil titleForHeaderInSectionnếu numberOfRowsInSectionlà 0.

CHỈNH SỬA : Bạn đã thực hiện phương pháp sau?

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

EDIT : ví dụ Swift 3

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    switch section {
    case 0:
        if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
            return "Title example for section 1"
        }
    case 1:
        if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
            return "Title example for section 2"
        }
    default:
        return nil // when return nil no header will be shown
    }
    return nil
}

thật đáng buồn là nó không hoạt động .. tôi đã cập nhật câu hỏi bằng mã mới và ảnh chụp màn hình mới.
Sebastian Flückiger

không có lỗi. vừa hoàn thành việc chỉnh sửa câu hỏi. bây giờ có mã mới và ảnh chụp màn hình mới.
Sebastian Flückiger

nhân tiện, bạn đã triển khai numberOfRowsInSection chưa?
LuisEspinoza

1
và điều gì sẽ xảy ra nếu bạn kiểm tra kích thước của tiêu đề phần trong nib? .. có thể nếu bạn sử dụng 0, bạn sẽ có kết quả tốt hơn..vì bạn đang đặt nó trong mã.
LuisEspinoza

2
Đây là một câu hỏi cũ bây giờ, nhưng return nil;trong titleForHeaderInSectionlà đủ cho tôi (sau khi kiểm tra count > 0cho rằng phần tất nhiên)
Patrick

135

Bạn phải đặt tableView:heightForHeaderInSection:thành 0 cho các phần thích hợp. Đây là một cái gì đó đã thay đổi khá gần đây và đã đưa tôi đến một vài nơi. Từ UITableViewDelegatenó nói rằng ...

Trước iOS 5.0, chế độ xem bảng sẽ tự động thay đổi kích thước chiều cao của tiêu đề thành 0 cho các phần mà tableView: viewForHeaderInSection: trả về chế độ xem nil. Trong iOS 5.0 trở lên, bạn phải trả về chiều cao thực cho mỗi tiêu đề phần trong phương pháp này.

Vì vậy, bạn sẽ phải làm một cái gì đó như

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return 0;
    } else {
        // whatever height you'd want for a real section header
    }
}

thật đáng buồn là nó không hoạt động .. tôi đã cập nhật câu hỏi bằng mã mới và ảnh chụp màn hình mới.
Sebastian Flückiger

3
Bảng tĩnh có một chút khác biệt. Mã này dành cho các chế độ xem tiêu đề bảng tùy chỉnh, không chỉ là a title. Nếu bạn đang đặt một, titlebạn sẽ cần phải quay lại nilcuộc gọi phương thức tableView:titleForHeaderInSection:khi thích hợp. Nếu bạn đang sử dụng các chế độ xem tiêu đề tùy chỉnh, bạn phải ghi đè viewForHeaderInSection. Nếu bạn đang làm điều đó, mã này sẽ hoạt động. Nếu không, tôi cần thêm thông tin để giải quyết vấn đề.
DBD

tuyệt vời ... cảm ơn rất nhiều. trước đó tôi đã trả lại một khoảng trống UIViewnhư thế này: else { vw = [[UIView alloc]init]; [vw setHidden:YES]; }
Vaibhav Saran

tôi đã sử dụng viewforheader trong phần + mã trên và hoạt động hoàn hảo trong iOS 6 và thậm chí ở phiên bản thấp hơn. thnnxx bạn thân
Amrit Trivedi có

Làm việc cho tôi - Tôi đang trên iOS6
Shirish Kumar

54

Trong tình huống kỳ lạ của tôi, tôi phải quay lại:

viewForHeaderInSection -> nil

 viewForFooterInSection -> nil (đừng quên footer!)

heightForHeaderInSection -> 0.01 (không phải 0!)

 heightForFooterInSection -> 0.01

chỉ trong trường hợp này các phần trống biến mất hoàn toàn


10
Tôi đã làm điều đó chỉ bằng cách đặt headerHeight thành 0,01.
Akshit Zaveri

1
iOS 8.4 Tôi vẫn có thể thấy văn bản bằng cách sử dụng 0,01, nhưng 0,0 đã làm việc ghi đè lên func tableView (tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {if securedTableData [section] .count == 0 {return CGFloat (0.0)} return CGFloat (40.0)}
DogCoffee

Điều này làm việc cho tôi một cách hoàn hảo. Thật không may, tôi không thể tìm thấy điều này ở bất kỳ nơi nào khác. Cảm ơn anh bạn.
Ruchi

Ngay cả trong iOS 12.1, bạn vẫn phải đặt chiều cao thành 0.01.... iOS có một số lỗi lạ.
Supertecnoboff

10

Hãy xem phương pháp -[UITableViewDelegate tableView:heightForHeaderInSection:]. Đặc biệt là lưu ý đi kèm với tài liệu của nó:

Trước iOS 5.0, chế độ xem bảng sẽ tự động thay đổi kích thước chiều cao của tiêu đề thành 0 cho các phần có tableView:viewForHeaderInSection: trả lại nilchế độ xem. Trong iOS 5.0 trở lên, bạn phải trả về chiều cao thực cho mỗi tiêu đề phần trong phương pháp này.


cảm ơn rất kẻ MCH - cập nhật ốm bạn trong một vài giờ và sẽ chấp nhận và upvote bất cứ điều gì làm việc tốt nhất :-)
Sebastian Flückiger

2
thật đáng buồn là nó không hoạt động .. tôi đã cập nhật câu hỏi bằng mã mới và ảnh chụp màn hình mới.
Sebastian Flückiger

9

Tôi biết đây là một câu hỏi cũ nhưng tôi muốn thêm vào nó. Tôi thích cách tiếp cận đặt titleHeaderthành nil hơn là thay đổi heightForHeaderInSectionthành 0 vì nó có thể gây ra vấn đề với indexPathviệc được +1 từ vị trí đáng lẽ do tiêu đề vẫn ở đó nhưng bị ẩn.

Vì vậy, với điều đó đã nói và xây dựng trên câu trả lời của DBD, bạn có thể đặt thành titleForHeaderInSection:nil cho các phần không có hàng trong đó như sau:

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

7

Vào năm 2015 bằng cách sử dụng iOS 8 và Xcode 6, những điều sau đây phù hợp với tôi:

/* Return the title for each section if and only if the row count for each section is not 0. */

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    }else{

    // here you want to return the title or whatever string you want to return for the section you want to display

    return (SomeObject*)someobjectArray[section].title;
    }
}

5

Đây có vẻ là cách thích hợp, Nó sẽ hoạt hình chính xác và hoạt động sạch sẽ ... như Apple dự định ...

Cung cấp thông tin thích hợp cho đại biểu tableView

Khi không có mục nào trong phần, Trả lại 0,0f trong:

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

..Cũng trả về nil cho:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

Thực hiện xóa dữ liệu thích hợp cho tableView

  1. Gọi [tableView beginUpdates];
  2. Xóa các mục khỏi dữ liệu của bạn Nguồn, theo dõi vị trí các phần tử đã bị xóa ..
  3. Gọi deleteRowsAtIndexPathsvới các đường dẫn chỉ mục của các ô bạn đã loại bỏ.
  4. nếu nguồn dữ liệu của bạn không có mục nào trong đó (Ở đây bạn sẽ chỉ có tiêu đề). GọireloadSections: để tải lại phần đó. Điều này sẽ kích hoạt hoạt ảnh chính xác và ẩn / trượt / làm mờ tiêu đề.
  5. Cuối cùng là gọi [tableView endUpdates];để kết thúc cập nhật ..

1
Cảm ơn vì mẹo về tải lại các lựa chọn: :-) Vẫn không thể làm được gì với tôi với iOS11.
Khó

Tại sao chúng ta phải gọi reloadSections? Tôi nhận thấy rằng nếu tôi không gọi nó, tiêu đề chế độ xem bảng của tôi sẽ chồng lên nhau (cho đến khi tôi cuộn, thì tiêu đề chính xác được hiển thị).
Supertecnoboff

2

Swift 4.2

Đặt heightForHeaderInSection thành Zero và nếu bạn đang xem phần tùy chỉnh, hãy đặt nó thành nil cho các phần không có ô.

func tableView(_ tableView: UITableView,
                   heightForHeaderInSection section: Int) -> CGFloat {
        return height_DefaultSection
    }

func tableView(_ tableView: UITableView,
                   viewForHeaderInSection section: Int) -> UIView? {

        return tableView.dataSource?.tableView(tableView, numberOfRowsInSection: section) == 0 ? nil: headerView(tableView: tableView, section: section)
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.