Reputation: 11175
I have a share button in a UITableViewCell
action which pulls up a UIActivityViewController
. This works absolutely fine, apart from the fact that I'm loading an image from Parse, and as the image is fairly high resolution, can make the UIActivityViewController
slow to appear. I have added a UIActivityIndicator
to the navigation bar to notify the user that something in loading, but it still isn't the best user experience.
I was wondering if there is anyway that I can make the UIActivityViewController
appear straight away while simultaneously loading the image in the background so that it is added to the share when it is loaded? Either that or is there a way to start loading the image as soon as the user swipes the UITableViewCell
?
If anyone has any other suggestions, then they would be much appreciated!
Thanks!
EDIT:
Here is the code I have:
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
let imageURL = NSURL(string: DataManager.sharedInstance.getRideByName(cell.rideNameLabel.text!)!.rideImage!)
let imageData = NSData(contentsOfURL: imageURL!)
dispatch_async(dispatch_get_main_queue()) {
let image = UIImage(data: imageData!)
let text = "I've just been to '\(cell.rideNameLabel.text!)' at \(self.parkPassed.name!)!"
let appURL = NSURL(string: "http://itunes.apple.com/app/1021402097")
let objectsToShare = [text, image!, appURL!]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.excludedActivityTypes = [UIActivityTypeAddToReadingList, UIActivityTypeAssignToContact, UIActivityTypeCopyToPasteboard, UIActivityTypePostToFlickr, UIActivityTypePostToTencentWeibo, UIActivityTypePostToVimeo, UIActivityTypePostToWeibo, UIActivityTypePrint, UIActivityTypeSaveToCameraRoll]
self.presentViewController(activityVC, animated: true, completion: nil)
self.navigationItem.titleView = nil
}
}
Upvotes: 1
Views: 553
Reputation: 3468
You can use Parse's PFImageView which uses a placeholder image that is stored locally. So the view will load immediately and once your controller has finished initializing you can tell Parse to load the image in the background and it should do the rest for you.
PFImageView *creature = [[PFImageView alloc] init];
creature.image = [UIImage imageNamed:@”1.jpg”]; // placeholder image
creature.file = (PFFile *)file;
[creature loadInBackground];
See this link for more details.
EDIT
Additionally just about every Parse action has a download in background with completion block version. You can download the image in the background and set the image in the completion block.
I'm not seeing any Parse references in your code, but it looks like it might be inside your DataManager. What it looks like you are doing is downloading the data first in the background, then upon completion you are presenting the UIActivityViewController.
Instead what I would do is create a custom UIActivityViewController, you would use it the same way except you would set image to be a placeholder image and create a custom property to hold the Image URL you wish to load. Then in onViewDidAppear of your custom UIActivityViewController you can start a PFQuery or some other Async task to download the image data in the background and upon completion you can load the real image and dismiss any UIActivityIndictators you may be showing.
PFQuery *query = [PFQuery queryWithClassName:@"myImages"];
[query whereKey:@"imageName" equalTo:@"your_image.jpg"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(@"Successfully retrieved %d images.", objects.count);
// Do something with the found objects
for (PFObject *object in objects) {
NSLog(@"%@", object.objectId);
}
} else {
// Log details of the failure
NSLog(@"Error: %@ %@", error, [error userInfo]);
}
}];
See this question for more details on downloading a Image using a PFQuery.
Upvotes: 2