I'm using the below code to track cells when a user drags their finger over them (this works great). That said, I want to highlight each of the cells (or change the color of the background view in my custom cells) as the user drags their finger over top of them. How can I accomplish this? See below.
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[self.ringCollectionView addGestureRecognizer:panGesture];
}
- (void) handlePanGesture:(UIPanGestureRecognizer*) panGesture
{
CGPoint location = [panGesture locationInView:self.ringCollectionView];
NSIndexPath *indexPath = [self.ringCollectionView indexPathForItemAtPoint:location];
NSMutableArray *selectedIndexes = [NSMutableArray arrayWithArray:[self.ringCollectionView indexPathsForSelectedItems]];
if (![selectedIndexes containsObject:#(indexPath.row)]) {
NSLog(#"THIS CELL IS %ld", (long)indexPath.row);
}
else
if (panGesture.state == UIGestureRecognizerStateEnded) {
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 10;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"RingCollectionViewCell";
RingCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Tapping");
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(118, 118);
}
First, I believe tracking selected cells via "native" UICollectionView mechanism is reasonable and consistent. There isn’t any need for custom gesture handlers inside of the cells. In order to represent selected state however, you need to set selectedBackgroundView property, something like this:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"RingCollectionViewCell" forIndexPath:indexPath];
if (!cell.selectedBackgroundView) {
cell.selectedBackgroundView = [[UIView alloc] initWithFrame:cell.bounds];
cell.selectedBackgroundView.backgroundColor = [UIColor grayColor];
}
return cell;
}
I don't know how your RingCollectionViewCell class is designed, but be advised that you will need to ensure contentView of this cell has transparent background color otherwise it will obscure the selectedBackgroundView.
Now the tricky part. UIPanGestureRecognizer gets events very quickly and the handle method will be called quite often when the user just keeps his/her fingers still on the screen. Thus you need to somehow suppress events which are not supposed to switch selected state of a cell.
My suggestion is to ignore all consequence events if they happen in the same cell. In order to implement such behavior we need to store index path of the last cell touched. Let’s use a simple property for that:
#interface ViewController ()
#property (strong, nonatomic, nullable) NSIndexPath *trackingCellIndexPath;
#end
Now you need to assign index path of last touched cell to this property in your gesture handle method. You also need to reset this property when the gesture is finished or cancelled. Switch selection of the given index path if it is not equal to the tracked index path and ignore the touch event otherwise:
- (void)handlePanGesture:(UIPanGestureRecognizer *)recognizer {
// Reset the tracking state when the gesture is finished
switch (recognizer.state) {
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
self.trackingCellIndexPath = nil;
return;
default:
break;
}
// Obtain the cell the user is currently dragging over
CGPoint location = [recognizer locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:location];
// If the user currently doesn't touch any cell, reset the tracking state and prepare to listen to another cell
if (!indexPath) {
if (self.trackingCellIndexPath) {
self.trackingCellIndexPath = nil;
}
return;
}
// If current event is subsequent gesture event which happens within the same cell, ignore it
if (self.trackingCellIndexPath == indexPath) {
return;
}
// If the cell hasn't been previously tracked, switch the selected state and start tracking it
self.trackingCellIndexPath = indexPath;
if ([self.collectionView.indexPathsForSelectedItems containsObject:indexPath]) {
[self.collectionView deselectItemAtIndexPath:indexPath animated:YES];
} else {
[self.collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];
}
}
The last thing to change is the selection mode of the collection view. As you expect multiple cells to remain selected, just switch allowsMultipleSelection of your collection view somewhere in viewDidLoad:
- (void)viewDidLoad {
...
self.collectionView.allowsMultipleSelection = YES;
}
So in order to change color you need to decide how to handle the gesture, but also how to change colors. Consider the following:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic) CGFloat redColor;
#property (nonatomic) CGFloat greenColor;
#property (nonatomic) CGFloat blueColor;
#property (nonatomic) CGPoint startPoint;
#end
#implementation ViewController
// insuring reasonable values
-(void)setRedColor:(CGFloat)colorX {
CGFloat x = colorX;
x = x > 0 ? x : 0;
x = x < 1.0 ? x : 1.0;
_redColor = x;
}
-(void)setGreenColor:(CGFloat)colorY {
CGFloat y = colorY;
y = y > 0 ? y : 0;
y = y < 1.0 ? y : 1.0;
_greenColor = y;
}
- (void)setBlueColor:(CGFloat)colorZ {
CGFloat z = colorZ;
z = z > 0 ? z : 0;
z = z < 1.0 ? z : 1.0;
_blueColor = z;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIView *panView = [UIView new];
panView.backgroundColor = UIColor.blueColor;
panView.translatesAutoresizingMaskIntoConstraints = false;
[self.view addSubview:panView];
[self.view addConstraints:#[
[NSLayoutConstraint constraintWithItem:panView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:0],
[NSLayoutConstraint constraintWithItem:panView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0],
[NSLayoutConstraint constraintWithItem:panView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:0],
[NSLayoutConstraint constraintWithItem:panView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]
]];
[panView addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action: #selector(handlePanGesture:)] ];
}
//Important Parts
-(void)handlePanGesture:(UIPanGestureRecognizer *) panGesture {
//getting our position from super for total location area
UIView *aView = [[panGesture view] superview];
if (panGesture.state == UIGestureRecognizerStateBegan) {
//saving the start of our pans point
_startPoint = [panGesture translationInView: aView];
}else if (panGesture.state == UIGestureRecognizerStateChanged) {
//where our pan moved
//For this example I'm just using changed value to set color using CGFLoat, but you could also determine a direction and go through a UIcolor array or however you want to actually set your color.
CGPoint trin = [panGesture translationInView:aView];
CGFloat xInc = (trin.x - _startPoint.x);// find how much left or right the finger moved.
CGFloat yInc = (trin.y - _startPoint.y); // find how much up or down the finger moved.
CGFloat base = 1.0; //used to keep values in range
//altering colors based on movement
//just as an example for the color change. Ideally you would implement a better color scheme.
[self setRedColor: self.redColor + (xInc == 0 ? 0 : base / xInc)];
[self setGreenColor: self.greenColor + (yInc == 0 ? 0 : base / yInc)];
self.blueColor = self.greenColor + self.redColor;
//setting the new color of our panView
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:1 animations:^{
panGesture.view.backgroundColor = [UIColor colorWithRed: self.redColor
green: self.greenColor
blue: self.blueColor
alpha:1.0];
}];
});
} else if (panGesture.state == UIGestureRecognizerStateEnded) {
_startPoint = CGPointZero;
}
}
#end
Related
In my collection view when (custom) cells are reused they, again, get the highlight I have set in didSelectItemAtIndexPath for the original selection. To prevent this, I am using the custom cell's prepareForReuse method, and post calling [super], I check to see if its the selected cell.
If it is I am change the highlight to default else I restore to the original selection highlight when the cell in question is brought back in scroll view's visible area.
Here's the code...
- (void)prepareForReuse
{
[super prepareForReuse];
if (!self.isSelected) {
[self setBackgroundColor:[UIColor systemBackgroundColor]];
[_tagImageView setTintColor:[UIColor systemBlueColor]];
}
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
}
But I notice that the second if block is never executed even when I bring back the original cell in view. This is where I need help. How do I ensure re-highlighting or the original cell/item?
Note, if I try and save the original cell- even though not highlighted, remains the one selected and the corresponding value is saved.
So, this is just about the re-highlight.
Also, here is the selection code...* didSelectItemAtIndexPath*
- (void)collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndexPath!=nil) {
if (indexPath.row==selectedIndexPath.row)
{
[tagCollectionView deselectItemAtIndexPath:indexPath animated:YES];
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor clearColor];
selectedCell.tagImageView.tintColor = [UIColor systemBlueColor];
selectedIndexPath=nil;
[newDictionary setValue:[NSNull null] forKey:#"type"];
}
else
{
[tagCollectionView deselectItemAtIndexPath:indexPath animated:YES];
TagCollectionViewCell *previousSelectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
previousSelectedCell.backgroundColor = [UIColor systemBackgroundColor];
previousSelectedCell.tagImageView.tintColor = [UIColor systemBlueColor];
selectedIndexPath = indexPath;
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor systemBlueColor];
selectedCell.tagImageView.tintColor = [UIColor systemBackgroundColor];
dictionaryType = _typesArray[selectedIndexPath.row];
[newDictionary setValue:dictionaryType forKey:#"type"];
}
}
else if (selectedIndexPath==nil)
{
selectedIndexPath = indexPath;
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor systemBlueColor];
selectedCell.tagImageView.tintColor = [UIColor systemBackgroundColor];
dictionaryType = _typesArray[selectedIndexPath.row];
[newDictionary setValue:dictionaryType forKey:#"type"];
}
}
Any help? Thanks.
Edit:
This is the part of the code that doesn't get called.
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
I think you are way over-complicating things.
A UICollectionView keeps track of its own "selected" cell(s), and calls setSelected on each cell when it is displayed.
You can put all of your "selected" appearance code inside your cell class:
- (void)setSelected:(BOOL)selected {
// change our color properties based on selected BOOL value
self.tagImageView.tintColor = selected ? UIColor.systemBackgroundColor : UIColor.systemBlueColor;
self.backgroundColor = selected ? UIColor.systemBlueColor : UIColor.systemBackgroundColor;
}
Now you don't need to do anything in didSelectItemAt.
Here's a quick example...
SampleCollectionViewCell.h
#interface SampleCollectionViewCell : UICollectionViewCell
- (void)fillData:(NSInteger)n;
#end
SampleCollectionViewCell.m
#import "SampleCollectionViewCell.h"
#interface SampleCollectionViewCell ()
{
UIImageView *theImageView;
UILabel *theLabel;
}
#end
#implementation SampleCollectionViewCell
- (instancetype)init
{
self = [super init];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit {
// add an image view and a label
theImageView = [UIImageView new];
theImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:theImageView];
theLabel = [UILabel new];
theLabel.textAlignment = NSTextAlignmentCenter;
theLabel.font = [UIFont systemFontOfSize:20.0 weight:UIFontWeightBold];
theLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:theLabel];
[NSLayoutConstraint activateConstraints:#[
[theImageView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:0.0],
[theImageView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:0.0],
[theImageView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:0.0],
[theImageView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:0.0],
[theLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:0.0],
[theLabel.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:0.0],
[theLabel.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-4.0],
]];
// image would probably be set by the data source, but
// for this example we'll use the same system image in every cell
UIImage *img = [UIImage systemImageNamed:#"person.fill"];
if (img) {
theImageView.image = img;
}
// let's give the content view rounded corners and a border
self.contentView.layer.cornerRadius = 8.0;
self.contentView.layer.borderWidth = 2.0;
self.contentView.layer.borderColor = UIColor.systemGreenColor.CGColor;
// default (not-selected) colors
theImageView.tintColor = UIColor.cyanColor;
theLabel.textColor = UIColor.blackColor;
self.contentView.backgroundColor = UIColor.systemBackgroundColor;
}
- (void)fillData:(NSInteger)n {
theLabel.text = [NSString stringWithFormat:#"%ld", (long)n];
}
- (void)setSelected:(BOOL)selected {
// change our color properties based on selected BOOL value
theImageView.tintColor = selected ? UIColor.redColor : UIColor.cyanColor;
theLabel.textColor = selected ? UIColor.yellowColor : UIColor.blackColor;
self.contentView.backgroundColor = selected ? UIColor.systemBlueColor : UIColor.systemBackgroundColor;
}
#end
SampleViewController.h
#interface SampleViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
#end
SampleViewController.m
#import "SampleViewController.h"
#import "SampleCollectionViewCell.h"
#interface SampleViewController ()
{
UICollectionView *collectionView;
}
#end
#implementation SampleViewController
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *fl = [UICollectionViewFlowLayout new];
fl.scrollDirection = UICollectionViewScrollDirectionVertical;
fl.itemSize = CGSizeMake(60, 60);
fl.minimumLineSpacing = 8;
fl.minimumInteritemSpacing = 8;
collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:fl];
collectionView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:collectionView];
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
[NSLayoutConstraint activateConstraints:#[
// constrain collection view 40-points from all 4 sides
[collectionView.topAnchor constraintEqualToAnchor:g.topAnchor constant:40.0],
[collectionView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:40.0],
[collectionView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-40.0],
[collectionView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-40.0],
]];
[collectionView registerClass:SampleCollectionViewCell.class forCellWithReuseIdentifier:#"c"];
collectionView.dataSource = self;
collectionView.delegate = self;
// let's give the collection view a very light gray background
// so we can see its frame
collectionView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 50;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
SampleCollectionViewCell *c = (SampleCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"c" forIndexPath:indexPath];
[c fillData:indexPath.item];
return c;
}
#end
Based on the code you posted, it looks like you want to be able to de-select an already selected cell. If so, add this to the controller:
// this allows us to de-select an already selected cell
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
// get array of already selected index paths
NSArray *a = [collectionView indexPathsForSelectedItems];
// if that array contains indexPath, that means
// it is already selected, so
if ([a containsObject:indexPath]) {
// deselect it
[collectionView deselectItemAtIndexPath:indexPath animated:NO];
return NO;
}
// no indexPaths (cells) were selected
return YES;
}
When run, it starts like this:
Tapping cell "1" selects it:
Tapping cell "7" automatically de-selects cell "1" and selects cell "7":
We can scroll up and down and the selected cell will automatically maintain its "selected appearance":
Edit
To explain why your prepareForReuse wasn't doing what you expected...
The collection view does not set the selected property of the cell until it is going to be displayed.
So, in:
- (void)prepareForReuse
{
[super prepareForReuse];
if (!self.isSelected) {
[self setBackgroundColor:[UIColor systemBackgroundColor]];
[_tagImageView setTintColor:[UIColor systemBlueColor]];
}
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
}
self.isSelected will never be true.
If you want to stick with changing the cell UI properties (colors, tint, etc) in didSelectItemAt, you need to update your cell appearance in cellForItemAt:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TagCollectionViewCell *c = (TagCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"c" forIndexPath:indexPath];
// whatever you are currently doing, such as
//c.tagImageView.image = ...;
if (selectedIndexPath != indexPath) {
[c setBackgroundColor:[UIColor systemBackgroundColor]];
[c.tagImageView setTintColor:[UIColor systemBlueColor]];
}
else
{
[c setBackgroundColor:[UIColor systemBlueColor]];
[c.tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
return c;
}
I have a UICollectionView and Im trying to set a label and an image in the collectionViewCell. Unfortunately I cant seem to get any labels to display or anything else for that matter.
Here is my code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
}
Unfortunately no label is being displayed and neither is the text in the label.
Updated: I've added the rest of the code from this class file.
#import "ContainerListController.h"
#import "ContainerController.h"
#import "ContainerList.h"
#implementation ContainerListController
//Deallocate temp variables
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//Initiate objects
- (id)init {
if (self = [super initWithTitle:LocStr(#"CONTAINER_LIST_TITLE") navBarHidden:NO]) {
m_paths = [ContainerList shared].paths;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(onContainerListDidChange)
name:kSDKLauncherContainerListDidChange object:nil];
}
return self;
}
//Load all the views.
- (void)loadView {
//Allocate a UI view
self.view = [[UIView alloc] init];
//Create flow layout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
//Force Horizontal Scroll
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
layout.minimumInteritemSpacing =[[UIScreen mainScreen] bounds].size.width;
layout.minimumLineSpacing=0.0;
//Create Collection
UICollectionView *coll =[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
//Allocations
m_coll = coll;
coll.dataSource =self;
coll.delegate =self;
coll.pagingEnabled = YES;
coll.collectionViewLayout = layout;
//Customize Cells
[coll registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[coll setBackgroundColor:[UIColor orangeColor]];
[layout invalidateLayout];
//Create the subview
[self.view addSubview:coll];
//set minimum spacing
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"Changed to landscape Spacing");
layout.minimumLineSpacing = 100.0f;
layout.minimumInteritemSpacing = 100.0f;
}
else{
layout.minimumLineSpacing = 40.0f;
layout.minimumInteritemSpacing = 40.0f;
}*/
//Old Layout
//UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
//m_table = table;
//table.dataSource = self;
//table.delegate = self;
//[self.view addSubview:table];
}
- (void)onContainerListDidChange {
m_paths = [ContainerList shared].paths;
[m_table reloadData];
[m_coll reloadData];
}
//Debugging components function
/*-(void)printComps:(NSArray* ) components{
for (NSInteger i =0; i<16; i++) {
NSString * item;
item=components[i];
}
}*/
//old tableview cell
- (UITableViewCell *)
tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:nil];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
cell.textLabel.text = (components == nil || components.count == 0) ?
#"" : components.lastObject;
return cell;
}
//Old tableView
- (void)
tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if (c != nil) {
[self.navigationController pushViewController:c animated:YES];
}
NSLog(#"Selected an item");
}
//old TableView count for epubs
- (NSInteger)
tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
return m_paths.count;
}
- (void)viewDidLayoutSubviews {
//m_table.frame = self.view.bounds;
m_coll.frame = self.view.bounds;
}
//Collection View Cell Data Allocation
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
//UICollectionViewCell *content = [[UICollectionViewCell alloc] init];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
NSString *Title = components.lastObject;
NSLog(#"Title: %#",Title);
NSString *Titletest = components.lastObject;
NSInteger comp1 = components.count;
NSString *comps = #"components";
NSLog(#"There are: %ld %#", (long)comp1,comps);
NSLog(#"Title: %#",Titletest);
for (NSInteger i =0; i<15; i++) {
NSString * item;
item=components[i];
NSLog(#"Component:%ld %#",(long)i,components[i]);
}
return cell;
}
//Collection View Cell Data De-Allocation
- (void)
collectionView:(UICollectionView *)collectionView
numberofItemsInSection:(NSIndexPath *)indexPath{
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if(c !=nil){
[self.navigationController pushViewController:c animated:YES];
}
}
//Collection
-(NSInteger)
collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section{
return m_paths.count;
}
//Set Collection View Cell Size
-(CGSize)
collectionView:(UICollectionView *) collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
//Set Landscape size of cells
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-360;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-60;
NSLog(#"Is Landscape");
return CGSizeMake(cellWidth, cellHeigt);
}
//Set Potrait size of cells
else{
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-60;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-160;
NSLog(#"Is Portrait");
return CGSizeMake(cellWidth, cellHeigt);
}*/
return CGSizeMake(collectionView.bounds.size.width, collectionView.bounds.size.height);
}
//Collection View Cell Position
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
if(UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
return UIEdgeInsetsMake(150.0,0.0,150.0,0.0); // top, left, bottom, right
}
else{
return UIEdgeInsetsMake(20.0,0.0,0.0,0.0); // top, left, bottom, right
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[m_coll performBatchUpdates:nil completion:nil];
}
-(void)viewWillTransitionToSize:withTransitionCoordinator{
[m_coll performBatchUpdates:nil completion:nil];
}
/*-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)
collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
CGFloat cellSpacing = ((UICollectionViewFlowLayout *) collectionViewLayout).minimumLineSpacing;
CGFloat cellWidth = ((UICollectionViewFlowLayout *) collectionViewLayout).itemSize.width;
NSInteger cellCount = [collectionView numberOfItemsInSection:section];
CGFloat inset = (collectionView.bounds.size.width - ((cellCount-1) * (cellWidth + cellSpacing))) * 0.5;
inset = MAX(inset, 0.0);
if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"Changed to landscape Spacing");
return inset;
}
else{
return inset;
}
}*/
#end
Clear example to use custom collectionViewCell.
Create a separate class subclass ofUICollectionViewCell see below code:
.h file:
#import <UIKit/UIKit.h>
#interface CollectionViewCell : UICollectionViewCell
#property (weak, nonatomic) IBOutlet UILabel *customLabel;
#end
.m file:
#import "CollectionViewCell.h"
#implementation CollectionViewCell
#end
Now drag and drop the collectionView inside viewController using storyboard then by selecting cell set custom class for it and connect its IBOutlet of label see below image.
Setting up custom class:
Connecting label's outlet: if adding label and other ui component from storyboard
Note: Drag uilabel inside cell before you connect its IBOutlet.
Now configure cell inside your viewController class. And configure collectionView correctly by connecting its delegate, dataSuorce and IBOutlet.
#import "ViewController.h"
#import "CollectionViewCell.h"
#interface ViewController (){
// instance variable deceleration part
NSMutableArray *yourArray;
}
#end
#implementation ViewController
- (void)viewDidLoad{
[super viewDidLoad];
_yourCollView.delegate = self;
_yourCollView.dataSource = self;
yourArray = [[NSMutableArray alloc] initWithObjects:#"1st cell",#"2nd cell",#"3rd cell",#"4th cell", nil];
// Do any additional setup after loading the view, typically from a nib.
}
// collection view delegate methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [yourArray count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"MyCustomCell" forIndexPath:indexPath];
// configuring cell
// cell.customLabel.text = [yourArray objectAtIndex:indexPath.row]; // comment this line if you do not want add label from storyboard
// if you need to add label and other ui component programmatically
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height)];
label.tag = 200;
label.text = [yourArray objectAtIndex:indexPath.row];
// this adds the label inside cell
[cell.contentView addSubview:label];
return cell;
}
//Note: Above two "numberOfItemsInSection" & "cellForItemAtIndexPath" methods are required.
// this method overrides the changes you have made to inc or dec the size of cell using storyboard.
- (CGSize)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(100, 100);
}
} // class ends
Setup the cell identifier (by selecting a cell) MyCustomCell you have given inside cellForItemAtIndexPath method before use see below image:
Note: Change the text color of uilabel to white before because by default collectionView appears black.
Hope here you understand.
Create subclass of UICollectionViewCell. For instance TestCollectionViewCell.
In Storyboard drag label in cell and set "Custom class" for this UICollectionViewCell with your created class. Set Reusable identifier, if your collection view in UIViewController don't forget to set DataSource and Delegate for that collectionView.
Connect IBOutlet in your Cell subclass.
Set at least 1 value inside numberOfItemsInSection method.
Then use your subclass of cell in cellForItemAt and try set text for a label.
You are missing the:
[cell.contentView addSubview:issue];
In my UITable view, i want to be able to switch the positions of two cells when you drag one on to the other. I have already completed this task. The only problem is that when you try to drag one over the other, all the rows that follow shift down to make room for the new one. I do not want this, I want the cells to essentially stay visually static when you are dragging the first cell around. Any ideas?
Thanks,
Mitch
I think you can do this with some trickery, which is after all, how Apple does a lot of its animations.
Start with a UIViewController with a table view as a subview
Add a pan gesture recognizer to the main view (you'll have to implement shouldRecognizeSimultaneouslyWithGestureRecognizer: and return YES, so it will work with the table view's own gesture recognizers)
When you start to drag, create a snapshot view of the cell you started the drag over, and add it as a subview of the main view. You'll probably want to disable the table view's scrolling at this point also.
Drag that snapshot view using the pan gesture recognizer's translationInView property
When you drop the view, delete the snapshot view, and update the table's data source to show the data in the new order you created with the move.
I haven't tried all of this yet (but I've used some elements of it in other projects), but I think this should give you a start on what you're trying to achieve. There are some more details to work out for sure -- what do you want to see in the spot from where you dragged the cell? A blank space? What do you want to see when the dragged view is dropped?
After Edit:
This is what I have so far, and it works pretty well. In the storyboard, I have a UITableViewController with two cell prototypes, both basic types. The one whose identifier is "Blank" just has no text in its label. The tableviewController is embedded in a navigation controller, and I've added a button to the navigation bar with the initial title of "Drag" -- this button is connected to the toggleDragging method.
#interface TableController ()
#property (strong,nonatomic) NSMutableArray *theData;
#property (strong,nonatomic) UIPanGestureRecognizer *panner;
#property (strong,nonatomic) UIView *cellSnapshotView;
#property (strong,nonatomic) NSIndexPath *draggingCellIndexPath;
#end
#implementation TableController
- (void)viewDidLoad {
[super viewDidLoad];
self.panner = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveCellImage:)];
[self.tableView addGestureRecognizer:self.panner];
self.panner.enabled = NO;
self.panner.delegate = self;
self.draggingCellIndexPath = [NSIndexPath indexPathForRow:-1 inSection:0];
self.theData = [#[#"One",#"Two",#"Three",#"Four",#"Five",#"Six",#"Seven",#"Eight",#"Nine",#"Black",#"Brown",#"Red",#"Orange",#"Yellow",#"Green",#"Blue",#"Violet",#"Gray",#"White"] mutableCopy];
}
-(IBAction)toggleDragging:(UIBarButtonItem *)sender {
if ([sender.title isEqualToString:#"Drag"]) {
self.panner.enabled = YES;
sender.title = #"Scroll";
}else{
self.panner.enabled = NO;
sender.title = #"Drag";
self.tableView.scrollEnabled = YES;
}
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
-(IBAction)moveCellImage:(UIPanGestureRecognizer *)panner {
if (! self.cellSnapshotView) {
CGPoint loc = [panner locationInView:self.tableView];
self.draggingCellIndexPath = [self.tableView indexPathForRowAtPoint:loc];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.draggingCellIndexPath];
self.cellSnapshotView = [cell snapshotViewAfterScreenUpdates:YES];
self.cellSnapshotView.alpha = 0.8;
self.cellSnapshotView.layer.borderColor = [UIColor redColor].CGColor;
self.cellSnapshotView.layer.borderWidth = 1;
self.cellSnapshotView.frame = cell.frame;
[self.tableView addSubview:self.cellSnapshotView];
self.tableView.scrollEnabled = NO;
[self.tableView reloadRowsAtIndexPaths:#[self.draggingCellIndexPath] withRowAnimation:UITableViewRowAnimationNone]; // replace the cell with a blank one until the drag is over
}
CGPoint translation = [panner translationInView:self.view];
CGPoint cvCenter = self.cellSnapshotView.center;
cvCenter.x += translation.x;
cvCenter.y += translation.y;
self.cellSnapshotView.center = cvCenter;
[panner setTranslation:CGPointZero inView:self.view];
if (panner.state == UIGestureRecognizerStateEnded) {
UITableViewCell *droppedOnCell;
CGRect largestRect = CGRectZero;
for (UITableViewCell *cell in self.tableView.visibleCells) {
CGRect intersection = CGRectIntersection(cell.frame, self.cellSnapshotView.frame);
if (intersection.size.width * intersection.size.height >= largestRect.size.width * largestRect.size.height) {
largestRect = intersection;
droppedOnCell = cell;
}
}
NSIndexPath *droppedOnCellIndexPath = [self.tableView indexPathForCell:droppedOnCell];
[UIView animateWithDuration:.2 animations:^{
self.cellSnapshotView.center = droppedOnCell.center;
} completion:^(BOOL finished) {
[self.cellSnapshotView removeFromSuperview];
self.cellSnapshotView = nil;
NSIndexPath *savedDraggingCellIndexPath = self.draggingCellIndexPath;
if (![self.draggingCellIndexPath isEqual:droppedOnCellIndexPath]) {
self.draggingCellIndexPath = [NSIndexPath indexPathForRow:-1 inSection:0];
[self.theData exchangeObjectAtIndex:savedDraggingCellIndexPath.row withObjectAtIndex:droppedOnCellIndexPath.row];
[self.tableView reloadRowsAtIndexPaths:#[savedDraggingCellIndexPath, droppedOnCellIndexPath] withRowAnimation:UITableViewRowAnimationFade];
}else{
self.draggingCellIndexPath = [NSIndexPath indexPathForRow:-1 inSection:0];
[self.tableView reloadRowsAtIndexPaths:#[savedDraggingCellIndexPath] withRowAnimation:UITableViewRowAnimationNone];
}
}];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.theData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([self.draggingCellIndexPath isEqual:indexPath]) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Blank" forIndexPath:indexPath];
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.theData[indexPath.row];
return cell;
}
This may be helpful, you can respond however you like to the delegate calls to achieve this effect:
https://github.com/alfiehanssen/AMHEditableTableView
Let me know if you have any questions,
I have a UITableView with some custom cells. In each cell, there is a ImageView and three labels and get the data from a string array. I have done the layout in my storyboard. The data source is a string array. This works.
Now I have insert a EditButton in the code. Now i can see the EditButton, but when I activate the edit mode the table cell will be resized, but the images and labels dont move.
Can you show me how to move the content of the cell? Who knows a tutorial with UITableView uses EditMode AND storyboards. All tutorials which I have found are based on the "old" Xcode.
Thank you very much
By the way, here is my code:
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
myData = [NSMutableArray arrayWithObjects:
#"Line1_Label1|Line1_Label2|Line1_Label3",
#"Line2_Label1|Line2_Label2|Line2_Label3",
#"Line3_Label1|Line3_Label2|Line3_Label3",
nil];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myData count];
}
// Return a cell for the table
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// A cell identifier which matches our identifier in IB
static NSString *CellIdentifier = #"CellIdentifier";
// Create or reuse a cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Get the cell label using its tag and set it
NSString *currentItem = [myData objectAtIndex:indexPath.row];
NSArray *itemArray = [currentItem componentsSeparatedByString:#"|"];
UILabel *cellLabel = (UILabel *)[cell viewWithTag:1];
[cellLabel setText:itemArray[0]];
UILabel *cellLabel2 = (UILabel *)[cell viewWithTag:3];
[cellLabel2 setText:itemArray[1]];
UILabel *cellLabel3 = (UILabel *)[cell viewWithTag:4];
[cellLabel3 setText:itemArray[2]];
// get the cell imageview using its tag and set it
UIImageView *cellImage = (UIImageView *)[cell viewWithTag:2];
[cellImage setImage:[UIImage imageNamed: #"control.png"]];
return cell;
}
// Do some customisation of our new view when a table item has been selected
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure we're referring to the correct segue
if ([[segue identifier] isEqualToString:#"ShowSelectedMovie"]) {
// Get reference to the destination view controller
ItemViewController *vc = [segue destinationViewController];
// get the selected index
NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row];
// Pass the name and index of our film
[vc setSelectedItem:[NSString stringWithFormat:#"%#", [myData objectAtIndex:selectedIndex]]];
[vc setSelectedIndex:selectedIndex];
}
}
#end
First of all, make an IBOutlet of the tableview in the .h and synthesize it in the .m.
Then make an action to the edit button (if you don't already have one). In the action, write:
CGRect rect = yourTableView.cell.contentView.frame;
//Do whatever changes you wish to do with the sizing of the view. origin changes placement and size changes size (duh). Line below is an example.
rect.origin.y = yourTableView.cell.contentView.frame.origin.y - 20;
yourTableView.cell.contentView.frame = rect;
This won't be animated, but I think it'll fulfill your purpose.
Overwrite the -(void)layoutSubviews{} - method of your custom UITableViewCellController.m or if you don't use a custom UITableViewCellController, try it in your UITableViewController. But I haven't tried it yet with no custom UITableViewCellController.
Something like this will do the trick:
-(void) layoutSubviews {
[super layoutSubviews];
CGFloat xPositionOfElementInTableCell = 273.0f; /* the position of the element before going into edit mode */
if (self.isEditing && !self.showingDeleteConfirmation) // if we enter editing mode but not tapped on the red minus at the moment
{
xPositionOfElementInTableCell = 241.0f;
} else if (self.isEditing && self.showingDeleteConfirmation) // after we tappet on the red minus
xPositionOfElement = 193.0f;
}
CGRect frameOfElementInTableCell = self.myElementInTableCell.frame;
frameOfElementInTableCell.origin.x = xPositionofElement;
self.myElementInTableCell.frame = frameOfElementInTableCell;
}
I hope it helps you. The idea for this code is not mine. I found it here in SO, too. Don't know where exactly.
I am using a UICollectionView programmatically.
I've set its frame as follows:
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 3000) collectionViewLayout:flowLayout];
My UICollectionViewFlowLayout has a section inset set as:
flowLayout.sectionInset = UIEdgeInsetsMake(20.0, 20.0, 100.0, 20.0);
I also only have 1 section.
I've set the height to be 3,000 to see if the collection view would scroll but it doesn't. I am setting it to that since the collection view doesn't seem to scroll up or down when I insert new items.
UICollectionView is subclassed from a UIScrollView, which means I can keep resetting the scroll view content size. Would this work properly?
The only issue is that this would work if I know the sizes of all items including how many items are on each row.
If each item had a different size, how would I find out the size of each row? I would need that to add all row sizes and increase the content size height of self.collectionView.
EDIT
Even my suggestion above, resetting the content size, does not work properly! I tried the following when updating my collection view:
int numberOfRows = self.dataArray.count / 3;
self.collectionView.contentSize = CGSizeMake(self.view.frame.size.width, (numberOfRows * 200) + 300);
This is very ugly though. This is because it assumes all my images are of size 200x200px, which fits 3 images per row (hence the division by 3).
Furthermore, even with the +300 that I have, the last row I can only see about 3/4 of it and not all of it. I have to scroll more and I will be able to see it but it goes back up again to 3/4. Its kind of like the scroll to refresh, where the view only moves if you drag it and when you leave it bumps back to where it was. Why is this happening? Is it just that Apple designed UICollectionView so poorly? This is a little ridiculous... UITableViews adjust their scroll according to their content automatically.
In answering some of your other questions about UICollectionView, I created this demo project, and it scrolls just fine, so I don't know what problem you're having. The only thing I needed to do to make the last row wholly visible was to increase the size of the bottom inset to 90. I also added a completion method to the performBatchUpdates:completion: to automatically scroll so that the last added item is visible (notice that I add some extra items by using performSelector;withObject:afterDelay:). My images are 48x48, and I just set my collection view to the bounds of my controller's view. Here is the code so you can compare it to what you have:
#interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> {
NSMutableArray *newData;
}
#property (nonatomic, retain) UICollectionView *collectionView;
#property (nonatomic, retain) NSMutableArray *results;
#end
#implementation ViewController
- (void)viewDidLoad {
self.results = [NSMutableArray array];
int i = 11;
while (i<91) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"New_PICT00%d.jpg",i]];
[self.results addObject:image];
i++;
}
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
//flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
self.view.backgroundColor = [UIColor blackColor];
[self.view addSubview:self.collectionView];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
//[self.collectionView registerClass:[RDCell class] forCellWithReuseIdentifier:#"myCell"];
[self.collectionView reloadData];
[self performSelector:#selector(addNewImages:) withObject:nil afterDelay:3];
}
-(void)addNewImages:(id)sender {
newData = [NSMutableArray array];
int i = 102;
while (i<111) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"New_PICT0%d.jpg",i]];
[newData addObject:image];
i++;
}
[self addNewCells];
}
-(void)addNewCells {
NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
[self.collectionView performBatchUpdates:^{
int resultsSize = [self.results count];
[self.results addObjectsFromArray:newData];
for (int i = resultsSize; i < resultsSize + newData.count; i++)
[arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
[self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];
}
completion: ^(BOOL finished){
[self.collectionView scrollToItemAtIndexPath:arrayWithIndexPaths.lastObject atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
}];
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return [self.results count];
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
//cell.iv.image = [self.results objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor colorWithPatternImage:[self.results objectAtIndex:indexPath.row]];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
UIImage *image = [self.results objectAtIndex:indexPath.row];
return CGSizeMake(image.size.width, image.size.height);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(10, 10, 90, 10);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Selected Image is Item %d",indexPath.row);
}
Setting the height of the UICollectionView to 3000 will make your scrolling problem worse. If the UICollectionView is 3000 pixels tall then it will only ever need to scroll if it has more than 3000 pixels worth of content in it. You should set it to the height of the view it is contained in (same as the width).
AFAIK the also should not set the contentSize directly, instead you need to override the - (CGSize)collectionViewContentSize method in a subclass of UICollectionViewLayout, but generally speaking you shouldn't need to change the content size for normal uses.
I'm not totally clear on what your problem is - is it that when you add more than a screens worth of items you can't scroll?
I've encountered the same problem because I was initializing the elements of my collectionView (i.e. it's DataSource) in the viewWillAppear method.
I finally add just a [self.collectionView reloadData]; and it works just fine!
Maybe you're in the same case.