目前我有一个 uicollection View ,它显示用户照片中的特定相册(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");}
];
}
将它们(缩略图版本)全部加载到 Collection View 中,一切正常。
然后当用户选择一张照片时,我调用这个 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/
允许使用 Collection View 进行分页。我写了一个 detailViewController 类。
问题来了。我应该如何将两者联系起来?
想法 1:让我的 mainView 发送一个表示所选照片的整数,然后 detailViewController 将加载该照片并开始延迟加载照片。
想法 2:以某种方式预加载一些全屏照片,然后将整数与数组中的点一起发送。
想法 3:将数字和我的数组对象都发送到 detailViewController,这样我就不必再次枚举 Assets 库。
这些是正确的方法还是我完全错过了这个想法?
编辑:
我的细节 Controller 中有一个启用了分页的 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];
}
它应该做的是从我的主视图中获取值并移动到该图像。不幸的是它没有。我不确定为什么,而且我觉得有更好的方法可以做到这一点。这似乎有点骇人听闻。
我如何更好地连接两个更好的 Controller 以及加载照片的正确方法是什么/我如何获得照片(在全尺寸细节 View 中)我在网格布局中时的照片。
感谢您的帮助。
最佳答案
好的,这分为三个部分。
首先是 UICollectionViewController
子类,用于显示照片库 (UIImage
)。
其次是 UIPageViewController
子类,用于管理每个 PhotoViewController
的左右滑动。
第三个是显示单张照片的 UIViewController
子类 (PhotoViewController
)。
Storyboard看起来像这样......
左边是一个 UICollectionViewController
,它与中间的 UIPageViewController
有一个 segue。右侧是一个 UIViewController
,它在属性 Pane 中设置了一个 Identifier
(请注意,这里没有继续)。
PhotoViewController
的标识符...
在 PhotoPageViewController
中,我有一个自定义对象...
在属性 Pane 中设置了类类型 PhotoPageModelController
...这作为 PhotoPageViewController
的数据源连接。
这几乎就是所有需要的 Storyboard设置。
因此,首先要设置的是 PhotoPageModelController
。这是 PhotoPageViewController
的数据源,因此将分发 UIViewController
的子类,以便 PhotoPageViewController
可以显示它们。
模型 Controller
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
好的。这就是照片页面模型 Controller 。
页面 View 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
照片 View Controller
接下来是将显示实际照片的 View Controller 。
它所需要的只是一个名为 photo
的 UIImage
类型的属性,然后是一个 UIImageView
来放置它。我将保留它给你,因为你可以用很多不同的方式做到这一点。
我在我的中放了一个可缩放的 UIScrollView
,这样用户就可以捏缩放照片。我还有一些额外的信息,例如拍摄照片的人的姓名和拍摄日期等...随心所欲地进行设置。
Collection View 转场
最后一部分(最后)是从 Collection View 到页面 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.
}
}
关于objective-c - 在 Collection View 和分页详细 View 之间转换的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18084002/