I have a UICollectionView that I cannot get to transfer the image to the detailview. The detailview transfer would work when I used local images and the pictures array with the [pictures[row]] method, but since using the SDWebImage framework, I cannot do that. I cannot figure out to properly transfer the image to the detail view once the cell is selected. The logic is explained in the first method CellForItemAtIndexPath. The selected cell and prepare for segue methods are causing the issue. Let me know if you need more information.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
pictureViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyCell" forIndexPath:indexPath];
NSString *pictures1 = [[pictures objectAtIndex:indexPath.row]objectForKey:#"filename"];
comment = [[pictures objectAtIndex:indexPath.row] objectForKey:#"comment"];
[cell.imageView setImageWithURL:[NSURL URLWithString:pictures1]
placeholderImage:[UIImage imageNamed:#"Earth.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
NSLog(#"Error downloaidng images");
}];
// UIImage *image;
// int row = [indexPath row];
//image = [UIImage imageNamed:pictures[row]];
//image = [UIImage imageWithData:imageUrl];
// cell.imageView.image = image;
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UIImage *image;
//int row = [indexPath row];
NSString *pictures1 = [[pictures objectAtIndex:indexPath.row]objectForKey:#"filename"];
// image = [UIImage imageNamed:pictures[row]];
image = [UIImage imageNamed:pictures1];
pictureDetailView *pictureDetail = [[pictureDetailView alloc]init];
pictureDetail.image = image;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UICollectionViewCell *)sender
{
pictureDetailView *targetVC = (pictureDetailView *) [segue destinationViewController];
NSIndexPath *indexPath = [self.collectionView indexPathForCell:sender];
UIImage *image;
//int row = [indexPath row];
NSString *pictures1 = [[pictures objectAtIndex:indexPath.row]objectForKey:#"filename"];
// image = [UIImage imageNamed:pictures[row]];
image = [UIImage imageNamed:pictures1];
//image = [UIImage imageWithData:imageUrl];
targetVC.image=image;
}
#end
I had a similar issue in an app I'm working on, and could not find any help for Collection Views. The code I used is below (updated to match your methods). I hope this helps get you on the right track. You can also check the demo project posted on the SDWebImage GitHub page. That helped me figure some of these issues out.
In Your CollectionViewController.h:
#import <UIKit/UIKit.h>
#import "PictureDetailView.h"
#class PictureDetailView;
#interface CollectionViewController : UICollectionViewController <UICollectionViewDataSource, UICollectionViewDelegate>
#property (nonatomic, strong) PictureDetailView *detailViewController;
#end
In Your CollectionViewController.m:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"yourSegueNameHere"]) {
PictureDetailView *pictureDetail = segue.destinationViewController;
NSIndexPath *indexPath = [[self.collectionView indexPathsForSelectedItems] lastObject];
NSString *largeImageURL = [pictures1 objectAtIndex:indexPath.row];
pictureDetail.imageURL = [NSURL URLWithString:largeImageURL];
}
}
In Your DetailViewController.h
#import <UIKit/UIKit.h>
#import "CollectionViewController.h"
#interface DetailViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *imageView;
#property (strong, nonatomic) NSURL *imageURL;
#end
In Your DetailViewController.m
#import "DetailViewController.h"
#import <SDWebImage/UIImageView+WebCache.h>
#import "UIImageView+WebCache.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
#synthesize imageURL = _imageURL;
#synthesize imageView = _imageView;
- (void)setImageURL:(NSURL *)imageURL
{
if (_imageURL != imageURL)
{
_imageURL = imageURL;
[self configureView];
}
}
- (void)configureView
{
if (self.imageURL)
{
[self.imageView setImageWithURL:self.imageURL
placeholderImage:nil
options:SDWebImageProgressiveDownload
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType)
{
}];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureView];
}
Just access the imageView of the selected cell and extract its image. Here is how to do it:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self collectionView:collectionView cellForItemAtIndexPath:indexPath];
UIImage *image = cell.imageView.image;
// Pass the image to the next VC.
}
Let me know if you need more help.
Related
At first, sorry for my long question.
I'm creating an custom UITableViewCell with UICollectionView inside it. Whenever users select this cell, UIImagePickerController will appear, and now I wanna pass all selected images from UIImagePickerController into UICollectionView inside my custom cell. I was completed to show image picker and now my problem is display selected images in collection view.
How can I make it?
My code:
SHImageUploadCell.h
#import <UIKit/UIKit.h>
#class SHImageUploadCell;
#protocol SHImagUploadDelegate<NSObject>
#optional
- (void)closeImage:(SHImageUploadCell*)cell;
#end
#interface SHImageUploadCell : UICollectionViewCell
#property (weak, nonatomic) IBOutlet UIImageView *imgUpload;
#property (strong,nonatomic) id<SHImagUploadDelegate> delegate;
#property(nonatomic) int imageIndex;
#property (weak, nonatomic) IBOutlet UIImageView *bugImage;
#end
SHImageUploadCell.m
#import "SHImageUploadCell.h"
#implementation SHImageUploadCell
- (IBAction)bntDeleteImageClick:(id)sender {
NSDictionary* userInfo = #{#"index": #(self.imageIndex)};
NSLog(#"%d", self.imageIndex);
if (_delegate) {
[_delegate closeImage:self];
}
}
#end
MyCustomCell.h
#import <UIKit/UIKit.h>
#interface SHPhotoPickerViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UICollectionView *photoCollection;
#property (strong, nonatomic) NSMutableArray *listImage;
#end
MyCustomCell.m
#import "SHPhotoPickerViewCell.h"
#import "SHImageUploadCell.h"
#interface SHPhotoPickerViewCell ()<UICollectionViewDataSource, UICollectionViewDelegate, SHImagUploadDelegate>
#end
#implementation SHPhotoPickerViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self.photoCollection registerClass:[SHImageUploadCell class] forCellWithReuseIdentifier:#"selectedCell"];
[self.photoCollection registerNib:[UINib nibWithNibName:#"SHImageUploadCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:#"selectedCell"];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.listImage.count;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
SHImageUploadCell *uploadCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"uploadCell" forIndexPath:indexPath];
uploadCell.imgUpload.image = [UIImage imageWithData: self.listImage[indexPath.row]];
uploadCell.imageIndex = (int)indexPath.row;
uploadCell.delegate=self;
return uploadCell;
}
#end
Handle cell select:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 4){
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
}
}
UIImagePickerController delegate:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
SHPhotoPickerViewCell *photoPickerCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:self.pickerCellIndexPath.row inSection:1]];
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
image = [SHHelper resizeImageWithImage:image toSize:CGSizeMake(480, 320)];
NSData *imageData = UIImageJPEGRepresentation(image, 0.7);
photoPickerCell.listImage = [NSMutableArray new];
[photoPickerCell.listImage addObject:imageData];
[photoPickerCell.photoCollection reloadData];
[picker dismissViewControllerAnimated:YES completion:^{
}];
}
Try this :
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
id object = [listImage objectAtIndex:indexPath.row];
if ([object isKindOfClass:[UIImage class]]) {
uploadCell.imgUpload.image = (UIImage *)object;
}
else{
uploadCell.imgUpload.image = [UIImage imageWithData: object];
}
return uploadCell;
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
[listImage addObject:image]; // here add image which you selected
// reload tableview
// reload collection view
[picker dismissViewControllerAnimated:YES completion:^{
}];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
[_keyboard.collectionView registerClass:[NibCell class] forCellWithReuseIdentifier:#"Cell"];
static NSString *identifier = #"Cell";
NibCell *cell = [self.keyboard.collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView * rampageGifImage = [[UIImageView alloc] initWithFrame:CGRectMake(0,0, cell.frame.size.width, cell.frame.size.height)];
[rampageGifImage setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#.gif",[rampageGif objectAtIndex:indexPath.row]]]];
[cell.layer setCornerRadius:4];
[cell addSubview:rampageGifImage];
return cell;
}
You can use Gif Image by Adding SDWebImage from Github in your project.
Try like this,
#import "UIImage+GIF.h"
_imageViewAnimatedGif.image= [UIImage sd_animatedGIFNamed:#"YOURGIF_IMAGE"];
Hope this will help you.
Try it. It is small category that could loads animated GIF. Also, jpg, png, etc..
#import "ViewController.h"
#import "UIImage+Gif.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIImageView *imageView1;
#property (weak, nonatomic) IBOutlet UIImageView *imageView2;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Usage 1 : gifWidthData
NSData *data = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"f1" withExtension:#"gif"]];
self.imageView1.image = [UIImage gifWithData:data];
// Usage 2 : gifWidthURL
NSURL *url = [[NSBundle mainBundle] URLForResource:#"f2" withExtension:#"gif"];
self.imageView2.image = [UIImage gifWithURL:url];
}
I have UIcollectionView in my first view of application after Uinavigationviewcontroller just in storyboard just like this :
this is my RootViewController.h
#import <UIKit/UIKit.h>
#interface RootViewController : UICollectionViewController<UICollectionViewDelegate,UICollectionViewDataSource>
#property (nonatomic, strong) NSArray *entries;
#end
and my RootViewController.m :
#import "RootViewController.h"
#import "AppRecord.h"
#import "Cell.h"
#define kCustomRowCount 7
#interface RootViewController () <UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
// the set of IconDownloader objects for each app
#property (nonatomic, strong) NSMutableDictionary *imageDownloadsInProgress;
#end
#implementation RootViewController
#pragma mark
// -------------------------------------------------------------------------------
// viewDidLoad
// -------------------------------------------------------------------------------
- (void)viewDidLoad
{
NSLog(#"inside class");
[super viewDidLoad];
// self.title = #"My Title";
//self.collectionView.delegate = self;
//self.collectionView.dataSource=self;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
NSUInteger count = [self.entries count];
NSLog(#"count: %lu", (unsigned long)count);
if (count == 0)
{
return kCustomRowCount;
}
return count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"inside cell");
AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row];
Cell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MY_CELL" forIndexPath:indexPath];
UIImage *truckImage = [[UIImage alloc] init];
truckImage = [UIImage imageNamed:#"Default.png"];
cell.imageView.image = truckImage;
return cell;
}
#end
now problem is none of my "cellForItemAtIndexPath" or "numberOfItemsInSection" or even "viewDidLoad" getting called and the output on Simulator is black screen.
This is my reload section of AppDelegate class :
__block ParseOperation *weakParser = parser;
parser.completionBlock = ^(void) {
if (weakParser.appRecordList) {
dispatch_async(dispatch_get_main_queue(), ^{
RootViewController *rootViewController = (RootViewController*)[(UINavigationController*)self.window.rootViewController topViewController];
rootViewController.entries = weakParser.appRecordList;
if(weakParser.appRecordList != nil)
NSLog(#"weakParser.appRecordList is Not nill");
[rootViewController.collectionView reloadItemsAtIndexPaths:[rootViewController.collectionView indexPathsForVisibleItems]];
[rootViewController.collectionView reloadData];
});
}
self.queue = nil;
};
[self.queue addOperation:parser];
self.appListData = nil;
}
Did you add the delegate and datasource connection for the collection view? It's the most common mistake, usually. They're commented out in code, I assume you did that via Storyboard
Do you have identifier on the storyboard cell?You can try to add
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"MY_CELL"];
in viewDidLoad
Since your RootViewController inherit UICollectionViewController you don't need to add UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout at all
I use the tapGesture method to pouch the image from UICollectionView to detailViewController
viewController.h as follows:
#import <Parse/Parse.h>
#interface CardsViewController : UIViewController <UICollectionViewDelegateFlowLayout> {
NSMutableArray *allImages;
NSArray *cardFileArray;
}
#property (weak, nonatomic) IBOutlet UICollectionView *imageCollection
and viewController.m as the follow
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [cardFileArray count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"MyCell";
Cards *cell = (Cards *)[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
PFObject *imageObject = [cardFileArray objectAtIndex:indexPath.row];
PFFile *imageFile = [imageObject objectForKey:KEY_IMAGE4];
cell.spinController.hidden = NO;
[cell.spinController startAnimating];
[imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
cell.imageView.image = [UIImage imageWithData:data];
[cell.spinController stopAnimating];
cell.spinController.hidden = YES;
}
}];
return cell;
}
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture{
CGPoint touchPoint = [gesture locationInView:imageCollection];
NSUInteger touchPage = floorf(touchPoint.x / imageCollection.frame.size.width);
NSIndexPath *indexPath = [imageCollection indexPathForItemAtPoint:touchPoint];
if (indexPath == nil) {
touchPage = touchPage % ([allImages count]);
}
//Push the image to another view
detailViewController*ptvc = [self.storyboard instantiateViewControllerWithIdentifier:#"imageDetail"];
[self.navigationController pushViewController:ptvc animated:YES];
ptvc.imageString = [cardFileArray objectAtIndex:touchedPage];
}
the detailViewController.h as follow
#property (strong, nonatomic) IBOutlet UIImageView *Preview;
#property (strong, nonatomic) UIImage *imagePreview;
so for the DetailViewController i put in viewDidload this line
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//self.imageView.image = [UIImage imageNamed:self.imageViewDetail];
self.Preview.image = self.imagePreview;
}
but the app make crash and mark the line on the viewDidload
; so any advice i need to puch the image on uicollectionView to detailView
to solve this first you need to identify the image in didselect from parse and declare the segue as well as following
[self performSegueWithIdentifier:#"showDetails" sender:imageCollection];
PFObject *object = [cardFileArray objectAtIndex:indexPath.row];
PFFile *file = [object objectForKey:KEY_IMAGE4];
[file getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
Cards *recipe = [[Cards alloc] init];
recipe.imageView.image = [UIImage imageWithData:data];
}
}];
then you perform the Segue method and link to the detail view as normal and not the following
link you segue to the "you cell" and the imageview in the cell
Finally, import your cell to the detail view and declare it in your header file (this will be linked to your segue)
i hope this will help you
Two things
Remove the tap gesture recognizer and use
-(void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
I see you are using storyboards.. just connect the two view controllers by a push segue. Set an UIImage as property of the detailViewController
-(void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//store indexPath.row to a variable accessible outside this function
selectedRow = indexPath.row;
[self performSegueWithIdentifier:#"detail" sender:nil];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DetailViewController *detail = [segue destinationViewController];
[detail setImageForDetail:[UIImage imageWithData:[allImages objectAtIndex:selectedRow]]];
//imageArray is the array used to populate the imageCollectionView and i assume they are stored as NSDATA
}
in DetailViewController.h, add
#property (strong,nonatomic) UIImage *imageForDetail;
in DetailViewController.m viewDidLoad add,
self.Preview.image = self.imageForDetail;
I have a collectionview controller and a collectionviewcell. FOr the collectionviewcell I have a custom class. I am trying to set the uiimage and it isn't working.
Thank you in advance!.
Method in collectionview controller where I am trying to set the image.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier=#"Cell";
CollectionVIewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
;
CollectionVIewCell *feederCell = (CollectionVIewCell*)[_availableFilters objectAtIndex:indexPath.row];
cell.labelDisplay.text=feederCell.filterName;
NSLog(#"selected =%#",cell.labelDisplay.text);
if (feederCell.isSelected) {
UIImageView *imageView=[[UIImageView alloc]init];
//process string name
NSString*filePath =[NSString stringWithFormat:#"%#.png",feederCell.filterName];
NSArray* words = [filePath componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceCharacterSet]];
filePath=[words componentsJoinedByString:#""];
cell.FilePath=filePath;
//image
UIImage *image = [UIImage imageNamed:filePath];
[imageView setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
[imageView setImage:image];
[cell setIconDisplay:imageView];//setting the image that won't set
}else if(!feederCell.isSelected){
UIImageView *imageView=[[UIImageView alloc]init];
NSString*filePath =[NSString stringWithFormat:#"%#.png",feederCell.filterName];
NSArray* words = [filePath componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceCharacterSet]];
filePath=[words componentsJoinedByString:#""];
UIImage *image = [UIImage imageNamed:filePath];
[imageView setFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
[imageView setImage:image];
[cell setIconDisplay:imageView];
}
return cell;
.h file
//
// CollectionVIewCell.h
#import <UIKit/UIKit.h>
#interface CollectionVIewCell : UICollectionViewCell
#property (strong, nonatomic) IBOutlet UIImageView *IconDisplay;
#property (strong, nonatomic) IBOutlet UILabel *labelDisplay;
#property (assign,nonatomic) BOOL isSelected;
#property (strong,nonatomic)NSString*textName;
#property(strong,nonatomic)NSString*FilePath;
#end
.m file
//
// CollectionVIewCell.m
#import "CollectionVIewCell.h"
#implementation CollectionVIewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_labelDisplay.text=_textName;
_IconDisplay=[[UIImageView alloc]init];
}
return self;
}
#end
You need to add the UIImageView as a subview. Otherwise it exists but isn't displayed.