iOS Maintaing selected button in Tableview when scrolling - ios

I have a UItableView with custom cell. There are multiple sections, and in those sections multiple rows. In each cell, I have a segment button for "Yes" and "No" selections. I would like to maintain the selections for the segment button when I scroll up and down the table. Can anyone please help. I have looked and did not find anything that helped me. Thank you!

You have multiple ways to do this.
The first one, which I think is the best one, is to use the selected state for the uitableviewcell.
With this method, the table view it self will set the cell's state and according to that state will call didselect or diddeselect on its delegate. Since all is managed by the table view, you don't need additional logic on your cellForRow method, and don't even need to worry about cell reuse.
Another way is to always set the state of your cell's buttons in cellForRow. For this, you need to keep a reference to all the selected rows, and to be able to manage reused cells, you need to make sure its state is always set on cellForRow.
I prefer the first one, but whatever suits you better.

Related

Is it possible to change attribute of individual UITableViewCell?

Is it possible to make changes to a particular UITableViewCell? For example, change the text in one cell of a table view with a button click?
It's possible, but you should not do that.
As you said in your comment, you can ask the table view for a cell and then make changes to that cell, but don't do that.
You should do what HHumorous said, and change your data model, then tell the table view to reload the affected cell.
If you simply change the appearance of the cell, then when the user scrolls that cell off-screen and then back on-screen the changes will be lost.

UITableView trigger when cell is reused

I'm having some issues with reusable cells in a UITableView. I have several types of cells, that I declare in the constructor.
My issue is that I have one particular type of cell that contains a UITextView and I have an issue when I scroll the table, the text within is lost. I need to save this text to the models that accompany the cells and then put the text back when the cell is used again.
How do I know that the cell is being moved away from? I have other types of cells, so I need a way to invoke some code to do the saving part on the scroll of the UITableView.
I hope that makes sense, if more is required, let me know.
Thanks.
Just save the text once it is changed to the model, check if any text is present and use that in tableView(_:cellForRowAt:)
For more help you will have to show us your code.
You can inherit UITextViewDelegate and in the textViewDidEndEditing(_:) check if the text view is edited, then you will be able to store the text in a variable or somewhere else and restore it whenever you are about to show that cell again.
If there is more than one text view, you might want to set an accessibility identifier for each kind, so you will find out which one did end editing.

Is it possible to have a UITableView with one row always in edit mode, showing its insertion or deletion control? If so, how?

I have a UITableView with some data, and I'm hoping to put in the top row or section a cell (call it, "Add Record" or something), which is always in edit state, so that it always displays the system insertion control. Is this possible? If so, how?
I've searched all around for this. Apple's documentation lists a setEditing(_:animated:) method on UITableViewCell. I used both that and setting isEditing to true on the cell on load, and it appears to be in isEditing state because the table wouldn't let it be selected until I turned on 'single selection in edit state'. But no insertion or deletion controls show up, and the delegate's tableView(_:editingStyleForRowAt:) is never called.
The cell looks fine if I call setEditing(_:animated:) on the table view itself, but that sets every cel to editing, deletion and all! That's not what I want.
I suppose I can just use a normal cell, and use an image of an insertion control, but I'd rather use Apple's system one if possible (since they might change). Aside: I could always load up an editing table on load and cache a snapshot of an editing control, but that's waaaay more work than its worth!
Is what I'm going for even possible? Do you understand what I'm going for? Any advice you could provide would be very helpful.
You can try the following approach:
Keep using setEditing on the UITableView itself.
To show the editing controls only for a specific cell, implement the
canEditRowAtIndexPath method of the
UITableViewDataSource delegate and return true only for the cell that you wish to allow editing for.
At this point your specific cell will show the editing controls, but the cells are not selectable; you'll need to set allowsSelectionDuringEditing on your table-view
to allow the cells to get selected. Next, you will probably want to
prevent the editing cell from being highlighted by implementing
shouldHighlightRowAtIndexPath delegate method and return true for
all cells except for the cell that you want to keep in editing mode.
Other possible solutions:
Create your own UITableViewCell and implement the editing UI yourself (which will always be visible), then use this cell where you need it.
Use another UITableView with a single cell which will always be in editing mode and place it above your other table so it would appear to be the same table. It's a possible solution but most likely an overkill.

Is there a way to directly access UICollectionView elements without reloading?

I have another question open where I'm trying to figure out how to reload the collectionView without auto-scrolling. I was also realizing there are a lot of other situations where I will need to change things in the collection view. Also I have some items that I will want to change the .alpha on and change the text of. Is there a way to do all of this in Swift? For example (to be specific) if I have a collection view with a view in each cell and that view has a textField in it, can I change the alpha and text, (change alpha with animation even) without reloading entire table?
Look at the documentation for UICollectionView. There are several "reload" methods:
reloadData()
reloadSections(_:)
reloadItems(at:)
If you just want to reload a single item, update your data source's data and then call reloadItems(at:) passing in the index path for the item.
Another option, if a cell is currently visible, is to use the cellForItem(at:) method to get a reference to an existing cell. Then you can directly access UI components of the cell as needed. You should also update your data model as needed so if the user scrolls and comes back, the cell will be rendered properly.
Most appropriate where you can update your custom view of a particular UIcollectionViewcell is reloadItemsAtIndexPaths.
You would be handling a particular item than whole collectionview with reloadData.
You can handle it via notifications or some call backs in your code where you can make decision when to update which cell.
Hope it will help you.

UITableView initial row selection

Maybe I'm missing something obvious, but I'm have a hard time programmatically setting the row selection in a tableView. The goal is to simply have a tableView open with a row already selected. The problem appears to be that I have to wait until the tableView is fully loaded before I can modify the selection.
I've read various strategies such as calling reloadData for the tableView in the viewController's viewWillAppear method, then immediately calling selectRowAtIndexPath for the target row. But when I do that, I get a range exception because the tableView has zero rows at that point. The UITableViewDelegate methods (numberOfRowsInSection, etc.) don't appear to be called immediately in response to reloadData (which makes sense if the table rows are drawn "lazily").
The only way I've been able to get this to work is to call selectRowAtIndexPath after a short delay, but then you can see the tableView scroll the selected row into view.
Surely, there's a better way of doing this?
Well, you can use another strategy. You can create a hidden table view, configure how you want and than show to user. Use the tableview.hidden = YES.

Resources