Tôi có một vấn đề khái niệm khá quan trọng mà nhiều người đã hỏi, nhưng không có câu trả lời rõ ràng đang tìm kiếm.Nút Làm mới iOS trong View Controller Nav: tải lại tất cả tableViewCells được tạo từ JSON được phân tích cú pháp khi được nhấp vào
Ứng dụng của tôi rất đơn giản: Một số hàng của TableViewCells được điền dữ liệu từ nguồn cấp dữ liệu JSON được phân tích cú pháp. Khi một ô được nhấp vào, thông tin của ô đó sẽ được chuyển tới một SecondViewController và được hiển thị. Nguồn cấp dữ liệu JSON cũng được lưu vào một tệp .plist và trong trường hợp Internet không có sẵn, các TableViewCells được điền từ .plist.
Đây là tất cả hoạt động tuyệt vời.
Tuy nhiên, điều cuối cùng tôi cần là nút làm mới ở đầu FirstViewController để làm mới nguồn cấp dữ liệu JSON và tất cả các ô trong bảng có dữ liệu mới từ các biến mới. Tuy nhiên, tôi đã gặp sự cố khi triển khai điều này:
Cuộc gọi JSON ban đầu của tôi và các biến để điền các ô được đặt trong phương thức ViewDidLoad. Khi lượt xem tải, các biến này được "đặt" và không làm mới. Hơn nữa, tôi có thể di chuyển lệnh và biến JSON vào viewWillLoad - thứ sẽ làm mới bảng mỗi lần sau khi nhấp vào một ô, sau đó bấm "back" vào firstViewController - điều này sẽ cập nhật JSON và các ô thành công, tuy nhiên nó tác động tốc độ và làm cho bộ điều khiển xem "tạm dừng" khi quay lại MainViewController, điều này làm cho việc gọi JSON ban đầu của tôi và đặt các biến của tôi trong viewWillLoad là một tùy chọn không thể thay đổi.
tôi đã tạo ra một nút tải lại trong viewDidLoad, được liên kết với một phương pháp IBAction "refresh":
Tạo Nút Programitically trong viewDidLoad:
// Reload issues button
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
target:self
action:@selector(refresh:)];
self.navigationItem.rightBarButtonItem = button;
[button release];
Phương pháp hành động nó liên quan đến:
- (IBAction)refresh:(id)sender {
myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL
URLWithString:@"http://www.yoursite.com/json.JSON"]
encoding:NSUTF8StringEncoding
error:nil];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];
// New updated dictionary built from refreshed JSON
allLetterContents = [myParsedJson objectForKey:@"nodes"];
// Log the new refreshed JSON
NSLog(@"You clicked refresh. Your new JSON is %@", myRawJson);
//Maybe use the notification center?? But don't know how to implement.
//[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(refreshView:)
name:@"refreshView" object:nil];
//[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshView"
object:nil];
}
[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows]
withRowAnimation:UITableViewRowAnimationNone];
[myRawJson release];
}
Trong mã ở trên, bạn có thể thấy rằng Tôi đang gọi lại JSON mỗi lần nút được nhấp và ghi nhật ký một thông báo vào bảng điều khiển với JSON mới. Điều này đang hoạt động. Tôi thậm chí còn xây dựng lại một từ điển bổ sung thành công nội dung mới.
Câu hỏi của tôi là: Làm thế nào tôi có thể làm cho tableViewCells "làm mới" bằng dữ liệu mới này? Tôi có thể chỉ làm cho nút tải lại toàn bộ bộ điều khiển xem - vì vậy nó sẽ gọi lại ViewDidLoad? Tôi có cần phải nghĩ lại cấu trúc ứng dụng của mình hay di chuyển các biến ban đầu ra khỏi chế độ xemDidLoad không?
Tôi đã đọc một số bài đăng trên NSNotificationCenter, nhưng việc triển khai thực hiện điều này vẫn còn cản trở tôi, vì tôi khá mới phát triển iOS.
Cảm ơn ~
Cập nhật:
Nó vẫn không cập nhật. Đây là mã nút làm mới đầy đủ của tôi với [self.tableView reloadData]; được gọi vào cuối IBAction của tôi.
- (IBAction)refresh:(id)sender {
[DSBezelActivityView newActivityViewForView:
self.navigationController.navigationBar.superview
withLabel:@"Loading Feed..." width:160];
myRawJson = [[NSString alloc] initWithContentsOfURL:[NSURL
URLWithString:@"http://site.com/mobile.JSON"]
encoding:NSUTF8StringEncoding
error:nil];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary * myParsedJson = [parser objectWithString:myRawJson error:NULL];
allLetterContents = [myParsedJson objectForKey:@"nodes"];
BOOL isEmpty = ([myParsedJson count] == 0);
if (isEmpty) {
NSString *refreshErrorMessage = [NSString
stringWithFormat:@"An internet or network connection is required."];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Alert"
message: refreshErrorMessage
delegate:self
cancelButtonTitle:@"Close"
otherButtonTitles:nil];
[alert show];
[alert release];
allLetterContents = [NSMutableDictionary
dictionaryWithContentsOfFile:[self saveFilePath]];
//NSLog(@"allLetterContents from file: %@", allLetterContents);
} else {
NSLog(@"Your new allLetterContents is %@", allLetterContents);
// Fast enumeration through the allLetterContents NSMutableDictionary
for (NSMutableDictionary * key in allLetterContents) {
NSDictionary *node = [key objectForKey:@"node"];
NSMutableString *contentTitle = [node objectForKey:@"title"];
NSMutableString *contentNid = [node objectForKey:@"nid"];
NSMutableString *contentBody = [node objectForKey:@"body"];
// Add each Title and Nid to specific arrays
//[self.contentTitleArray addObject:contentTitle];
[self.contentTitleArray addObject:[[contentTitle
stringByReplacingOccurrencesOfString:@"&"
withString:@"&"] mutableCopy]];
[self.contentNidArray addObject:contentNid];
[self.contentBodyArray addObject:contentBody];
}
}
[self.tableView reloadData];
[DSBezelActivityView removeViewAnimated:YES];
[myRawJson release];
}
Tôi đang cấu hình di động tại cellForRowAtIndexPath (Cập nhật: văn toàn bộ phương pháp):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
}
// Configure the cell.
cell.textLabel.text = [self.contentTitleArray objectAtIndex: [indexPath row]];
cell.detailTextLabel.text = [self.contentNidArray objectAtIndex: [indexPath row]];
return cell;
}
Đặt nó trên didSelectRowAtIndexPath:
self.detailViewController.currentNodeTitle = [contentTitleArray
objectAtIndex:indexPath.row];
self.detailViewController.currentNodeNid= [contentNidArray
objectAtIndex:indexPath.row];
self.detailViewController.currentNodeBody = [contentBodyArray
objectAtIndex:indexPath.row];
Vì vậy, khi nhấn nút refresh của tôi bảng nên * làm mới với json mới, nhưng không .. Tôi có thiếu một bước?
Ngoài này có thể không quan trọng, nhưng tôi thay đổi màu sắc cho mỗi hàng khác với:
// Customize the appearance of table view cells.
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 2)
{
[cell setBackgroundColor:[UIColor colorWithRed:221.0/255.0 green:238.0/255.0 blue:255.0/255.0 alpha:1]];
cell.textLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];
cell.detailTextLabel.textColor = [UIColor colorWithRed:2.0/255.0 green:41.0/255.0 blue:117.0/255.0 alpha:1];
} else [cell setBackgroundColor:[UIColor clearColor]];
}
Cập nhật
Tôi sẽ nghi ngờ một số vấn đề với 'cellForRowAtIndexPath:' mà bạn đã dán chỉ một đoạn nhỏ. – Krizz
@Krizz - Tôi đã thêm toàn bộ cellForRowAtIndexPath của mình. Tôi đã không đăng toàn bộ phương pháp vì nó hoàn toàn tiêu chuẩn ngoại trừ những gì tôi đã thêm vào. - Cảm ơn – Pat
Bạn đã xác minh với trình gỡ lỗi '[self.tableView reloadData];' đang đạt được và 'tableView' không phải là nil? – Krizz