2012-09-01 16 views
7

Tôi đã triển khai ứng dụng iPhone sử dụng UITableViewController/UITableView và dữ liệu lõi. Hơn nữa, tôi sử dụng NSFetchedResultsController để quản lý dữ liệu bảng. Đây là tất cả rất thẳng về phía trước và hoạt động tuyệt vời. Sau đó tôi quyết định rằng tôi sẽ hiển thị một tin nhắn trong UITableView khi không có hàng nơi tìm thấy/lấy ra. Sau khi nghiên cứu điều này, có vẻ như cách tốt nhất (có lẽ là cách duy nhất) để làm điều này là trả lại một ô "giả" có chứa thông báo. Tuy nhiên, khi tôi làm điều này, tôi nhận được một chương trình khó chịu từ hệ thống thời gian chạy than phiền (và đúng như vậy) về sự không thống nhất của dữ liệu: "Cập nhật không hợp lệ: số phần không hợp lệ. Số phần chứa trong chế độ xem bảng ...". Đây là mã có liên quan: phản ứngHiển thị thông báo "Không tìm thấy hàng" trong UITableView với dữ liệu lõi

- (NSInteger) numberOfSectionsInTableView: (UITableView *)tableView 
{ 
    if ([[self.fetchedResultsController fetchedObjects] count] == 0) return 1; 
    return [[self.fetchedResultsController sections] count]; 
} 

- (NSInteger) tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    if ([[self.fetchedResultsController fetchedObjects] count] == 0) return 1; 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex: section]; 
    return [sectionInfo numberOfObjects]; 
} 

- (UITableViewCell *) tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath 
{ 
    if ([[self.fetchedResultsController fetchedObjects] count] == 0) { 
     UITableViewCell *cell = [[UITableViewCell alloc] init]; 
     cell.textLabel.text = @"No widgets found."; 
     return cell; 
    } 

    STCellView *cell = (STCellView *)[tableView dequeueReusableCellWithIdentifier: @"ShieldCell"]; 
    [self configureCell: cell atIndexPath: indexPath]; 
    return cell; 
} 

Tôi đã đọc từ câu hỏi tương tự và dường như tôi nên sử dụng

insertRowsAtIndexPaths: withRowAnimation: 

để chèn "giả" hàng nhắn vào bàn của tôi. Tuy nhiên, điều này cũng có nghĩa là xóa hàng "giả" khi một hàng thực được chèn vào. Tôi có thể làm điều này, nhưng có vẻ như có một cách dễ dàng hơn để thực hiện việc này. Tất cả những gì tôi muốn làm là hiển thị một thông báo cho biết rằng không có hàng nào trong bảng (đủ đơn giản?). Vì vậy, câu hỏi của tôi là: Có cách nào để hiển thị một tin nhắn trong một UITableView mà không sử dụng cách tiếp cận "giả" tế bào HOẶC là có một cách để thuyết phục UITableViewController/NSFetchResulsController rằng đây chỉ là một hàng "giả" và họ không nên nhận được rất buồn vì nó không phải là một hàng thực (từ quan điểm của tôi) trong bảng?

Bất kỳ trợ giúp nào bạn có thể cung cấp sẽ rất được đánh giá cao (Tôi là một người mới gặp khó khăn trong việc phát triển iPhone và tôi muốn tìm hiểu các phương pháp hay nhất). Cảm ơn.

+2

Thay vì hack với nguồn dữ liệu bảng để có được giao diện người dùng dự định tại sao không thêm thông báo "Không tìm thấy hàng" vào tiêu đề tableview thay vào đó? – Rog

+0

@Rog Mẹo hữu ích. +1 –

+0

Đây là cách tiếp cận tốt nhất nếu bạn chỉ có một phần trong chế độ xem bảng của mình. Xem cách tiếp cận của tôi dưới đây cho nhiều phần – Brett

Trả lời

12

Thay vì hack với nguồn dữ liệu tableview để nhận giao diện người dùng dự định, bạn nên thêm thông báo "Không tìm thấy hàng" vào tiêu đề tableview để thay thế.

+0

Đây là câu trả lời rõ ràng nhất và tốt nhất. Cảm ơn rất nhiều!! – user1092808

