ScrollView or CollectionView?

2019-04-17 14:25发布

I have a collection view populated with data like:

[self.graniteImages addObject:[[NSMutableDictionary alloc]
                               initWithObjectsAndKeys:@"Angel Cream", @"name",
                               @"angel-cream.jpg", @"image", nil]];
[self.graniteImages addObject:[[NSMutableDictionary alloc]
                               initWithObjectsAndKeys:@"Angola Black", @"name" ,
                               @"angola_black1.jpg", @"image" , nil]];

and then have a segue to a detail view which is static.

I now want to add paging to the detail view so that I can swipe through the images that I have contained in my collection view in the same way that the iPhone photo gallery works.

I'm guessing either a scrollview or a second collectionview would be needed however I'm not sure where to start with this so any pointers, sample code or any other help you guys could give would be massively appreciated.

Thanks

2条回答
家丑人穷心不美
2楼-- · 2019-04-17 14:57

You should simply use a UIScrollView with paging enabled. The following code should do the trick:

NSInteger numberOfImages = [self.graniteImages count];
    CGRect bounds = self.scrollView.bounds;
self.scrollView.contentSize = CGSizeMake(bounds.size.width * numberOfImages, bounds.size.height);
scrollView.pagingEnabled = YES;

CGFloat x = 0;  
for (NSMutableDictionary *dict in images) {
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[dict valueForKey:@"image"]]];
    imageView.frame = CGRectMake(x, 0, bounds.size.width, bounds.size.height);
    [scrollView addSubview:imageView];
    x += self.view.bounds.size.width;
}

EDIT: This code would go in your detail view controller's ViewDidLoad method. Your detail view controller should also have a property index of type NSUInteger and a graniteImages property of type NSMutableArray* that you can set in your collection view controller's prepareForSegue method just like:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:@"yourSegue"]){
    ((DetailViewController*)segue.destinationViewController).graniteImages = self.graniteImages;
    ((DetailViewController*)segue.destinationViewController).index = self.tappedImageIndex;
    }
}

and in your ViewDidLoad method you add:

[scrollView scrollRectToVisible:CGRectMake(bounds.size.width * self.index, 0, bounds.size.width, bounds.size.height) animated:NO];
查看更多
戒情不戒烟
3楼-- · 2019-04-17 15:02

If you already have a collection view that does what you want just turn on paging. self.collectionView.pagingEnabled = YES You can also enable paging in IB by checking the paging box in the attributes inspector. Using a UICollectionView gives you the added benefit of reusable cells.

Edit

You could still use UICollectionView. Create an UICollectionViewCell subclass that contains your detail view. Then when you want to launch directly to a particular image you can use - (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated If you're loading a ton of images in this view the scrollview method will load all of your images at once rather than on demand like they would in a collectionview scenario. You can always work around that in a scrollview but all that work's been done for you in UICollectionView.

Edit2

I started this in a comment but it was getting big...

In your view controller subclass you will need to register either your class or a nib that you created to lay out that cell. I prefer the nib so I can lay everything out in Interface Builder. If you go the nib route you will create an empty xib and drag a UICollectionViewCell out of the object library in the bottom right. Then select that cell and make sure the Class is set to the custom subclass you've created.

Now in your view controller subclass you'll call – registerNib:forCellWithReuseIdentifier: in the viewDidLoad method like this:

   [self.collectionView registerNib:[UINib nibWithNibName:@"WhateverYouNamedYourNib" bundle:nil] forCellWithReuseIdentifier:@"cell"];

Your view controller will conform to the UICollectionViewDataSource protocol and you will implement this method:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  CustomCellClass *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath
  //Setup the cell with image and whatever else
  return cell;
}
查看更多
登录 后发表回答