Find Index Number Of A Specific UICollectionView Cell - ios

I have a UICollectionView that returns 77 cells. I'm trying to figure out how to point to a specific cell, for instance the cell at row 2, column 4. To boil it down to my very basic need I need to write a statement that would do this:
if cell[46] == cell[12] {
println("they match")
}
I do not know where to start with this task. I started by trying to print the indexPath that is being used in my prepareForSegue method but that's not returning anything.
This collection view is using dynamic cells. Would it any difference to make them static cells?

There exists collectionView?.visibleCells() which returns [AnyObject] which you can cast to be of type UICollectionViewCell so you can get an array of on screen cells. Then you can access specific cells using subscript notation for comparison, but I still don't think directly comparing the cells is the best approach and if you can store your data in such a way that you can easily access the values without making a request to the server each time, that would be a much better approach for what you're attempting to accomplish.

As mentioned by #jkaufman, you need to use a method that gets you a cell from an index path. func cellForItemAtIndexPath(_ indexPath: NSIndexPath) -> UICollectionViewCell? is the method you would need, and you can pass it an index path, which can be constructed with a section and row index. From there, you could get each of your cells, and do the comparison after retrieving both cells from the cellForItemAtIndexPath.
Function documentation: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/#//apple_ref/occ/instm/UICollectionView/cellForItemAtIndexPath:

Related

UICollectionView scroll to specific cell

i try to create a UICollectionView who should open at a specific cell.
My approach is to store all cells:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) ->
UICollectionViewCell {
// my code
cells.append(cell)
return cell
}
then find the desired cell in viewDidAppear:
let result:[MyCell] = cells.filter{ $0.myProperty!.uuid == selectedUUID }
Unfortunately the desired cell can't be found within the cells array, because not all cells are stored yet.
Am i going in the right direction or do i need a different solution?
EDIT: removed misleading information
Don't work with the cell themselves.
Your cells are displaying data, right? They must. That data (could be numbers, or text, or an image, anything) should be a custom object.
For example, you're displaying a list of animals.
So you have the Animal class, with different properties (Size, weight, age). Again, all an example. Maybe you're displaying a list of students which have a FirstName, Lastname, and so on. Lets say we're using the Animal.
You have an array of Animal objects, you can have 1, or 4, or 234234, it doesn't matter. The array can hold as many animals as you want. But you only have one array.
Your collection view (or tableview) needs to create a cell for each row. How many rows?! Easy, the other methods tells us there are a specific number of rows per section. Let's say we only have one section.
How do you define rows? You give him a number. What number? The number of animals in your array. For example, 5. Or, much better, myAnimalsArray.Count. Now if you have 20 animals, you'll have 20 cells. If you have 3 animals, you'll have 3 cells.
Okay, now to the cells, you know how many you have, and the cellForRow will therefore create X cells, X being the count of your array.
You'll probably have a simple cell for testing, like
cell.title = animal.name
and then return the cell. It's all pseudo code here, but you get the idea.
Now to your actual question
I've written all that because, according to your other comments in the other answers, you seem pretty confused.
You have your animal array (the data), and no cells yet. You want to start on the animal that has a name starting with E, for example. Well, after you've all the animals on the array, you need to find the one that starts with E (or any other filter you might like). You find it with a searching method. Once its done, you will know the index of the animal in the array. It's the array item number 23, it's the Elephant.
Create an NSIndexPath object with section 0 and index 23 (because your filter found it's the 23rd item, again, i'm just using examples), and pass that indexPath object to the scroll method of the collectionview.
And you're good ;)
Do that in the ViewDidLayoutSubviews or viewDidAppear. (first one is better). But you must do it after your array of animals is loaded, otherwise you won't have any data to filter.
Once you've called the method in the link above, your collectionview will scroll, and if you've done it soon enough, it will load at that index and not at index zero.
i have solved this problem through this code hope it will helpful for you:
[self.collectionview setContentOffset:CGPointMake(0,self.collectionview.contentSize.height-self.collectionview.frame.size.height/2) animated:YES];
set above only parameter to contentsize:CGSizemake(x,y);
by adjusting your required parameter you can scroll to specific cell.
just replace above parameter inplace of c and y in contentsize:CGSizemake(x,y); method.
and you have to adjust parameter.
UICollectionView's cell is reused.
For example, if view can only show 3 cells once: A, B , C; then ur cells maybe like [A, B, C, A, B, C, A, B, ...];
each time, u set the property of cell, uuid will be reset to a new value.
so u cant filter out what u want.
Hitendra Hckr is right, u should "filter data array instead of filtering cells array".
Or u can "alloc" new cell instead of "dequeueReusableCellWithReuseIdentifier:forIndexPath:".(Not recommend)
For your case, you need to filter data array instead of filtering cells array, this way you can get exact index.
Based on the filteredIndex create indexpath using below method,
NSIndexPath(forItem: filteredIndex, inSection: yourSectionIndex)
This way you can scroll to particular cell.
Try adding a call to collectionView.reloadData() before scrollToItemAtIndexPath. This will ensure all required cells are created.

What does queueReusableCellWithReuseIdentifier do in Xcode?