+0

Tôi thích âm thanh này. Bạn đang nói rằng bạn xem cho số hàng có sẵn, sau đó có điều kiện hiển thị/ẩn tiêu đề tableview? Hoặc luôn hiển thị tiêu đề và chỉ cần thay đổi văn bản thành "Không tìm thấy hàng"? –

+0

Sẽ không hoạt động trong trường hợp thanh tìm kiếm trong tiêu đề – Andy

1

Đề xuất đơn giản của tôi để hiển thị thông báo trống là sắp xếp lại bộ điều khiển của bạn thành đơn giản UIViewController (không phải là UITableViewController).

UIViewController này được sáng tác bởi một UITableView (bộ điều khiển là nguồn dữ liệu và các đại biểu cho bảng của bạn) và bởi một UILabel (hoặc một UIView có chứa một UILabel) mà hiển thị thông báo hàng trống.

Theo cách này, bạn có thể kiểm soát khả năng hiển thị của bảng và nhãn dựa trên các hàng đã truy xuất.

Cách tiếp cận này có thể mất thời gian nhưng tôi nghĩ tốt để tránh hack NSFetchResultsController và nguồn dữ liệu. Hơn nữa, bạn có thể kiểm soát hoàn toàn việc sắp xếp vị trí cho thông điệp trống của mình.

Vì @Rog đề xuất bạn cũng có thể sử dụng tiêu đề chế độ xem bảng để hiển thị thông báo đó. Như bạn thích.

Hy vọng điều đó sẽ hữu ích.

+0

Đây không phải là một giải pháp tốt vì bạn không thể sử dụng '' UITableViewController'' 'được xây dựng trong '' UIRefreshControl'' đúng phân lớp '' UIViewController''. Tốt hơn là sử dụng bộ điều khiển khung nhìn để nhúng lớp con của bộ điều khiển xem bảng và xử lý chế độ xem trống trong bộ điều khiển xem bộ chứa. – amb

+0

@amb Đó là một giải pháp có thể ... các op đã không yêu cầu sử dụng một kéo xuống để làm mới chức năng ... Trong opionion của tôi ở đây ngăn chặn là quá nhiều. Cám ơn bạn đã góp ý. –

+0

Vâng, bạn hoàn toàn đúng, nhưng sử dụng cả một '' UITableViewController'' và '' UIRefreshControl'' là một cái gì đó rất phổ biến khi bạn phải hiển thị một thông báo xem bảng trống. – amb

1

Phương pháp thay thế mà tôi đã sử dụng trước đây là sử dụng Dữ liệu cốt lõi để quản lý cập nhật cho bạn bằng cách chèn thực thể 'không có hàng' cho phần không có hàng nào được phát hiện trong lớp mô hình của bạn. cập nhật.

Có một số cách để thực hiện điều này, ví dụ: đặt trường tên/tiêu đề thành thông báo trạng thái đã biết hoặc cờ trong thực thể. Sau khi chèn, bạn có thể phát hiện thực thể 'no rows' trong phương thức ủy nhiệm cellForRowAtIndexPath và chèn một ô bảng thay thế để hiển thị thông báo.

Chỉ cần xóa thực thể 'không có hàng' trước khi làm mới dữ liệu cho phần đó.

+0

Tại sao bỏ phiếu xuống? Tôi chỉ cung cấp một giải pháp làm việc để xử lý nhiều phần! – Brett

7

Tôi đã làm như sau trong viewDidLoad.

UILabel *label = [[UILabel alloc] init]; 
[label setTextColor:[UIColor lightGrayColor]]; 
[label setText:@"No widgets found."]; 
[label sizeToFit]; 
label.frame = CGRectMake((self.tableView.bounds.size.width - label.bounds.size.width)/2.0f, 
         (self.tableView.rowHeight - label.bounds.size.height)/2.0f, 
         label.bounds.size.width, 
         label.bounds.size.height); 
[self.tableView insertSubview:label atIndex:0]; 

Trong trường hợp này, mỗi TableViewCells phải mờ đục để ẩn nhãn. hoặc cần phải chuyển đổi thuộc tính ẩn của nhãn theo số lượng hàng.