I'm using the AFNetworking library to set images with the contents of URLs. In the following example topLeftImage is an instance of a UIImageView.
[topLeftImage setImageWithURL:[NSURL URLWithString:imageURL]];
What I'd like to do is to show a UIActivityIndicatorView while the image is downloading. However I can't figure where to trigger the starting and stopping of the activity indicator. The following is my code for the activity indicator.
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[topLeftImage addSubview:activityIndicator];
[activityIndicator startAnimating];
How can I link the above code to the setImageWithURL method so that activity indicator appears only while the image is downloading?
UIImageView+AFNetworking.h category provides a setImageWithURL method that allows you to use success and failure blocks. This blocks will be executed once the request finishes in success or fail. So you can start the animation just before the request and put the stop in success and fail blocks. This is a sample code:
NSURL *imageURL = [NSURL URLWithString:#"http://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/402px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg"];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:imageURL];
[_activityIndicator setHidden:NO];
[_activityIndicator startAnimating];
[_imageView setImageWithURLRequest:imageRequest
placeholderImage:nil
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image)
{
[_activityIndicator setHidden:YES];
[_activityIndicator stopAnimating];
_imageView.image = image;
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error)
{
[_activityIndicator setHidden:YES];
[_activityIndicator stopAnimating];
}];
Simple extension for UIImageView in Swift:
extension UIImageView {
func setImageWithString(string: String?) {
if let string = string, let url = NSURL(string: string) {
let activityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)))
activityIndicatorView.hidden = false
activityIndicatorView.color = UIColor.lightGrayColor()
addSubview(activityIndicatorView)
bringSubviewToFront(activityIndicatorView)
activityIndicatorView.startAnimating()
setImageWithURLRequest(NSURLRequest(URL: url), placeholderImage: nil, success: { request, response, image in
self.image = image
activityIndicatorView.hidden = true
activityIndicatorView.stopAnimating()
activityIndicatorView.removeFromSuperview()
}, failure: { request, response, error in
activityIndicatorView.hidden = true
activityIndicatorView.stopAnimating()
activityIndicatorView.removeFromSuperview()
})
}
}
}
Related
I have cobbled together some methods to resize images and put them into a UIScrollView for horizontal scrolling, however one of my problems is that I'm capturing strongly, and I have attempted a few options that I have read about, but all result in no images being displayed. I'm hoping one of you can help me resolve this issue so I can quit cooking so much memory when my app loads the images into the scroll view.
- (void)setImage:(NSURL *)imageURL errorImage:(UIImage *)errorImage{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:imageURL];
[request addValue:#"image/*" forHTTPHeaderField:#"Accept"];
UIImageView *newView = [[UIImageView alloc] initWithFrame: CGRectMake(self.x, 0, self.screenWidth, self.screenHight)];
[self.scrollView addSubview: newView];
self.x = (self.x + newView.frame.size.width);
if(self.x > self.view.frame.size.width) {
self.scrollView.contentSize = CGSizeMake(self.x, self.scrollView.frame.size.height);
}
[[newView subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)]; // Remove previous that not stop
__block UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] init];
activityIndicator.frame = newView.bounds;
[activityIndicator setHidden:NO];
[activityIndicator startAnimating];
activityIndicator.color = [UIColor redColor];
[newView addSubview:activityIndicator];
void (^removeSpinner)(void) = ^{ // Desctuctor Block
if (activityIndicator) {
[activityIndicator setHidden:YES];
[activityIndicator stopAnimating];
[activityIndicator removeFromSuperview];
activityIndicator = nil;
}
};
[newView setImageWithURLRequest:request placeholderImage:nil success: ^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
removeSpinner();
// resize the resulting image for this device
newView.image = [self imageScaleCropToSize:image];
NSLog(#"successfully loaded image: %#", imageURL);
} failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
removeSpinner();
NSLog(#"failed loading [%#]: %#", imageURL, error);
}];
}
i want to use afnetworking method to download and show image into imageview.
another step is i want to save all image in case of user open application in offline mode.
there is a few article on SO that give method on how to use UrlCache and cache variable in url header.
with background of developing in android is there any way to make Afnetworking works like Imageloader
solution in android ? (saving file into program or document folder and retrive in offline mode)
this is my code for showing images in uicolleciotn view :
if (![appRecord.thumb_url isEqualToString:#""])
{
[myCell.imageView setImageWithURL:[NSURL URLWithString:appRecord.thumb_url] placeholderImage:[UIImage imageNamed:#"white.png"]];
__weak UIImageView *weakImageView = myCell.imageView;
NSURLRequest *request1 = [NSURLRequest requestWithURL:[NSURL URLWithString:appRecord.thumb_url]];
[myCell.imageView setImageWithURLRequest:request1
placeholderImage:[UIImage imageNamed:#"white.png"]
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
UIImageView *strongImageView = weakImageView; // make local strong reference to protect against race conditions
if (!strongImageView) return;
[UIView transitionWithView:strongImageView
duration:0.3
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
strongImageView.image = image;
}
completion:NULL];
}
failure:NULL];
}
after changing the code due to luvacu suggestion :
adding this to header :
#property (nonatomic, strong) NSURLRequest *strongRequest1;
and :
__block UIImageView *weakImageView = myCell.imageView;
NSURLRequest *request1 = [NSURLRequest requestWithURL:[NSURL URLWithString:appRecord.thumb_url]];
__block NSURLRequest *weakRequest1 = request1;
[myCell.imageView setImageWithURLRequest:request1
placeholderImage:[UIImage imageNamed:#"white.png"]
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
UIImageView *strongImageView = weakImageView; // make local strong reference to protect against race conditions
if (!strongImageView) {
return;
}
[UIView transitionWithView:strongImageView
duration:0.3
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
strongImageView.image = image;
}
completion:NULL];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSURLRequest *strongRequest = weakRequest1;
UIImageView *strongImageView = weakImageView;
UIImage *cachedImage = [[UIImageView sharedImageCache] cachedImageForRequest:strongRequest];
if (cachedImage) {
[UIView transitionWithView:strongImageView
duration:0.3
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
strongImageView.image = cachedImage;
}
completion:NULL];
}
}];
still no iamge apear after making program offline.
AFNetworking's category UIImageView+AFNetworking includes a NSCache for each image URL request. Try to load a cached image for that request, when the request fails.
__block UIImageView *weakImageView = myCell.imageView;
NSURLRequest *request1 = [NSURLRequest requestWithURL:[NSURL URLWithString:appRecord.thumb_url]];
__block NSURLRequest *weakRequest1 = request1;
[myCell.imageView setImageWithURLRequest:request1
placeholderImage:[UIImage imageNamed:#"white.png"]
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
UIImageView *strongImageView = weakImageView; // make local strong reference to protect against race conditions
if (!strongImageView) {
return;
}
[UIView transitionWithView:strongImageView
duration:0.3
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
strongImageView.image = image;
}
completion:NULL];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSURLRequest *strongRequest = weakRequest1;
UIImage *cachedImage = [[UIImageView sharedImageCache] cachedImageForRequest:strongRequest]
if (cachedImage) {
[UIView transitionWithView:strongImageView
duration:0.3
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
strongImageView.image = cachedImage;
}
completion:NULL];
}
}];
Also, you are loading the image twice. Remove the first one:
[myCell.imageView setImageWithURL:[NSURL URLWithString:appRecord.thumb_url] placeholderImage:[UIImage imageNamed:#"white.png"]];
I am using DBChooser in my application to import images from dropbox, I am getting image url like & to dasplay the image in UIImageView i have following code
UIImageView *imageView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)];
imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"https://www.dropbox.com/s/7qey2let40eb9je/PRELIMINARY_FORM_2.jpg"]]];
[self.view addSubview:imageView];
but the image is not showing in application. please help me how to display the dropbox image in UIImageView, is it issue of https OR what .
See this reference: https://cantonbecker.com/etcetera/2014/how-to-directly-link-or-embed-dropbox-images/
Short answer: append raw=1 as querystring value to your image url
Let's try:
+ (void) downloadImage : (NSURL*) url withCallBack:(DownloadCallbackBlock)callback
{
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSHTTPURLResponse *httpresponse = (NSHTTPURLResponse *)response;
if (httpresponse.statusCode == 200)
{
callback(error,data);
}
else
{
//error
}
}];
}
And I use it:
[DownloadManager downloadImage:url withCallBack:^(NSError *error, NSData *data){
if (data)
{
UIImage *image = [[UIImage alloc]initWithData:data];
[_arrImages addObject:image];
dispatch_async(dispatch_get_main_queue(), ^{
[self processAddImage];
});
}
I want to first create imageview onto the scroll view.there i set placeholder image or give Background color of imageview.so all image view are display.
- (void)LoadDataInScrollView
{
dispatch_queue_t imageQueue = dispatch_queue_create("Image Queue",NULL);
//totalImageGetDict into count total Number of object and generate imageview.
for (int ivalue = 0; ivalue < [totalImageGetDict count]; ivalue++)
{
dispatch_async(imageQueue, ^{
//define x value
CGFloat xOrigin =ivalue *ascrollView.frame.size.width+50;
imageView = [[UIImageView alloc] init];
imageView.tag = ivalue;
[imageView setBackgroundColor:[UIColor whiteColor]];
imageView.frame = CGRectMake(xOrigin-40,imgYpos, ascrollView.frame.size.width-20, scrollViewHight);
//then here first i set already downloaded image.it's comes from another class. getImageLoadDict into images are already downloaded**
if ([getImageLoadDict objectForKey:[NSNumber numberWithInteger:ivalue]]!= nil)
{
//dispatch_async(dispatch_get_main_queue(), ^{
[imageView setImage:[getImageLoadDict objectForKey:[NSNumber numberWithInteger:ivalue]]];
//});
}
else
{
//totalImageGetDict into remaining images object and asynchronously download here.
STVisionPhoto *photoObj = [totalImageGetDict objectForKey:[NSNumber numberWithInteger:ivalue]];
UIImage *newimage = [photoObj image];
dispatch_async(dispatch_get_main_queue(), ^{
[imageView setImage:newimage];
});
}
[ascrollView addSubview:imageView];
});
}
}
You can use SDWebImage to do it.It is pretty easy to use
Edit :
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage * image = [UIImage imageWithData:[NSData dataWithContentsOfURL:your url]];
dispatch_async(dispatch_get_main_queue(), ^{
[imgview setImage:image];
});
});
You can try this if you don't want to use any library
Try to use this code:
UIImageView *imgView = [[UIImageView alloc] init];
imgView.frame = CGRectMake(12.5, 12.5, 80, 80);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *profileImage;
profileImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:YOUR_URL_STRING]]];
dispatch_async(dispatch_get_main_queue(), ^{
imgView.image = profileImage;
});
});
[cell.contentView addSubview:imgView];
(void)loadImg:(NSString *)url img :(UIImageView *)imgView{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
__weak UIImageView *imageV = imgView;
[imgView setImageWithURLRequest:request placeholderImage:[UIImage imageNamed:#"songRecDef"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
imageV.image = image;
[imageV setNeedsLayout];
NSLog(#"%#",response);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
[imageV setImage:[UIImage imageNamed:#"songRecDef"]];
NSLog(#"%#",error);
}];
}
I am using table view to show a list of data. Each custom table cell has a back ground image coming from JSON. I use AFNetworking framework to download those image. But table view scrolling is not smooth. I create those cells using .xib file.
static NSString *CellIdentifire=#"CellId";
NSMutableDictionary *murDic=[matchListarry objectAtIndex:indexPath.row];
TTTCellFormatchList *matchListcell;
matchListcell=(TTTCellFormatchList *)[tableView dequeueReusableCellWithIdentifier:CellIdentifire];
if (matchListcell==nil)
{
NSArray *CellNib=[[NSBundle mainBundle] loadNibNamed:#"TTTCellFormatchListcontroller" owner:self options:nil];
matchListcell=(TTTCellFormatchList *)[CellNib objectAtIndex:0];
}
UIView *MainView=(UIView *)[matchListcell.contentView viewWithTag:101];
UIActivityIndicatorView *Spinner=(UIActivityIndicatorView *)[MainView viewWithTag:93];
//Clearing The back Ground
matchListcell.backgroundColor=[UIColor clearColor];
//Downlod back ground image in block and background thread
NSString *BackgroundImageStgring=[murDic valueForKey:#"MatchImage"];
UIImageView *BackgrounImage=(UIImageView *)[matchListcell.contentView viewWithTag:100];
NSURLRequest *request_img = [NSURLRequest requestWithURL:[NSURL URLWithString:BackgroundImageStgring]];
AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request_img, imageProcessingBlock:nil, success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image)
{
if(image!=nil)
{
image=[image blurredImageWithRadius:2 iterations:1 tintColor:[UIColor darkGrayColor]];
[BackgrounImage setImage:image];
[Spinner stopAnimating];
[Spinner setHidden:YES];
}
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
[[UIImage imageNamed:#"picture.png"] applyLightEffect];
[BackgrounImage setImage:[UIImage imageNamed:#"picture.png"]];
NSLog(#"Error %#",error);
}];
[operation start];
// call background queue for dynamic loading of data
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// load your dynamic data here
// call main queue here
dispatch_async(dispatch_get_main_queue(), ^{
// after loading data in background. use your downloaded data here.
});
});
Custom UITableView with UITextview is not scrolling smoothly in ios device