我有一个我在viewDidLoad中设置的UICollectionView,并在此之后立即添加图像。当用户滚动到某一点时,我尝试添加更多图像但是集合视图不会加载新图像
如何重新加载或添加更多图像到我的滚动视图
#pragma mark - New Retrieve
- (void) rwDataToPlist {
// Step1: Get plist file path
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory ,NSUserDomainMask, YES);
NSString *documentsDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"news.plist"];
NSLog(@"Plist File Path: %@", filePath);
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
stuff = [[NSArray alloc] initWithContentsOfFile:filePath];
//NSLog(@"Stuff %@", stuff);
[self sortRetrievedData];
} else {
}
}
-(void)sortRetrievedData {
titles = [stuff valueForKey:kKeyTitle];
thumbMediaUrl = [stuff valueForKey:kKeyThumbUrl];
thumbWidth = [stuff valueForKey:kKeyThumbWidth];
thumbHeight = [stuff valueForKey:kKeyThumbHeight];
for(NSArray *array in titles) {
for (NSArray *realArray in array) {
titles = realArray;
}
}
for(NSArray *array in thumbMediaUrl) {
for(NSDictionary *dict in array) {
thumbMediaUrl = dict;
}
}
for(NSArray *array in thumbWidth) {
for(NSDictionary *dict in array) {
thumbWidth = dict;
}
}
for(NSArray *array in thumbHeight) {
for(NSDictionary *dict in array) {
thumbHeight = dict;
}
}
}
#pragma mark - Collection View
#pragma mark - Display Collection
-(void)displayCollection {
UIColor *myColor = [UIColor colorWithRed:(245.0 / 255.0) green:(245.0 / 255.0) blue:(245.0 / 255.0) alpha: 1];
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
CGRect locOfScree = CGRectMake(0, 64, screenWidth, screenHeight - 44);
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
imageDisplayer = [[UICollectionView alloc] initWithFrame:locOfScree collectionViewLayout:layout];
[imageDisplayer setDataSource:self];
[imageDisplayer setDelegate:self];
UINib *nib = [UINib nibWithNibName:@"CollectionViewCell" bundle:nil];
[imageDisplayer registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
[imageDisplayer setBackgroundColor:myColor];
[self.view insertSubview:imageDisplayer belowSubview:navBar];
//[self.view addSubview:imageDisplayer];
}
#pragma mark - Setup
- (void)setupData
{
self.imageURLStrings = [NSMutableArray array];
// Save image to docs directory so we can get a nice URL
// Not sure how to get the URL from an asset catalog off the top of my head
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"greyBurger.png"];
UIImage *image = [UIImage imageNamed:@"greyBurger"];
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
// Populate our imageURLStrings array with many paths
for (NSInteger i = 0; i < NumberOfImages; i++)
{
[self.imageURLStrings addObject:path];
//NSLog(@"Path %@", path);
}
}
- (void)setupCollectionView
{
UINib *nib = [UINib nibWithNibName:@"CollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
}
#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
//return [self.imageURLStrings count];
return [titles count];
//return 2;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
//NSLog(@"CELL FOR COUNT:%lu", [titles count]);
NSString *title = [titles objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor whiteColor];
NSString *imageUrl = [thumbMediaUrl objectForKey:title];
NSURL *thumbUrl = [NSURL URLWithString:imageUrl];
UIImageView *imageView = [[UIImageView alloc] init];
NSData *imageData = [NSData dataWithContentsOfURL:thumbUrl];
imageView.image = [UIImage imageWithData:imageData];
cell.backgroundView = imageView;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
//cell.frame = CGRectMake(0, 0, 100, 100);
//cell.imageURLString = [self.imageURLStrings objectAtIndex:indexPath.item];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
NSString *title = [titles objectAtIndex:indexPath.row];
float width = [[thumbWidth objectForKey:title] floatValue];
float height = [[thumbHeight objectForKey:title] floatValue];
float imageWidth = (screenWidth / 2) - 3;
float scale = imageWidth / width;
float imageHeight = height * scale;
CGSize imageSize = CGSizeMake(imageWidth, imageHeight);
return imageSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
// Layout: Set Edges
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// return UIEdgeInsetsMake(0,8,0,8); // top, left, bottom, right
return UIEdgeInsetsMake(0,0,0,0); // top, left, bottom, right
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray* attributesToReturn = [self layoutAttributesForElementsInRect:rect];
for (UICollectionViewLayoutAttributes* attributes in attributesToReturn)
{
if (nil == attributes.representedElementKind)
{
NSIndexPath* indexPath = attributes.indexPath;
attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;
}
}
return attributesToReturn;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes* currentItemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
if (indexPath.item < numColumns){
CGRect f = currentItemAttributes.frame;
f.origin.y = 0;
currentItemAttributes.frame = f;
return currentItemAttributes;
}
NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-numColumns inSection:indexPath.section];
CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
CGFloat YPointNew = fPrev.origin.y + fPrev.size.height + 10;
CGRect f = currentItemAttributes.frame;
f.origin.y = YPointNew;
currentItemAttributes.frame = f;
return currentItemAttributes;
}
我根据前两个答案的建议更改了我的代码,现在我必须将图像添加到正在运行的视图中。并使每列具有各自独立的高度,因此每个边缘有2px的间距,这是我尝试重新加载数据
-(void)refreshView {
[self rwDataToPlist];
[self.collectionView reloadData];
[self setupCollectionView];
}
答案 0 :(得分:2)
启动iOS6本身Apple推出了UICollectionView。您可以使用UICollectionView和Pull to Bottom Refresh来实现目标。它看起来像UITableView Pull to Bottom Refresh。
以下是UIcollectionView的一些参考:
创建UICollectionView后,您需要为UICollectionView添加PulltoBottom Refresh,如下面的代码:
-(void)viewWillAppear:(BOOL)animated
{
[self.collectionView.infiniteScrollingView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhite];
[self.collectionView addInfiniteScrollingWithActionHandler:^{
////(@"Infinitescroll");
@try {
int64_t delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//[self.dataSource addObjectsFromArray:tmp];
[self.collectionView performBatchUpdates:^{
} completion:nil];
[self.collectionView.infiniteScrollingView stopAnimating];
});
}
@catch (NSException *exception) {
}
}];
[super viewWillAppear:animated];
}
对于下面的代码,您必须添加一些文件:
答案 1 :(得分:1)
一些建议/问题:
不知道您的特定问题的限制,听起来您正在尝试显示图像网格的某些外观,并在用户滚动超过某个点时加载图像的“下一页”。看起来像UITableView或UICollectionView是一个更合适的机制来做你正在尝试做的事情。这两个类都将处理延迟加载的图像,通过正确配置的数据源进行分页,自动进行contentSize调整,并且在没有mainThread冻结的情况下将会非常快速。它们也基于MVC设计模式,可能会澄清上面代码中的一些设计。
加载更多图像时UI /滚动冻结的原因可能是由于从磁盘读取userDefaults和图像数据本身。磁盘操作可能很昂贵,尤其是一次很多。如果必须以这种方式加载元数据和图像文件,请考虑通过GCD的dispatch_async
在后台线程上执行此处理。
第二组图像未出现的原因可能是由于图像帧或scrollView contentSize误算。通过向scrollView而不是UIImageViews添加一系列彩色UIView来考虑调试,并考虑将contentSize.height硬编码为比您需要的大得多的东西。你还有NSLogged图像帧和contentSize以确保它们匹配吗?
修改强>
这是一个使用UICollectionView和后台线程的快速示例项目的链接,用于从磁盘读取UIImage数据(由于使用UICollectionView,这不再是必需的):
https://github.com/alfiehanssen/SOImageGrid
如果您有任何疑问,请告诉我,希望我的目标并不完全不合适。
答案 2 :(得分:-2)
我使用前两个答案中建议的UICollectionView并添加了CHTCollectionViewWaterfallLayout以允许我想要的图像间距
我的代码:
#pragma mark - Collection View
#pragma mark - Display Collection
-(void)displayCollection {
UIColor *myColor = [UIColor colorWithRed:(245.0 / 255.0) green:(245.0 / 255.0) blue:(245.0 / 255.0) alpha: 1];
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
CGRect locOfScree = CGRectMake(0, 44, screenWidth, screenHeight - 44);
CHTCollectionViewWaterfallLayout *layout = [[CHTCollectionViewWaterfallLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(2, 2, 2, 2);
layout.headerHeight = 0;
layout.footerHeight = 0;
layout.minimumColumnSpacing = 2;
layout.minimumInteritemSpacing = 2;
//UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
imageDisplayer = [[UICollectionView alloc] initWithFrame:locOfScree collectionViewLayout:layout];
imageDisplayer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[imageDisplayer setDataSource:self];
[imageDisplayer setDelegate:self];
UINib *nib = [UINib nibWithNibName:@"CollectionViewCell" bundle:nil];
[imageDisplayer registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
[imageDisplayer setBackgroundColor:myColor];
[self.view insertSubview:imageDisplayer belowSubview:navBar];
//[self.view addSubview:imageDisplayer];
imageDisplayer = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
imageDisplayer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageDisplayer.dataSource = self;
imageDisplayer.delegate = self;
imageDisplayer.backgroundColor = [UIColor whiteColor];
[imageDisplayer registerClass:[CHTCollectionViewWaterfallCell class]
forCellWithReuseIdentifier:CellIdentifier];
}
#pragma mark - Setup
- (void)setupCollectionView
{
UINib *nib = [UINib nibWithNibName:@"CollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
}
#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
//return [self.imageURLStrings count];
return [titles count];
//return 2;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
/*
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
*/
CHTCollectionViewWaterfallCell *cell =
(CHTCollectionViewWaterfallCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier
forIndexPath:indexPath];
NSString *title = [titles objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor whiteColor];
NSString *imageUrl = [thumbMediaUrl objectForKey:title];
NSURL *thumbUrl = [NSURL URLWithString:imageUrl];
UIImageView *imageView = [[UIImageView alloc] init];
NSData *imageData = [NSData dataWithContentsOfURL:thumbUrl];
imageView.image = [UIImage imageWithData:imageData];
cell.backgroundView = imageView;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
NSString *title = [titles objectAtIndex:indexPath.row];
float width = [[thumbWidth objectForKey:title] floatValue];
float height = [[thumbHeight objectForKey:title] floatValue];
float imageWidth = (screenWidth / 2) - 3;
float scale = imageWidth / width;
float imageHeight = height * scale;
CGSize imageSize = CGSizeMake(imageWidth, imageHeight);
return imageSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
// Layout: Set Edges
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// return UIEdgeInsetsMake(0,8,0,8); // top, left, bottom, right
return UIEdgeInsetsMake(0,0,0,0); // top, left, bottom, right
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray* attributesToReturn = [self layoutAttributesForElementsInRect:rect];
for (UICollectionViewLayoutAttributes* attributes in attributesToReturn)
{
if (nil == attributes.representedElementKind)
{
NSIndexPath* indexPath = attributes.indexPath;
attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;
}
}
return attributesToReturn;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes* currentItemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
if (indexPath.item < numColumns){
CGRect f = currentItemAttributes.frame;
f.origin.y = 0;
currentItemAttributes.frame = f;
return currentItemAttributes;
}
NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-numColumns inSection:indexPath.section];
CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
CGFloat YPointNew = fPrev.origin.y + fPrev.size.height + 10;
CGRect f = currentItemAttributes.frame;
f.origin.y = YPointNew;
currentItemAttributes.frame = f;
return currentItemAttributes;
}