I am trying to implement collectionview which have functionality when I click on plus cell a new cell will be added and when I click on cross icon cell will be removed and plus cell needs to be moved to the removed cell position,here I am attaching design for reference
design here
You need two separate cell layouts for this design.
In the function that returns the number of items in your UICollectionView, simply add one for the last cell.
For object 0..n (where n is the number of data objects in your collection) you then return your custom data cell. For object n+1, you return the cell layout for the "New Item Cell".
You should tak a look at the UICollectionViewDataSource protocol.
collectionView(_:numberOfItemsInSection:)
UICollectionViewDataSource
If I have 2 prototype cells and each row has a timestamp. Is it possible to sort cells based on the timestamp of their rows? or second cell will be always under the first one? Example below. This is general question, so I want to know in which direction should I look
Prototype cell 1
Prototype cell 2
Prototype cell 2
Prototype cell 1
Update with some code
Basically I have first prototype cell which I already sorted by timestamp and it's working fine.
func attemptReloadOfTable() {
self.messages.sort(by: {$0.timestamp < $1.timestamp})
self.tableView.reloadData()
}
Later I added another prototype cell which provide date which should be sorted within first prototype cell and the second one. Second prototype cell also has timestamp and I'm not sure how to mix them.
I have a tableView with 2 prototype Cells.
The first Prototype Cell has a TextField and Button on the right. Let's say it "Cell1"
The second Prototype Cell has only a label. Let's say it "Cell2"
I just want to type something in the first cell and then by taping the Button to :
1) Create a new Cell2 Prototype Cell Row
2) That new Cell2 Prototype Cell Row must have a Label with the value i entered on the Cell1 TextField.
So with that way i could have a list of Cell2 Rows with different values of TextField.
I know how to achieve the first (the new Row created) but not the second.
When the segue starts, i have only the Cell1 Prototype like this photo :
And when i tap the + Button, i have a new Row of "Cell2" Prototype.
This kind of Cell must have the label of the Textfield everytime.
How can i take the value of TextField everytime and pass it to new created Cell2 Row Label?
In all probability your difficulty is merely that your data model is a little too simple-minded. Keep in mind that all the work must be done by your cellForRowAtIndexPath: implementation consulting the data model. Thus the data model must know two things for each row:
Is this a prototype 1 row or a prototype 2 row?
What is the text field (if this is a prototype 1 row) or label (if this is a prototype 2 row) value for this row?
Given a data structure that carries that information, it is clear enough how to proceed:
As the user types in a text field, the text field delegate should enter the text field's text into the model at that row.
When the user hits the Plus button, we figure out what row this is and insert into the data model, immediately after the current row, a new entry marked as a prototype 2 row with the same text value as the current row. We then insert the row into the table as well, so that our cellForRowAtIndexPath: is called for the new row.
Given those simple instructions, it's quite easy to build a working example of the sort of thing you're trying to do:
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.
I have UITextField and an ImageView inside UICollectionView cell. It loads data from web service. The user can input data inside the text field and have to submit it. My problem is, when I scroll the collection view, the entered value in one text field in a cell got messed up with other text field values from another cell, and it displays wrong values.
my steps(suppose I have cells A, B, ......., k)
1.entering values
Cell A Textfield= 12
Cell B Textfield= 13
2.scrolling down
(I haven't entered anything in cell F Textfield, though it shows 13)
3.scrolling back to where I entered values
Cell A Textfield= 12
Cell B Textfield= (blank)
You can solve this problem by keeping the values of UITextField in an Array. Whenever you are entering value to UITextField and dismissing keyboard,then save that value to array at the same cell index value in array and when you scroll your collectionView, the textfield value should entered from array and it won't misplace value.
UICollectionView and UITableView reuse a handful of cell objects as you scroll. This helps with memory management. It also means that when you populate one text field on a cell, that text field's cell will get reused for a different row as you scroll, so if you don't reset the text field's content, you'll see the same data showing up for the wrong rows.
The solution is that your "source of truth" (aka model) must always be separate from your UI. So when the user types something in a text field, your model (perhaps an array of strings?) should be updated accordingly. Then when the user scrolls, you must use tableView:cellForRowAtIndexPath: or collectionView:cellForItemAtIndexPath: methods to populate the cell with the appropriate data. If there is no data, you must clear any data that may have been left over from another row whose cell got reused.
Other opportunities you'll have to deal with cell reuse include the willDisplayCellForRowAtIndexPath method on UITableViewDelegate, or prepareForReuse on UITableViewCell. Collection view objects have corresponding methods as well.
As far as I can understand from question I think the problem is, you are not updating values every time - cellForRowAtIndexPath function gets called on scrolling.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
what you need to do to resolve this issue is "You have to store all the values you have entered in your cell's textField and whenever above datasource method gets called for UITableView, updated cell accordingly".