在集合视图和分页详细信息视图之间转换的正确方法

时间:2013-08-06 15:10:19

标签: objective-c alassetslibrary

目前我有一个uicollection视图,在用户照片中显示特定的相册(ALAssets库)。

在我的mainView.m中,我收集了图片:

+ (ALAssetsLibrary *)defaultAssetsLibrary {
    static dispatch_once_t pred = 0;
    static ALAssetsLibrary *library = nil;
    dispatch_once(&pred, ^{
        library = [[ALAssetsLibrary alloc] init];
    });
    return library;
}


- (void)beginLoadingPhotoInfo {

...

[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
                               usingBlock:assetGroupEnumerator
                             failureBlock:^(NSError *error) {NSLog(@"Probs");}
         ];
}

将它们(缩略图版本)全部加载到集合视图中,一切正常。

然后,当用户选择照片时,我称之为prepareToSegue方法:(仍在mainView.m中)

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if([[segue identifier] isEqualToString:@"showDetail"])
    {
        NSIndexPath *indexPath = [[self.collectionView indexPathsForSelectedItems] lastObject];
        DetailViewController *detailviewcontroller = [segue destinationViewController];
        detailviewcontroller.photoArrayIndex = indexPath.row;

        //photos array
        detailviewcontroller.photosArray = _photoListArray;





}

目前我正在发送一个包含照片信息的数组,并尝试滚动到数组中的位置。

我在这里找到了这个资源用于水平分页:

http://adoptioncurve.net/archives/2013/04/creating-a-paged-photo-gallery-with-a-uicollectionview/

允许使用集合视图进行分页。我写了一个detailViewController类。


这是问题所在。我应该如何连接这两个?

创意1:让我的mainView发送一个代表所选照片的​​整数,然后detailViewController会加载那个并开始延迟加载照片。

创意2:以某种方式预加载一些全屏照片,然后发送整数与数组中的点。

创意3:将数字和我的数组对象发送到detailViewController,这样我就不必再次枚举资产库了。

这些都是正确的方法还是我完全错过了这个想法?


编辑:

我的详细控制器中的内容是启用了分页的uicollectionview流布局。 这是我设置布局的方法:

- (void) setCollectionView {

    [self.collectionView registerClass:[DetailViewCell class] forCellWithReuseIdentifier:@"detailViewCell"];

    //Flow Layout
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    [flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
    [flowLayout setMinimumInteritemSpacing:0.0f];
    [flowLayout setMinimumLineSpacing:0.0f];
    [self.collectionView setPagingEnabled:YES];
    [self.collectionView setCollectionViewLayout:flowLayout];


    CGFloat pageWidth = self.collectionView.frame.size.width;
    NSInteger num = _photosArrayIndex + 1;
    CGPoint scrollTo = CGPointMake(pageWidth * num, 0);
    NSLog(@"scroll to: %@", NSStringFromCGPoint(scrollTo));
    [self.collectionView setContentOffset:scrollTo];


}

它应该做的是从我的主视图中获取值并移动到该图像。不幸的是它没有。我不确定为什么,而且我觉得有更好的方法可以做到这一点。它看起来有点像黑客。

如何更好地连接两个更好的控制器以及加载照片的正确方法是什么?如何进入照片(在完整尺寸详细视图中)我在网格布局中时所处的位置。< / p>

非常感谢帮助。

1 个答案:

答案 0 :(得分:4)

好的,这有三个部分。

首先是UICollectionViewController子类来显示照片库(UIImage)。 其次是UIPageViewController子类,用于管理每个人PhotoViewController从一侧到另一侧的滑动。 第三个是显示单张照片的UIViewController子类(PhotoViewController)。

故事板看起来像这样......

enter image description here

左边是UICollectionViewController,它与中间的UIPageViewController有一个segue。右侧是UIViewController,在属性窗格中设置了Identifier(注意,此处没有设置)。

PhotoViewController ...

的标识符

enter image description here

PhotoPageViewController我有自定义对象......

enter image description here

在属性窗格中设置类类型PhotoPageModelController ...这是作为PhotoPageViewController的dataSource连接的。

enter image description here

这就是所有故事板设置所需要的。

因此,设置的第一件事是PhotoPageModelController。这是PhotoPageViewController的dataSource,因此会分配UIViewController的子类,以便PhotoPageViewController可以显示它们。

模型控制器

PhotoPageModelController.h

@class PhotoViewController;

@interface PhotoPageModelController : NSObject <UIPageViewControllerDataSource>

// this is the array of the photos. Either an array of UIImages or objects containing
// them or something. My personal project had an array of photoIDs that I could use to
// pull the photos out of Core Data.

// In this example the array will contain instances of UIImage.
@property (nonatomic, strong) NSArray *photos;

- (PhotoViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard;

- (NSUInteger)indexOfViewController:(PhotoViewController *)controller;

@end

PhotoPageModelController.m

#import "PhotoPageModelController.h"
#import "PhotoViewController.h"

@implementation PhotoPageModelController

- (UIImage *)photoAtIndex:(NSUInteger)index
{
    // check that the index is in bounds and then return the UIImage to display.
    // In my project I just returned the ID of the photo and let the photo
    // controller load the actual image from core data. (See below)

    if ([self.photos count] == 0
            || index >= [self.photos count]) {
        return nil;
    }

    return self.photos[index];
}

#pragma mark - convenience methods

- (PhotoViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard
{
    UIImage *photo = [self photoAtIndex:index];

    if (photo == nil) {
        return nil;
    }

    // This is why we don't have a segue. We are loading it manually
    // from the storyboard using the identifier.
    EventPhotoViewController *controller = [storyboard instantiateViewControllerWithIdentifier:@"PhotoViewController"];

    // The model controller is where the PhotoViewController gets the actual image from.
    // Or an object containing the image with a name, date, details, etc...
    // The controller doesn't know anything about the other photos. Only the one it's displaying.
    controller.photo = photo;

    return controller;
}

- (NSUInteger)indexOfViewController:(PhotoViewController *)controller
{
    // Return the index of the given data view controller.
    // For simplicity, this implementation uses a static array of model objects and the view controller stores the model object; you can therefore use the model object to identify the index.
    return [self.photos indexOfObject:controller.photo];
}

#pragma mark - page view data source

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    // We need to find the index of the current controller so we can get the index
    // and then the view controller for the one before it.
    NSUInteger index = [self indexOfViewController:(PhotoViewController *) viewController];
    if ((index == 0) || (index == NSNotFound)) {
        // We have reached the beginning of the photos array so return nil.
        // This tells the Page View Controller that there isn't another page.
        return nil;
    }

    index--;
    return [self viewControllerAtIndex:index storyboard:viewController.storyboard];
}


// This is the same as above but going forward instead of backward.
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(EventPhotoViewController *) viewController];
    if (index == NSNotFound) {
        return nil;
    }

    index++;
    if (index == [self.photoIDs count]) {
        return nil;
    }
    return [self viewControllerAtIndex:index storyboard:viewController.storyboard];
}

