Ios 视图重新打开后恢复进度栏
在我的应用程序中,我有一个UIViewController,带有一个UIProgressView和一个开始下载AFNetworking库的按钮。 在viewController关闭然后重新打开后,如何恢复下载进度条 这是我的代码: ViewController.mIos 视图重新打开后恢复进度栏,ios,objective-c,uiviewcontroller,afnetworking,Ios,Objective C,Uiviewcontroller,Afnetworking,在我的应用程序中,我有一个UIViewController,带有一个UIProgressView和一个开始下载AFNetworking库的按钮。 在viewController关闭然后重新打开后,如何恢复下载进度条 这是我的代码: ViewController.m [...] - (void) updateProgress:(float)progress forOperation:(AFHTTPRequestOperation *)operation { self.downloa
[...]
- (void) updateProgress:(float)progress forOperation:(AFHTTPRequestOperation *)operation {
self.downloadprogress.progress = progress;
}
- (void)downloadTest:(NSString *)cid
{
NSString *string = [NSString stringWithFormat:@"%@get_new.php?c=%@", BaseURLString, cid];
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip", cid]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
__weak typeof(operation)weakOperation = operation;
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
__strong __typeof(weakOperation)strongOperation = weakOperation;
//NSLog(@"Progress = %f", (float)totalBytesRead / totalBytesExpectedToRead );
float progressValue = (float)totalBytesRead / totalBytesExpectedToRead;
[self updateProgress:progressValue forOperation:strongOperation];
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// DOWNLOAD OK
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// DOWNLOAD ERROR
}];
[operation start];
}
[...]
NSString* const kStartDownloadNotificationName = @"StartDownloadNotificationName";
NSString* const kStartDownloadNotificationParamCid = @"StartDownloadNotificationParamCid";
@interface AppDelegate ()
@property (strong, nonatomic) AFHTTPRequestOperation* downloadOperation;
- (void)startDownloadOperationWithNotification:(NSNotification*)notification;
@end
@implementation AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startDownloadOperationWithNotification:)
name:kStartDownloadNotificationName
object:nil];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kStartDownloadNotificationName
object:nil];
}
- (void)startDownloadOperationWithNotification:(NSNotification*)notification
{
NSString* cid = notification.userInfo[kStartDownloadNotificationParamCid];
if (cid == nil) {
return;
}
NSString *string = [NSString stringWithFormat:@"%@get_new.php?c=%@", BaseURLString, cid];
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip", cid]];
self.downloadOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
self.downloadOperation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
__weak typeof(self.downloadOperation)weakOperation = self.downloadOperation;
[self.downloadOperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
__strong __typeof(weakOperation)strongOperation = weakOperation;
//NSLog(@"Progress = %f", (float)totalBytesRead / totalBytesExpectedToRead );
self.currentDownloadProgressValue = (float)totalBytesRead / totalBytesExpectedToRead;
}];
[self.downloadOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// DOWNLOAD OK
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// DOWNLOAD ERROR
}
];
[self.downloadOperation start];
}
@end
ViewController.h
@interface InfoViewController : UIViewController{
IBOutlet UITextView *txtinfo;
IBOutlet UIBarButtonItem *btnDown;
}
@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;
- (IBAction)downloadBtn:(id)sender;
@end
extern NSString* const kStartDownloadNotificationName;
extern NSString* const kStartDownloadNotificationParamCid;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic) float currentDownloadProgressValue;
@end
@interface InfoViewController : UIViewController{
IBOutlet UITextView *txtinfo;
IBOutlet UIBarButtonItem *btnDown;
}
@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;
- (IBAction)downloadBtn:(id)sender;
@end
试着这样做:
- (void)downloadTest:(NSString *)cid
{
NSString *string = [NSString stringWithFormat:@"%@get_new.php?c=%@", BaseURLString, cid];
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.zip", cid]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicatorView.hidesWhenStopped = YES;
[activityIndicatorView startAnimating];
activityIndicatorView.center = self.view.center;
[self.view addSubview:activityIndicatorView];
__weak typeof(operation)weakOperation = operation;
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
__strong __typeof(weakOperation)strongOperation = weakOperation;
//NSLog(@"Progress = %f", (float)totalBytesRead / totalBytesExpectedToRead );
float progressValue = (float)totalBytesRead / totalBytesExpectedToRead;
[self updateProgress:progressValue forOperation:strongOperation];
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// DOWNLOAD OK
[activityIndicatorView stopAnimating];
[activityIndicatorView removeFromSuperview];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// DOWNLOAD ERROR
if (!error)
{
}
[activityIndicatorView stopAnimating];
[activityIndicatorView removeFromSuperview];
}];
[operation start];
}
作为额外的奖励,我建议您将活动指标分配到其他地方(-init
),这样您就不必继续重新分配。此外,一次分配更脆弱(以一种好的方式),而且内存管理实践也更好
另外,我做了很多假设,关于你将指标放在什么视图(和框架)中。相应地调整
干杯我没用过网络,所以也许我错了;但对我来说,由于取消分配
操作
对象,在退出downloadTest:
方法后,您的代码下载似乎将停止
要解决此问题,请使用属性或某些非局部范围变量。但是,如果您想在销毁视图控制器之后继续下载,则需要使用应用程序生命周期中存在的对象
例如,它可能是AppDelegate
的属性。在这种情况下,当前下载进度也是AppDelegate
的属性。使用这种方法,在InfoViewController
的viewDidLoad:
方法中,您可以请求当前下载大小,并用相应的值更新进度条。此外,要在显示视图控制器时更新当前下载进度,您可以订阅表示当前下载进度的AppDelegate
属性值的更新(使用KVO)
请参见下面这种方法的示例
AppDelegate.h
@interface InfoViewController : UIViewController{
IBOutlet UITextView *txtinfo;
IBOutlet UIBarButtonItem *btnDown;
}
@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;
- (IBAction)downloadBtn:(id)sender;
@end
extern NSString* const kStartDownloadNotificationName;
extern NSString* const kStartDownloadNotificationParamCid;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic) float currentDownloadProgressValue;
@end
@interface InfoViewController : UIViewController{
IBOutlet UITextView *txtinfo;
IBOutlet UIBarButtonItem *btnDown;
}
@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;
- (IBAction)downloadBtn:(id)sender;
@end
ViewController.h
@interface InfoViewController : UIViewController{
IBOutlet UITextView *txtinfo;
IBOutlet UIBarButtonItem *btnDown;
}
@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;
- (IBAction)downloadBtn:(id)sender;
@end
extern NSString* const kStartDownloadNotificationName;
extern NSString* const kStartDownloadNotificationParamCid;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic) float currentDownloadProgressValue;
@end
@interface InfoViewController : UIViewController{
IBOutlet UITextView *txtinfo;
IBOutlet UIBarButtonItem *btnDown;
}
@property (weak, nonatomic) IBOutlet UIProgressView *downloadprogress;
- (IBAction)downloadBtn:(id)sender;
@end
ViewController.m
[……]
- (void)viewDidLoad
{
[super viewDidLoad];
// ...
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
[self updateProgress:appDelegate.currentDownloadProgressValue];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear];
// ...
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate addObserver:self
forKeyPath:@"currentDownloadProgressValue"
options:NSKeyValueObservingOptionNew
context:NULL];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear];
// ...
AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
[appDelegate removeObserver:self
forKeyPath:@"currentDownloadProgressValue"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqual:@"currentDownloadProgressValue"]) {
NSNumber* currentProgressObj = [change objectForKey:NSKeyValueChangeNewKey];
[self updateProgress:[currentProgressObj floatValue]];
}
}
- (void)updateProgress:(float)progress
{
self.downloadprogress.progress = progress;
}
- (void)downloadTest:(NSString *)cid
{
[[NSNotificationCenter defaultCenter] postNotificationName:kStartDownloadNotificationName
object:nil
userInfo:@{ kStartDownloadNotificationParamCid : cid }];
}
[...]
p.S.抱歉,我没有检查此代码的生成或运行时错误。看起来您到目前为止还没有尝试过任何操作。您是否可以显示在视图控制器的二次加载上查找操作和更新进度值的尝试?我通常将所有网络代码放在自己的类中,并发送一个NSNotification,其中包含进度,我可以从任何视图控制器捕获进度,并对其执行任何操作。@AaronBrager我没有尝试过。。我不是objective-c:PAwesome方面的专家,我曾经尝试使用ShareInstance来保存currentProgressValue。然后通过委托进行写作。你提供了一个很好的解决方案。