在集合视图和分页详细信息视图之间转换的正确方法 [英] Correct way to transition between collection view and paged detail view

查看:61
本文介绍了在集合视图和分页详细信息视图之间转换的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Currently I have a uicollection view which displays a specific album in the users photos, (ALAssets library).

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

In my mainView.m I gather the pictures:

+ (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");}
         ];
}

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

Load them (the thumbnail version) all into the collection view and that all works well.

然后当用户选择一张照片时,我调用这个 prepareToSegue 方法:(仍在 mainView.m 中)

Then when a user selects a photo I call this prepareToSegue method: (still in 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;





}

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

Currently I am sending an array with the info of the photos and attempting to scroll to the position in the array.

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

I found this resource here for the horizontal paging:

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

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

Which allows for paging using a collection view. I wrote that a detailViewController class.

问题来了.我应该如何连接两者?

Here's the question. How should I connect the two?

想法 1:让我的 mainView 发送一个代表所选照片的​​整数,然后 detailViewController 将加载该数字并开始延迟加载照片.

Idea 1: Have my mainView send an integer number representing the photo selected and the detailViewController will then load that one and begin lazy loading the photos.

想法 2:以某种方式预加载一些全屏照片,然后将整数与数组中的点一起发送.

Idea 2: Somehow preload some of the full screen photos and then send the integer with the spot in the array.

想法 3:将数字和我的数组对象都发送到 detailViewController,这样我就不必再次枚举资产库.

Idea 3: Send both the number and my array object over to the detailViewController so that I don't have to enumerate through the assets library again.

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

Are any of these the correct approach or did I miss the idea completely?

我的详细信息控制器中有一个启用了分页的 uicollectionview 流布局.这是我设置布局的方法:

What I have in my detail controller is an uicollectionview flow layout with paging enabled. This is the method where I set up the layout:

- (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];


}

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

What It should do is take the value from my main view and move to that image. Unfortunately it does not. I'm not sure why and also I feel like there is a better way of doing this. It just seems sort of Hackish.

我如何更好地连接两个更好的控制器以及加载照片的正确方法是什么/我如何获得照片(在全尺寸详细信息视图中)我在网格布局时打开的照片.

How do I connect the two better controller better and what is the correct way of loading the photos/ how do I get to the photo (in the full size detail view) I was on when they were in a grid layout.

感谢帮助.

推荐答案

好的,分为三个部分.

首先是 UICollectionViewController 子类,用于显示照片库 (UIImage).第二个是 UIPageViewController 子类,用于管理每个单独的 PhotoViewController 左右滑动.第三个是 UIViewController 子类 (PhotoViewController),用于显示单张照片.

First is the UICollectionViewController subclass to display the gallery of photos (UIImage). Second is the UIPageViewController subclass to manage the swiping from side to side of each individual PhotoViewController. Third is the UIViewController subclass (PhotoViewController) to display a single photo.

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

The storyboard will look something like this...

左边是一个 UICollectionViewController,它与中间的 UIPageViewController 有一个segue.右侧是一个 UIViewController,它在属性窗格中设置了一个 Identifier(注意,这没有任何关联).

On the left is a UICollectionViewController this has a segue to the UIPageViewController in the middle. On the right is a UIViewController that has an Identifier set in the properties pane (note, there is no segue to this).

PhotoViewController 的标识符...

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

In the PhotoPageViewController I have a custom object...

在属性面板中设置一个类类型PhotoPageModelController...这作为PhotoPageViewController的数据源连接.

With a Class type PhotoPageModelController set in the properties pane... This is connected as the dataSource of the PhotoPageViewController.

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

That's pretty much all the storyboard set up required.

所以,首先要设置的是PhotoPageModelController.这是 PhotoPageViewController 的数据源,因此将分配 UIViewController 的子类,以便 PhotoPageViewController 可以显示它们.

So, the first thing to set up is the PhotoPageModelController. This is the dataSource for the PhotoPageViewController as such will dispense subclasses of UIViewController so that the PhotoPageViewController can display them.

模型控制器

PhotoPageModelController.h

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

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

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

OK. So that is the Photo Page Model Controller.

页面视图控制器

接下来是 PhotoPageViewController.

PhotoPageViewController.h

PhotoPageViewController.h

#import <Foundation/Foundation.h>

@interface PhotoPageViewController : UIPageViewController

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

@end

PhotoPageViewController.m

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

照片视图控制器

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

Next is the view controller that will display the actual photo.

它所需要的只是一个 UIImage 类型的属性,称为 photo,然后是一个 UIImageView 来放置它.我会留着它因为你可以用很多不同的方式来做到这一点.

All it needs is a property of type UIImage called photo and then a UIImageView to place it in. I'll leave this up to you as you can do it many different ways.

我已经在我的中放置了一个可缩放的 UIScrollView 以便用户可以捏缩放照片.我还获得了一些额外信息,例如拍摄照片的人的姓名和拍摄日期等...随心所欲地设置.

I've put a zoomable UIScrollView in mine so that the user can pinch zoom the photo. I've also got some extra info such as the name of the person who took the photo and the date it was taken etc... Set this up however you like.

集合视图转场

最后一部分(最后)是从集合视图到页面视图控制器.

The final part (at last) is going from the collection view to the page view controller.

这是在 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.
    }
}

这篇关于在集合视图和分页详细信息视图之间转换的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