【问题标题】:Get download progress from different ViewController从不同的 ViewController 获取下载进度
【发布时间】:2013-04-21 11:46:23
【问题描述】:

我有一个VideoListController。它有带有下载按钮的视频列表。当我按下下载按钮时,控制权转移到DetailViewController。在DetailViewController,我正在使用AFNetworking 下载文件。

如果我从DetailViewController 回到VideoListController。我如何知道下载进度或何时从VideoListController 完成下载。我想知道这一点,因为基于此我将重新加载列表以显示播放按钮而不是下载。

【问题讨论】:

  • 我知道你要下载完整的东西,但你能告诉我,你如何在其他视图控制器中更新下载进度值

标签: iphone ios uiviewcontroller afnetworking


【解决方案1】:

我认为针对您的问题的最佳解决方案是创建一个自定义的delegate 协议,DetailViewControllerVideoListController 可以使用该协议相互通信。查看此帖子以获取更多信息How to use custom delegates in Objective-C

简而言之,策略如下: 1. DetailViewController 定义了一个 delegate protocol 用于将事件传递给它的委托 2.VideoListController 成为它知道上传进度或完成时的代表 3.VideoListController跟踪哪些DetailViewControllers完成了下载

这里是代码: DetailViewController.h:

@class DetailViewController;
@protocol Delegate <NSObject>
- (void) detailViewController: (DetailViewController *) theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful;
@end

@property (nonatomic, weak) id<DetailViewController> delegate;

DetailViewController.m: 每当下载完成时,请执行以下操作:

if ([[self delegate] respondsToSelector:@selector(detailViewController:didFinishDownloadingVideoWithResults:)]){
   [[self delegate] detailViewController:self didFinishDownloadingVideoWithResults:YES];
}

现在,在VideoListController.m 中确保您将自己确立为DetailViewController 的代表。

[theDetailViewController setDelegate:self];

并实现委托方法。例如,您可以有一个字典来定义哪些 DetailViewController 已完成下载:

   - (void) detailViewController: (DetailViewController *) theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful{
      detailViewControllersDownloadInformation[theDetailViewController] = @(successful);
}

现在,当您需要检查 DetailViewController 是否确实完成了下载时,您所要做的就是检查该字典

if (detailViewControllersDownloadInformation[theDetailViewController] && detailViewControllersDownloadInformation[theDetailViewController] == @(YES)){
    // Did download a video
}

请记住,我提供的解决方案只会让您知道下载是否已完成。如果您还想跟踪进度,则需要将其作为附加参数传递给委托。我们还假设您将所有DetailViewControllers 保存在内存中。如果您发布并重用它们,您将需要跟踪以不同数据结构下载的元素。

【讨论】:

  • 我在这里遇到错误:@property (nonatomic, weak) id delegate;我认为应该是 id 委托;是吗?
  • 我是这样实现的:@class DetailViewController; @protocol Delegate - (void) detailViewController: (DetailViewController *) theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful; @end @property (nonatomic, weak) id 委托; @end
  • 在 DetailViewController 中,当下载完成时。我添加这个: if ([[self delegate] respondsToSelector:@selector(detailViewController:didFinishDownloadingVideoWithResults:)]){ [[self delegate] detailViewController:self detailViewController:didFinishDownloadingVideoWithResults:YES];但我得到这个错误:使用未声明的标识符'didFinishDownloadingVideoWithResults'
  • 有一个错字,现在尝试使用:[[self delegate] detailViewController:self didFinishDownloadingVideoWithResults:YES];
  • 由于我收到警告,在 VideoListController 中,我添加了这样的委托:@interface RowViewController : UITableViewController 当我从 DetailViewController 回到 VideoListController 时,下载时,这个方法仍然没有被叫。 -(void) detailViewController:(DetailViewController *)theDetailViewController didFinishDownloadingVideoWithResults:(BOOL)successful { NSLog(@"Download Completed!"); }
【解决方案2】:

我使用 NSNotificationCenter 让它工作。 在DetailViewController的viewDidLoad中,我添加了这个

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(movieDownloadDidFinish)
                                             name:@"MovieDownloadDidFinishNotification"
                                           object:nil];

下载完成后。我称之为:

[[NSNotificationCenter defaultCenter] postNotificationName:@"MovieDownloadDidFinishNotification" object:self];

当点击导航控制器中的后退按钮时,我从 DetailViewController 中移除观察者

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"MovieDownloadDidFinishNotification" object:nil];

并在 DetailViewController 中添加了下载完成时调用的方法。

-(void) movieDownloadDidFinish {
    NSLog(@"MovieDownloadDidFinish on DetailViewController");
}

现在在 VideoListController 的 viewDidAppear 中,我添加了观察者

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(movieDownloadDidFinish)
                                             name:@"MovieDownloadDidFinishNotification"
                                           object:nil];

并且在 VideoListController 的 viewDidDisappear 中,我移除了观察者

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"MovieDownloadDidFinishNotification" object:nil];

并在 VideoListController 中添加了下载完成时调用的方法。

-(void) movieDownloadDidFinish {
    NSLog(@"MovieDownloadDidFinish On VideoListController");
}

这样,当 DetailViewController 可见时,会调用 DetailViewController 的方法 movieDownloadDidFinish ,类似地,当 VideoListController 可见时,会调用 VideoListController 的 movieDownloadDidFinish。

【讨论】:

    猜你喜欢
    • 2018-10-05
    • 1970-01-01
    • 2014-04-11
    • 2011-07-26
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2022-08-09
    相关资源
    最近更新 更多