6

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?

enter image description here

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

enter image description here

+0

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

+0

@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

+0

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

Trả lời

5

Bạn cần để gọi phương thức tải lại.

[self.tableView reloadData]; 

này sẽ cháy các dataSourcedelegate sự kiện một sẽ làm mới UITableView.

Bạn có thể tìm thêm thông tin trong UITableView Class Reference:

Gọi phương pháp này để tải lại tất cả các dữ được sử dụng để xây dựng bảng, bao gồm cả pin, tiêu đề mục và footers, mảng chỉ mục, và vân vân. Để có hiệu quả, chế độ xem bảng sẽ chỉ hiển thị lại những hàng có thể nhìn thấy được.

+1

Vâng đây là những gì nhiều bài viết khác đã nói, nhưng khi tôi thêm [self.tableView reloadData]; đến cuối - (IBAction) làm mới: (id) người gửi, nó không có hiệu lực. Bất kỳ ý tưởng nào khác? Hoặc có lẽ tôi chỉ gọi nó ở sai chỗ? – Pat

+0

Tôi đã cập nhật bài đăng của mình để bao gồm mã IBAction và một số thông tin khác. Có lẽ tôi đang thiếu một số mã? Tôi có thể xác minh rằng JSON đã thay đổi bằng cách chạy ứng dụng, sau đó cập nhật nguồn JSON và khi tôi nhấp vào nút "làm mới", NSLog của tôi cho thấy nút được làm mới sẽ xuất ra nội dung mới nhưng các ô không cập nhật. – Pat