目前我有一个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>
非常感谢帮助。
答案 0 :(得分:4)
好的,这有三个部分。
首先是UICollectionViewController
子类来显示照片库(UIImage
)。
其次是UIPageViewController
子类,用于管理每个人PhotoViewController
从一侧到另一侧的滑动。
第三个是显示单张照片的UIViewController
子类(PhotoViewController
)。
故事板看起来像这样......
左边是UICollectionViewController
,它与中间的UIPageViewController
有一个segue。右侧是UIViewController
,在属性窗格中设置了Identifier
(注意,此处没有设置)。
PhotoViewController
...
在PhotoPageViewController
我有自定义对象......
在属性窗格中设置类类型PhotoPageModelController
...这是作为PhotoPageViewController
的dataSource连接的。
这就是所有故事板设置所需要的。
因此,设置的第一件事是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.
}
}