mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-03-28 23:58:50 +08:00
[New Example] 500pxgram
- added UIActivityMonitor - added simple NSCache for UIKit tab
This commit is contained in:
@@ -64,15 +64,16 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
// UITabBarControllerDelegate
|
||||
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
|
||||
#pragma mark - UITabBarControllerDelegate
|
||||
|
||||
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
|
||||
{
|
||||
if ([viewController isKindOfClass:[UINavigationController class]]) {
|
||||
NSArray *viewControllers = [(UINavigationController *)viewController viewControllers];
|
||||
UIViewController *rootViewController = viewControllers[0];
|
||||
if ([rootViewController conformsToProtocol:@protocol(PhotoFeedControllerProtocol)]) {
|
||||
// FIXME: the dataModel does not currently handle clearing data during loading properly
|
||||
// [(id <PhotoFeedViewControllerProtocol>)rootViewController resetAllData];
|
||||
// [(id <PhotoFeedControllerProtocol>)rootViewController resetAllData];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
NSUInteger _totalItems;
|
||||
BOOL _fetchPageInProgress;
|
||||
BOOL _refreshFeedInProgress;
|
||||
|
||||
CLLocationCoordinate2D _location;
|
||||
NSURLSessionDataTask *_task;
|
||||
|
||||
CLLocationCoordinate2D _location;
|
||||
NSUInteger _locationRadius;
|
||||
NSUInteger _userID;
|
||||
}
|
||||
@@ -123,7 +124,12 @@
|
||||
- (void)clearFeed
|
||||
{
|
||||
_photos = [[NSMutableArray alloc] init];
|
||||
_ids = [[NSMutableArray alloc] init];
|
||||
_ids = [[NSMutableArray alloc] init];
|
||||
_currentPage = 0;
|
||||
_fetchPageInProgress = NO;
|
||||
_refreshFeedInProgress = NO;
|
||||
[_task cancel];
|
||||
_task = nil;
|
||||
}
|
||||
|
||||
- (void)requestPageWithCompletionBlock:(void (^)(NSArray *))block numResultsToReturn:(NSUInteger)numResults
|
||||
@@ -185,7 +191,7 @@
|
||||
NSString *urlAdditions = [NSString stringWithFormat:@"&page=%lu&rpp=%lu%@", (unsigned long)nextPage, (long)numPhotos, imageSizeParam];
|
||||
NSURL *url = [NSURL URLWithString:[_urlString stringByAppendingString:urlAdditions]];
|
||||
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
|
||||
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||||
_task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||||
if (data) {
|
||||
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
|
||||
|
||||
@@ -223,8 +229,8 @@
|
||||
}
|
||||
_fetchPageInProgress = NO;
|
||||
});
|
||||
}]; // end task
|
||||
[task resume];
|
||||
}];
|
||||
[_task resume];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
|
||||
@implementation PhotoFeedNodeController
|
||||
{
|
||||
PhotoFeedModel *_photoFeed;
|
||||
ASTableNode *_tableNode;
|
||||
PhotoFeedModel *_photoFeed;
|
||||
ASTableNode *_tableNode;
|
||||
UIActivityIndicatorView *_activityIndicatorView;
|
||||
}
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
@@ -35,12 +36,10 @@
|
||||
self.navigationItem.title = @"ASDK";
|
||||
[self.navigationController setNavigationBarHidden:YES];
|
||||
|
||||
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular
|
||||
imageSize:[self imageSizeForScreenWidth]];
|
||||
[self refreshFeed];
|
||||
|
||||
_tableNode.dataSource = self;
|
||||
_tableNode.delegate = self;
|
||||
|
||||
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -51,20 +50,35 @@
|
||||
{
|
||||
[super loadView];
|
||||
|
||||
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular imageSize:[self imageSizeForScreenWidth]];
|
||||
[self refreshFeed];
|
||||
|
||||
CGSize boundSize = self.view.bounds.size;
|
||||
|
||||
[_activityIndicatorView sizeToFit];
|
||||
CGRect refreshRect = _activityIndicatorView.frame;
|
||||
refreshRect.origin = CGPointMake((boundSize.width - _activityIndicatorView.frame.size.width) / 2.0,
|
||||
(boundSize.height - _activityIndicatorView.frame.size.height) / 2.0);
|
||||
_activityIndicatorView.frame = refreshRect;
|
||||
|
||||
[self.view addSubview:_activityIndicatorView];
|
||||
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
_tableNode.view.allowsSelection = NO;
|
||||
_tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
_tableNode.view.leadingScreensForBatching = AUTO_TAIL_LOADING_NUM_SCREENFULS; // overriding default of 2.0
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - helper methods
|
||||
|
||||
- (void)refreshFeed
|
||||
{
|
||||
[_activityIndicatorView startAnimating];
|
||||
// small first batch
|
||||
[_photoFeed refreshFeedWithCompletionBlock:^(NSArray *newPhotos){
|
||||
|
||||
[_activityIndicatorView stopAnimating];
|
||||
|
||||
[self insertNewRowsInTableView:newPhotos];
|
||||
[self requestCommentsForPhotos:newPhotos];
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
|
||||
@implementation PhotoFeedViewController
|
||||
{
|
||||
PhotoFeedModel *_photoFeed;
|
||||
UITableView *_tableView;
|
||||
PhotoFeedModel *_photoFeed;
|
||||
UITableView *_tableView;
|
||||
UIActivityIndicatorView *_activityIndicatorView;
|
||||
}
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
@@ -38,8 +39,7 @@
|
||||
_tableView.delegate = self;
|
||||
_tableView.dataSource = self;
|
||||
|
||||
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular imageSize:[self imageSizeForScreenWidth]];
|
||||
[self refreshFeed];
|
||||
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -50,19 +50,38 @@
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
_photoFeed = [[PhotoFeedModel alloc] initWithPhotoFeedModelType:PhotoFeedModelTypePopular imageSize:[self imageSizeForScreenWidth]];
|
||||
[self refreshFeed];
|
||||
|
||||
CGSize boundSize = self.view.bounds.size;
|
||||
|
||||
[self.view addSubview:_tableView];
|
||||
|
||||
_tableView.frame = self.view.bounds;
|
||||
_tableView.allowsSelection = NO;
|
||||
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
[_tableView registerClass:[PhotoTableViewCell class] forCellReuseIdentifier:@"photoCell"];
|
||||
|
||||
[self.view addSubview:_activityIndicatorView];
|
||||
|
||||
[_activityIndicatorView sizeToFit];
|
||||
CGRect refreshRect = _activityIndicatorView.frame;
|
||||
refreshRect.origin = CGPointMake((boundSize.width - _activityIndicatorView.frame.size.width) / 2.0,
|
||||
(boundSize.height - _activityIndicatorView.frame.size.height) / 2.0);
|
||||
_activityIndicatorView.frame = refreshRect;
|
||||
}
|
||||
|
||||
#pragma mark - helper methods
|
||||
|
||||
- (void)refreshFeed
|
||||
{
|
||||
[_activityIndicatorView startAnimating];
|
||||
|
||||
// small first batch
|
||||
[_photoFeed refreshFeedWithCompletionBlock:^(NSArray *newPhotos){
|
||||
|
||||
[_activityIndicatorView stopAnimating];
|
||||
|
||||
[self insertNewRowsInTableView:newPhotos];
|
||||
[self requestCommentsForPhotos:newPhotos];
|
||||
|
||||
|
||||
@@ -437,11 +437,9 @@
|
||||
rect.size = [_photoDescriptionLabel sizeThatFits:CGSizeMake(availableWidth, CGFLOAT_MAX)];
|
||||
_photoDescriptionLabel.frame = rect;
|
||||
|
||||
[[PINRemoteImageManager sharedImageManager] downloadImageWithURL:photo.URL
|
||||
options:PINRemoteImageManagerDownloadOptionsSkipDecode
|
||||
completion:^(PINRemoteImageManagerResult * _Nonnull result) {
|
||||
_photoImageView.image = result.image;
|
||||
}];
|
||||
[UIImage downloadImageForURL:photo.URL completion:^(UIImage *image) {
|
||||
_photoImageView.image = image;
|
||||
}];
|
||||
|
||||
[self downloadAndProcessUserAvatarForPhoto:photo];
|
||||
[self loadCommentsForPhoto:photo];
|
||||
@@ -467,15 +465,10 @@
|
||||
|
||||
- (void)downloadAndProcessUserAvatarForPhoto:(PhotoModel *)photo
|
||||
{
|
||||
[[PINRemoteImageManager sharedImageManager] downloadImageWithURL:_photoModel.ownerUserProfile.userPicURL
|
||||
options:PINRemoteImageManagerDownloadOptionsSkipDecode
|
||||
processorKey:@"custom"
|
||||
processor:^UIImage * _Nullable(PINRemoteImageManagerResult * _Nonnull result, NSUInteger * _Nonnull cost) {
|
||||
CGSize profileImageSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT);
|
||||
return [result.image makeCircularImageWithSize:profileImageSize];
|
||||
} completion:^(PINRemoteImageManagerResult * _Nonnull result) {
|
||||
_userAvatarImageView.image = result.image;
|
||||
}];
|
||||
[UIImage downloadImageForURL:photo.URL completion:^(UIImage *image) {
|
||||
CGSize profileImageSize = CGSizeMake(USER_IMAGE_HEIGHT, USER_IMAGE_HEIGHT);
|
||||
_userAvatarImageView.image = [image makeCircularImageWithSize:profileImageSize];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)reverseGeocodeLocationForPhoto:(PhotoModel *)photo
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
@interface UIImage (Additions)
|
||||
|
||||
+ (UIImage *)followingButtonStretchableImageForCornerRadius:(CGFloat)cornerRadius following:(BOOL)followingEnabled;
|
||||
+ (void)downloadImageForURL:(NSURL *)url completion:(void (^)(UIImage *))block;
|
||||
|
||||
- (UIImage *)makeCircularImageWithSize:(CGSize)size;
|
||||
|
||||
|
||||
@@ -60,6 +60,40 @@
|
||||
return followingBtnImageStretchable;
|
||||
}
|
||||
|
||||
+ (void)downloadImageForURL:(NSURL *)url completion:(void (^)(UIImage *))block
|
||||
{
|
||||
static NSCache *simpleImageCache = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
simpleImageCache = [[NSCache alloc] init];
|
||||
simpleImageCache.countLimit = 10;
|
||||
});
|
||||
|
||||
if (!block) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if image is cached
|
||||
UIImage *image = [simpleImageCache objectForKey:url];
|
||||
if (image) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
block(image);
|
||||
});
|
||||
} else {
|
||||
// else download image
|
||||
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
|
||||
NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||||
if (data) {
|
||||
UIImage *image = [UIImage imageWithData:data];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
block(image);
|
||||
});
|
||||
}
|
||||
}];
|
||||
[task resume];
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImage *)makeCircularImageWithSize:(CGSize)size
|
||||
{
|
||||
// make a CGRect with the image's size
|
||||
|
||||
Reference in New Issue
Block a user