I am working with open source iOs app and came across this:
queueReusableCellWithReuseIdentifier
How do you use this? I kind of think I may have an idea of it - perhaps it is a variable that is passed through multiple times? Do you use it each time? I'm a beginner, so any help will be appreciated. Thank you so much!
Think about all the cell of a table view exists in an array of cells.
Once the table view wants to load a cell it calls this method with the indexPath (to insert it into the right index) and identifier to recognise the cell (if you have multiple cells)
Now, if the this method return nil. Then the "array of cells" does not contains a cell that can be reused, and the a cell needs to be initialised.
This method if for performance issues mainly, so you will not have to instantiate a instance of a cell every time you want to load a cell.

iOS Dynamic cell content

I have searched for this a lot and haven't found what I am looking for.
I want to have UITableViewCell such that each have dynamic content. For example, one cell can have a place name, address, phone number, image, etc. Another cell can have some or all of these attributes.
I know that I should have functions cellForRowAtIndexPath: and heightForRowAtIndexPath: return stuff appropriately.
The problem I am facing is that I have my cells designed in nib files, and am loading the layout from there. I can calculate the heights for each cell based on conditions(though this is tedious), also I need to arrange stuff in that cell if one thing is missing. For example, if place name is missing then move all the elements up via setFrame:.
There should be an easy way out I believe?
In such dynamic cases I would not bother with using storyboards to accomplish this. It should be very easy to do this programatically...
If you really do need to create this in a storyboard you could generate a full cell which could consist of (for instance) 5 labels. Now in the table view data source I presume you have some array of objects where each element represents a single row in the table view. If so then in your case each of this object can have a method that will return an array of non-empty strings (the strings that will actually be displayed) which can be a dynamical count from 1 up to 5 strings.
If you do this you will request this array in method requesting the height for row at index path and by using this count you can then return the height of the row (for instance numOfStrings*40.0f). Inside the method requesting your cell you can simply fill those labels with the same array you use to calculate the height.
As for non storyboard approach I suggest you to override an UITableViewCell, generate a static method that will return you the cell height for string count and generate an initializer with the string array which should then iterate through the array generating the labels and setting the text to it.

iOS 7: Two different heights for cells in a table inheriting from the same UITableViewCell

I need "Two different heights for cells in a table inheriting from the same UITableViewCell".
A bit more on this. I am using iOS 7 and storyboard. I created on the story board two different UITableViewCell prototype for a UITableView with custom cells.
I then created a class, MyUITableViewCell which defines the beheaviour of the cell as well as a protocol method that is then implemented by the delegate (which is in my case is the UITableViewController class where the UITableView containing the cells is).
Now.. I would like to dynamically set the row of the cells according to whether the cells is of type 1 or type 2.
I have found this method:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// if(indexPath) refers to cell of type 1 then
// return 240;
// else return 120;
// I created a NSDictionary with data that includes the type of cell information, however I am not sure how to link indexPath to the dictionary. The keys of the dictionary are ids and not array indexes.. so I am a bit lost in here..
}
As said in the comment:
"I created a NSDictionary with data that includes the type of cell information, however I am not sure how to link indexPath to the dictionary. The keys of the dictionary are ids and not array indexes.. so I am a bit lost in here.."
I would like to find a solution to this but not sure if it is possible using only NSDictionary or if I need some other hack...
Sure you can do that. The cells in your table view are data backed, you must have access to the data that defines the table in the table view delegate.
If your table is simple with only one section then you might only need to look at indexPath.row. There must be some way to relate this value to your data, if there is not you will not be able to populate the cell in cellForRowAtIndexPath either.
Often the indexPath.row value can be used as an index into an array containing data, such as [tableDataArray objectAtIndex:indexPath.row]; In your case, if the data is a dictionary, what are the keys? Maybe you can make a key directly from the row ([NSNumber numberWithInteger:indexPath.row], since a key must be an object) or maybe you need to use an array to translate the NSNumber produced from the index paths into the keys that are used in your dictionary. If your data is pre-existing and it would be a lot of work to change it this might be the best way, otherwise think about organising your data for easy access.
An alternative would be to use a UICollectionView, where with a custom UICollectionViewLayout you can define the frame of every cell individually at the time you report attributes for the cell. However you still need a way to relate index path to the underlying data. It is more versatile than a UITableView and is possibly a more useful skill to develop with the state of iOS development today.

Alternative method for getting reference to a UITableviewCell?

The design of the app I am working on, specifically the tableview part is quite complicated.
There are around 5-6 methods in which I need to get a reference to particular cell from the table view.
What I do not like is that I have to use the
-tableview:cellForRowAtIndexPath
This is a datasource method and does a lot of heavy lifting. Custom cell configuration, dequeueing, getting data for particular cell..etc.. The point is all this code is executed again,even if it does not make any sense at all. The cell object is completely loaded already.
Am I right in my observation and if yes, is there a working tested and lightweight solution?
Perhaps there could be an index of references to all cells. Asking it, I would immediately get the reference without the datasource code.
UITableView has cellForRowAtIndexPath: method.
From UITableView reference:
Returns the table cell at the specified index path.
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
Parameters
indexPath The index path locating the row in the receiver.
Return Value An object representing a cell of the table or nil if the cell is not visible or indexPath is out of range.

Resources