How to implement collection view like this? - ios

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

Related

Detect section of UICollectionViewCell

I have got UICollectionView with custom layout, so there is a row of items, that are scrolling with paging. Also there is a multiple sections, so the final view is like an App Store example of final view is as below,
Problem is, to place in each section footer a page control, that will detect current page of section. I don't know how to detect in witch section scroll view offset was changed. Will appreciate any help or another solutions!
You can get the section and row in which the collection view was selected using the following delegate method.
// Swift
func collectionView(_ collectionView: UICollectionView,
didSelectItemAtIndexPath indexPath: NSIndexPath)
// Obj-C
- (void)collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
Here, this method is invoked on the delegate only when a cell is selected. It returns indexPath.
indexPath contains two property you are asking for right now.
indexPath.row - Gives the item currently selected item index in section.
indexPath.section - Gives the current section being used in the collectionView
Note: Counting Starts from 0, not 1.
So if I selected "ComboCritters" ( Look image above), I would get 0 for indexPath.section referring to the "New Games we love! " and, 2 for indexPath.row saying the 3rd item is selected.
And, that's how you get the selected section in your app.
Kind Regards,
Suman Adhikari
You can't have the three sections highlighted in red in your diagram as separate sections in the same collection view if you want them to independently scroll. Scrolling happens to the entire collection view, not to one section of it, unless you have a very complicated layout subclass.
It would be far simpler to have three collection views, one for each section.

How to not reuse UITableViewCell and keep cells in memory after they disappear from the view?

I have a "not so big" dynamic tableView with a number of rows that can vary between 10 and 20.
I used Storyboard and created 4 different cell prototypes which all have their own identifier. Most of these cells have UITextFields in them and the user will enter information such as e-mail adresses etc...
I use dequeueReusableCellWithIdentifier: in tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) to create my cells.
However whenever I scroll my tableView I can see that the appearing cells get the data from upper cells, because cells that disappear are enqueued for reuse.
Given the fact that I have a limited number of cells, I would like to get rid of the reusing feature and just have my set of cells with their own data inside. When I scroll down I see cells that correspond to the lower cells, and when I go back up I see again my upper cells.
How can I do that?
and how can I then create a cell that corresponds to a prototype from the storyboard without using dequeueReusableCellWithIdentifier: ?
I have already searched among similar question here in StackOverflow and tried to keep an array of my cells and just return the correct element if it already exists from tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) but nothing worked so far
You are overthinking this a bit. If you think about what dequeueReusableCellWithIdentifier: does, it just grabs a cell that it finds with that specific identifier. If you want every row to have it's own unique cell that is not used by any other row, just give each row it's own identifier. The simplest way would be to just to stringify the indexPath row, or both the row+section if you have multiple sections.
Something like this should do it:
let cellIdentifier = String(indexPath.section) + "-" + String(indexPath.row)
In these cases I will typically create what would be the content of the table view cell in its own view controller or custom view, something like "SignupFormViewController", and store that as a property on the view controller that is managing your table view. In your case this could also be multiple view controllers of this type in several properties or an array. Then dequeue your cells as normal but treat them as dumb containers to which the view controllers' views are added as subviews. Then you'll just to have tie up all the loose ends—removing the view from the cell when the cell dequeued, not adding a view if the identical view is already a child of the cell, constraints to match cell size, etc.

UICollectionView: Get indexPath of Cell that is not visible

I have a UICollectionView with several cells – there are always some of them outside the viewport, so there are cells being reused.
When an event occurs I want to take a specific cell and move it to the front of the UICollectionView. In order to make moveItemAtIndexPath() work I need to know the current indexPath of the Cell that I want to move.
When I initialize the Cells in the CollectionViewDelegate with the cellForItemAtIndexPath method I save its indexPath into a variable of the Object that is the model of the Cell (not it’s actual Object, just the model). Then I look at this variable when I want to move the cell.
This is working fine as long as the cell was visible once – it seems like it only initiated then, even though it is part of the CollectionViewData all the time.
How can I make sure my CollectionViewCell has an indexPath, even when it is not visible or has not been visible yet?
If you know what data (cell) you want to present at the front (I assume top) of your UICollectionView, why don't you just update your dataSource and reload your UICollectionView?

Can you store state in a custom UICollectionViewCell? Or can the state get erased (like when the cell scrolls off the screen)?

If I create a UICollectionViewCell subclass like:
class StudentCell: UICollectionViewCell {
var student: Student?
}
And in my controller I implement UICollectionView's didSelectItemAtIndexPath and set the variable:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
if let studentCell = collectionView.cellForItemAtIndexPath(indexPath) as? StudentCell {
studentCell.student = self.someStudent
}
}
When I click on the cell it should set student, but if the cell is scrolled off screen it seems like the whole cell might get wiped and when it comes back on screen it would need to rebuild itself in cellForItemAtIndexPath.
The problem I have is that I have a UICollectionView with cells that do not scroll off the screen that I'm storing data in. Because they don't leave the screen I assume they should not get wiped, but one of the cells does not seem to keep it's variable, which makes me think maybe it's getting wiped and I may need to move the state outside of the cells to a dictionary or something and in didSelectItemAtIndexPath instead of setting the variable in the cell I'd set the dictionary. Whenever I need to access the data instead of asking the cell for it I'd look it up in the dictionary.
But either way, I was wondering if it's possible (or a bad idea) to set it in the cell or not.
Yes, cells in both UICollectionView and UITableView can (will) be reused at the systems discretion and should not be used to store state information, only display information. Specifically, both views will reuse cells when they are scrolled off-screen, but there's no guarantee this is the only time they'll be reused. The usual way to handle this is to define some kind of cell data object which stores the data for each cell (visible and not) and refresh the cell view from that as needed/requested.
Tables display their data in cells. A cell is related to a row but it’s not exactly the same. A cell is a view that shows a row of data that happens to be visible at that moment. If your table can show 10 rows at a time on the screen, then it only has10 cells, even though there may be hundreds of rows with actual data. Whenever a row scrolls off the screen and becomes invisible, its cell will be re-used for a new row that scrolls into the screen.

UITableView inside custom UICollectionView

As the title says, i'm trying to put one UITableView inside a custom UICollectionViewCell, i made it so it's perfectly displayed, but now i need the touches inside the Cell that contains the Table to call the didSelectRowForIndexPath method.
I have a .xib for this custom UICollectionViewCell, inside it i have the UITableView, and i have it's delegate and datasource correctly set.
Now, if i run this, the CollectionView cells are loaded with their proper data (this is, each cell with a table containing the proper rows), but if i try to select one row from one table, the CollectionViewCell is selected instead of the TableViewCell (this is expected, but not what i need).
I'd like to know if is there a way for the TableView row to get selected, even if it's inside a CollectionView cell.
Thank you and sorry for my english.

Resources