@end

行。这就是Photo Page Model Controller。

网页浏览控制器

PhotoPageViewController的下一步。

PhotoPageViewController.h

#import <Foundation/Foundation.h>

@interface PhotoPageViewController : UIPageViewController

@property (nonatomic, strong) NSArray *photos;
@property (nonatomic) NSUInteger initialIndex;

@end

PhotoPageViewController.m

#import "PhotoPageViewController.h"
#import "PhotoPageModelController.h"

@interface PhotoPageViewController ()

// this property is connected in the storyboard
@property (nonatomic, weak) IBOutlet PhotoPageModelController *modelController;

@end

@implementation PhotoPageViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.modelController.photos = self.photos;

    // We use the initialIndex property to get the first controller and display it.
    UIViewController *initialController = (UIViewController *)[self.modelController viewControllerAtIndex:self.initialIndex storyboard:self.storyboard];

    [self setViewControllers:@[initialController]
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:NO
                  completion:^(BOOL finished) {

                  }];

    // That's it. Because we have the datasource class it makes this class really easy and short.

    // It doesn't even need to know anything about the view controllers it is displaying.
    // It's just a dispensing machine.
}

@end

照片视图控制器

接下来是将显示实际照片的视图控制器。

它所需要的只是UIImage类型的photo属性,然后是UIImageView来放置它。我会把它留给你,因为你可以做很多不同的事情方式。

我在我的手机中放置了一个可缩放的UIScrollView,以便用户可以捏缩放照片。我还得到了一些额外的信息,比如照片拍摄者的姓名和拍摄日期......等等你喜欢这样设置。

集合视图segue

最后一部分(最后)从集合视图进入页面视图控制器。

这是在prepareForSegue

中完成的
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"PhotoSegue"]) {
        PhotoPageViewController *controller = segue.destinationViewController;

        NSIndexPath *selectedIndex = [self.collectionView indexPathsForSelectedItems][0];

        // The PageViewController doesn't need anything except the index to start on...
        // i.e. the index of the photo that the user just selected.
        controller.initialIndex = (NSUInteger)selectedIndex.item;

        // ...and the array of photos it will be displaying.
        controller.photos = self.photos;

        // Everything else is done by the PageViewController.
    }
}
相关问题