2010-02-23 49 views
24

Tôi có một UITableview mà tôi tải với dữ liệu không đồng bộ để bảng nhìn có thể xuất hiện mà không có dữ liệu.
Tôi đã mệt mỏi với phương pháp ReloadData nhưng bảng nhìn vẫn trống cho đến khi tôi cuộn bảng xem, đột nhiên dữ liệu xuất hiện.
Điều tương tự cũng xảy ra khi tôi tải chế độ xem bảng và xem chi tiết giữa các mục, dữ liệu mục trước sẽ xuất hiện đầu tiên và ngay khi tôi cuộn trong chế độ xem bảng, nó sẽ hiển thị dữ liệu chính xác.
Tôi đoán là phương pháp ReloadData hoạt động tốt, nhưng tôi cần vẽ lại bảng phân cảnh bằng cách nào đó, bất kỳ đề xuất nào về cách giải quyết vấn đề này?Vẽ lại UITableView sau khi cập nhật dữ liệu async

/Jimmy

+0

Thông thường, phương thức reloadData làm mới chế độ xem của chế độ xem bảng. Bạn có thể đặt mẫu mã TableViewController của bạn? –

Trả lời

53

Bạn nói bạn đang Populating nội dung không đồng bộ nhưng bạn đã gọi reloadData trong bối cảnh các chủ đề chính? (Và không phải thông qua các chủ đề thao tác trên nội dung)

Objective-C

[yourUITableView performSelectorOnMainThread:@selector(reloadData) 
            withObject:nil 
           waitUntilDone:NO]; 

Swift

dispatch_async(dispatch_get_main_queue(), { self.tableView.reloadData() }) 

MonoTouch

InvokeOnMainThread(() => this.TableView.ReloadData()); 
+7

Cảm ơn đã giải quyết nó =) giải pháp cho monotouch là: InvokeOnMainThread (() => this.TableView.ReloadData()); –

+0

@yonel Tôi đang gặp vấn đề tương tự như JimmyEngtröm và tôi thực sự hy vọng những gì bạn nói sẽ làm điều đó, nhưng than ôi tôi vẫn gặp vấn đề này. Tôi không thể tìm cách làm mới UITableView sau khi cập nhật các mảng dữ liệu cơ bản mà nó đang sử dụng. –

+0

@ MasonG.Zhwiti: đặt một điểm ngắt trong phương thức numberOfRowsInSections trong nguồn dữ liệu bảng của bạn và kiểm tra xem nó có nằm trong nó sau khi reloadData hay không. Sau đó kiểm tra số hàng bạn quay trở lại đây, nếu nó không phải 0, thì nó sẽ gọi cho cellForRowAtIndex. – yonel

2

Tôi đoán nó không được nạp lại.

Khi bạn di chuyển các tế bào để ra khỏi màn hình, sau đó ...

tableView: cellForRowAtIndexPath:

... sẽ được gọi. Vì vậy, nó sẽ được tải lại.

Tôi đoán biến UITableView không được xác thực.

Nếu bạn sử dụng UITableView làm chế độ xem chính, bạn có thể thử điều này.

[self.view reloadData];

hoặc

[self.tableView reloadData];

4

Yonels Câu trả lời là hoàn hảo khi xem bạn là hiện thời hiển thị cho người sử dụng (ví dụ: Người dùng nhấn một nút tải lại mà populates UITableView của bạn.)

Tuy nhiên, nếu dữ liệu của bạn được tải không đồng bộ và UITableView của bạn không hiển thị trong khi cập nhật (ví dụ: Bạn thêm Dữ liệu vào số UITableView trong Chế độ xem khác và UITableView được hiển thị sau bởi userinput), chỉ cần ghi đè phương thức viewWillAppear của UITableViewController.

- (void)viewWillAppear:(BOOL)animated{ 
[super viewWillAppear:animated]; 
[self.tableView reloadData]; 
} 

Hiệu ứng tích cực là UITableView chỉ tải lại dữ liệu của nó một lần khi người dùng thực sự muốn xem nó, chứ không phải khi thêm mục mới.

2

Tôi đã gặp sự cố tương tự ngày hôm nay (Storyboard trong iOS 7.0). Tôi đã sử dụng bảng Xem bên trong một UIViewController.Khi xem được nạp tất cả mọi thứ đã làm việc tốt; tất cả các đại biểu đã được gọi.Tuy nhiên ; Khi dataSource cơ bản (trong trường hợp của tôi, Array) đã được sửa đổi; các hàng của bảng hiển thị không được cập nhật. Chúng đã được cập nhật; chỉ khi tôi đang cuộn chế độ xem bảng.

Đã thử mọi thứ; gọi reloadData trên Main thread, gọi lại tải lại trong ViewWillAppear; không có gì hiệu quả.

Sự cố mà tôi đã tìm thấy; là tôi đã không tạo ra kết nối trong bảng phân cảnh; cho xem bảng với tham chiếu Outlet.The dataSource và delegate được thiết lập mặc dù. Tôi không nghĩ rằng đó có thể là vấn đề; vì mọi thứ đều hoạt động tốt ở lần đầu tiên.

Hy vọng nó sẽ giúp ai đó.Tôi đã có một số thời gian khủng khiếp để tìm ra điều này.

0

Sau khi sao chép một cách ngây thơ một cách ngây thơ trong giải pháp của yonel và gọi nó là tốt, tôi nhận ra rằng gọi performSelectorOnMainThread:withObject:waitUntilDone: cố định các triệu chứng, nhưng không phải là vấn đề. Vấn đề lớn hơn là bạn đang thực hiện cập nhật giao diện người dùng trong khi vẫn còn trong ngữ cảnh của chuỗi không đồng bộ hoặc nền.

Đây là những gì mã của tôi trông giống như:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 
    // Make a call to reload table data 

}); 

Khi nó sẽ giống như thế này:

dispatch_queue_t queue = dispatch_queue_create("com.kyleclegg.myqueue", NULL); 
dispatch_async(queue, ^{ 

    // Make API call 
    // Retrieve data, parse JSON, update local properties 

    dispatch_async(dispatch_get_main_queue(), ^{ 
    // Now make the call to reload data and make any other UI updates 
    [self.tableView reloadData] 
    }); 

}); 

Nếu điều chỉ bạn cần phải làm là gọi [self.tableView reloadData] nó có thể là tốt để sử dụng performSelectorOnMainThread:withObject:waitUntilDone: vì nó hoàn thành cùng một mục tiêu, nhưng bạn cũng nên nhận ra những gì đang xảy ra trong bức tranh lớn. Ngoài ra, nếu bạn đang làm nhiều công việc giao diện người dùng hơn là tải lại bảng thì tất cả mã đó cũng sẽ nằm trên hàng đợi chính.

Tham chiếu: A concise example sử dụng GCD và quản lý nền so với chuỗi chính.

Các vấn đề liên quan