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

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.

Related

Getting the data of all TableView Cell which all has TextFields in it (including the hidden views)

I'd like to get every data that is within all cells in one tableview which is quite a long list.
I'm looking for an approach on how to retrieve everything including those hidden in view, which I know the views are reused. I think some of you might have experienced this problem before, what are your approach on this?
I've tried
let cells = self.tableView.visibleCells
then looping into every cell and saving each data to an array but it is not effective in getting those that aren't part of the view or hidden. Is there a way to get over this?
In cellForRowAtIndexPath, YOU are telling the table what is in each cell. So why would you turn around and ask the table what's in each cell? If the user puts "Hello" in your first cell, then scrolls the table enough to push that first cell out of view, then when the user scrolls back to the top, YOU are the one telling it to put "Hello" back in that first cell. YOU own the data source, not the table.
You need a data source. That can be "empty" at first, maybe an array of empty strings if that's what you want (each index in the array could map to a table row for example). But then, as the user interacts with the text fields in the cells, you need to update that data source with the text they entered.
You should use that data source as your source for the cellForRowAtIndex method. That way you can handle populating the cells when they are requested by the table, and you also know all the data when the user is done.
Why not just update the model each time the user taps a key when editing a textfield? You could create a protocol for that cell subclass and make your view controller the delegate for each cell. As long as cells are guaranteed to stay on the screen while you're typing (you'll get some weird behaviors if not) the cell can send a message to the view controller or whatever you hook it up to telling it what new value to store. Then everything is already stored for you when you need the full list, and you don't have to interact with the tableview.

Can UICollectionViewUpdateItem be used to update a single label?

I'm trying to update a single label in a collection view cell. I know how to update the entire collection view and how to update a single cell, but I want to update only a label because if the whole cell updates it will change other stuff which I don't want to change yet. In the docs I found something called UICollectionViewUpdateItem but cannot figure out how to use it. Is this capable of updating a single label or if not is there another way?
If you know the index path of the cell you want to update, you can get the cell using cellForItem(at: IndexPath). From there you can edit your cell's label.
However, I suggest you don't change your underlying data so that it's in a state that is unsuitable for presentation in the UI. The collection view can decide to create cells at times that are unpredictable to you.
UICollectionViewUpdateItem is used to indicate e.g. from where a cell moved, and where it moved to, or that a cell at a certain position was deleted, updated, etc. The docs state:
You do not create instances of this class directly.
So it means you should only create it indirectly, for example through reloadItems(at: [IndexPath]). It will reload your entire cell and should not be used to update a single detail of it.

Change another cell in dynamic prototype UITableView when a switch in one cell change

I used to use static UITableView but the table is too long and overflow the memory.
I switched a dynamic prototype UITableView with 1 type of cell, which has an UISwitch in it.
One of the cell, when turning on the switch, will turn off the switch of another cell. These cells have fixed index.
The IBAction method is in my UITableViewCell subclass and I don't want to add the UITableView as a property in my UITableViewCell.
How do I achieve the above effect?
I'm planing to use an id or similar to distinguish between the cells as each cell's switch has different effects, that doesn't solve the above requirement.
Thanks,
I would add a block property to your cell which you can use to notify your controller of changes in the switch. See my answer below to a question on this:
How can I get index path of cell on switch change event in section based table view
All your logic can now be implemented in the view controller.
You are best to create a data model in the view controller which the cells simply provide views and controls onto. When you flick one switch and the block fires, update the data model and simply reload the table. Any cells affected will show the new data model positions for their switches. Avoid using one cell to adjust another. Just update the model and reload the cells.

How to refresh a UITableView in iphone?

I have a UI table view loading data from network. If the user move the finger on one cell, one button will be displayed, just like iPhone style delete button. If the user click this button, the value of one label in the cell will be changed accordingly. However, I didn't find any way to make table view to re-draw this cell, except for reload the whole table. I don't want to use reload data method, because I just need change the value in one cell instead of the whole table. Any suggestion on this?
Take a look at the method
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
Calling this method will result in your table view's data source asking its delegate for information about that cell.
For future reference, I found this very easily by checking the documentation on UITableView. I suggest you do that in the future before posting here.

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