2012-01-24 40 views
11

Tôi có UITableView từ nguồn cấp dữ liệu RSS bên ngoài.Animate Spinner khi tải trang mới

Khi bạn chọn một hàng, nó sử dụng điều hướng và các trang trình bày từ bên phải, vấn đề là nguồn cấp dữ liệu RSS chứa hình ảnh do đó có thể mất vài giây để tải và không có bất kỳ dấu hiệu nào. nó cho một vụ tai nạn ứng dụng.

Tôi quyết định thêm một spinner để bạn biết rằng trang mới đang tải.

Đây là mã của tôi:

RootViewController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
NSLog(@"Loading New Page"); 

[tableView deselectRowAtIndexPath:indexPath animated:YES]; 
DetailsViewController *detailViewController = [[DetailsViewController alloc] initWithNibName:@"DetailsViewController" bundle:nil]; 
detailViewController.item = [rssItems objectAtIndex:floor(indexPath.row/2)]; 
[self.navigationController pushViewController:detailViewController animated:YES]; 
[detailViewController release]; 

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
spinner.center = CGPointMake(160, 240); 
[self.view addSubview:spinner]; 
[spinner startAnimating]; 
[spinner release]; 

} 

DetailsViewController.m

- (void)viewDidLoad { 
    [super viewDidLoad]; 

     NSString *imgURL = [item objectForKey:@"image"]; 
     NSData *mydata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imgURL]]; 
     item_photo.image = [[UIImage alloc] initWithData:mydata]; 

    item_title.text = [item objectForKey:@"title"]; 
    item_date.text = [NSString stringWithFormat:@"Date: %@",[item objectForKey:@"date"]]; 
    item_time.text = [NSString stringWithFormat:@"Time: %@",[item objectForKey:@"time"]]; 
    item_cost.text = [NSString stringWithFormat:@"Cost: £%@",[item objectForKey:@"cost"]]; 
    item_info.text = [item objectForKey:@"description"]; 
    self.navigationItem.title = @"Event Type"; 
} 

Có hai vấn đề với mã này.

  1. Spinner không hoạt động cho đến sau khi trang mới được tải.
  2. Spinner không tắt khi nạp.

Nếu có ai có thể giúp tôi giải quyết vấn đề này, tôi sẽ thực sự biết ơn.

+0

Tôi nghĩ rằng bạn vẫn đang mất tích mã nơi sau đó xem chỉ số hoạt động bị ngừng/gỡ bỏ. Ngoài ra: làm thế nào bạn tải các hình ảnh? Nếu bạn đang sử dụng phương pháp chặn (tức là phương thức không chạy trong chuỗi nền), toàn bộ vòng lặp chính của bạn sẽ bị chặn có nghĩa là: không có tương tác người dùng, không hoạt ảnh vv (sẽ giải thích hành vi này). Nếu đây là trường hợp bạn thực sự nên chuyển sang tải không đồng bộ. –

+0

@TriPhoenix Làm thế nào để bạn biết nếu nó là một phương pháp chặn hay không? tôi đã thêm vào mã trên DetailsViewController.m –

+0

Bạn có thể biết cách hoạt động của hàm: các hàm chặn sẽ trả về giá trị ngay lập tức, trong trường hợp này 'initWithContentsOfURL' sẽ đặt dữ liệu vào trong' NSData'so của bạn, hàm funciton không thể trả về trước khi trả lại dữ liệu này. Các yêu cầu không đồng bộ phức tạp hơn theo nghĩa là bạn bắt đầu yêu cầu và sẽ không có kết quả trả về mà đúng hơn là yêu cầu sẽ gọi hàm gọi lại trên mã của bạn khi nó được hoàn tất. Có một số khung công tác như ASIHTTPRequest giúp dễ dàng hơn hoặc bạn có thể sử dụng NSURLConnection và tự làm điều đó. –

Trả lời

23

Bạn đang thêm quan điểm chỉ số hoạt động cho quan điểm của bộ điều khiển được đẩy điều khiển xem chi tiết, vì vậy bạn sẽ không nhìn thấy nó anyway

thử di chuyển nhóm thứ hai của mã để phương pháp viewDidLoad của DetailsViewController, bạn có thể gọi stopAnimating trên chỉ báo hoạt động khi bạn tải xong. Để có tham chiếu đến UIActivityIndicator, bạn nên thêm thẻ

ví dụ: trong viewDidLoad

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
spinner.center = CGPointMake(160, 240); 
spinner.tag = 12; 
[self.view addSubview:spinner]; 
[spinner startAnimating]; 
[spinner release]; 

trong phương pháp loadingFinished (phương pháp nào được gọi khi tải xong)

[[self.view viewWithTag:12] stopAnimating]; 
+0

Điều này không hoạt động vì DetailsViewController không 'hiển thị' cho đến khi tất cả thông tin được tải xong. –

+0

chế độ xem chi tiết không hiển thị vì bạn đang tải dữ liệu một cách đồng bộ, sẽ chặn luồng. bạn cần thực hiện yêu cầu này dưới nền nếu bạn muốn hiển thị chỉ báo hoạt động hoạt ảnh – wattson12

+0

và bạn sẽ làm như thế nào? –

3

Bạn cần phải làm một số công việc trong một thread nền. Nếu dòng sau là một trong đó mất thời gian:

detailViewController.item = [rssItems objectAtIndex:floor(indexPath.row/2)]; 

Sau đó, bạn có thể làm điều này trong nền với GCD:

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 

dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
    // This is the operation that blocks the main thread, so we execute it in a background thread 
    id item = [rssItems objectAtIndex:floor(indexPath.row/2)]; 

     // UIKit calls need to be made on the main thread, so re-dispatch there 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      detailViewController.item = item; 
      [spinner stopAnimating]; 
     }); 
}); 

Và 1 đến @ wattson12 - bạn cần phải thêm các spinner sang chế độ xem mới thay thế. Ngoài ra, bạn có thể thêm spinner vào chế độ xem hiện tại và thay vào đó, hãy đặt lệnh gọi pushViewController vào khối xếp hàng chính GCD của bạn.

Điểm cuối cùng - bạn sẽ muốn xóa spinner khỏi trình giám sát của nó sau khi bạn ngừng hoạt ảnh. Ngoài ra, bạn có thể có một phiên bản của spinner và đặt hidesWhenStopped thành YES.

0

Đây là một bánh xe quay tròn trên một cái nhìn mờ trong nhanh chóng:

func blurScence(){ 
    let blurEffect: UIBlurEffect = UIBlurEffect(style: .Dark) 
    let blurView: UIVisualEffectView = UIVisualEffectView(effect: blurEffect) 
    blurView.translatesAutoresizingMaskIntoConstraints = false 
    blurView.frame = self.view.frame 

    let spinner = UIActivityIndicatorView(activityIndicatorStyle:.White) 
    spinner.center=blurView.center 
    blurView.addSubview(spinner) 
    spinner.startAnimating() 

    self.view.addSubview(blurView) 
} 
Các vấn đề liên quan