3

目前我有一个 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];


}

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

如何更好地连接两个更好的控制器以及加载照片的正确方法是什么/如何获取我在网格布局中时所使用的照片(在全尺寸细节视图中)。

帮助表示赞赏。

4

1 回答 1

4

好的,这有三个部分。

首先是UICollectionViewController显示照片库的子类 ( UIImage)。其次是UIPageViewController管理每个人左右滑动的子类PhotoViewController。第三是显示单张照片的UIViewController子类 ( )。PhotoViewController

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

在此处输入图像描述

左边是一个UICollectionViewControllerthis,中间有一个segue UIPageViewController。右边是在属性窗格UIViewController中有一个Identifier集合的 a(注意,这没有 segue)。

PhotoViewController...的标识符

在此处输入图像描述

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

在此处输入图像描述

在属性窗格中设置了 Class 类型PhotoPageModelController...这是作为PhotoPageViewController.

在此处输入图像描述

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

因此,首先要设置的是PhotoPageModelController. 这是这样的数据源,PhotoPageViewController它将分配子类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

好的。这就是照片页面模型控制器。

页面视图控制器

接下来为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为 called的属性,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.
    }
}
于 2013-08-08T16:12:39.957 回答