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.
Related
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.
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.
I have abit of a problem, I have a coredata object that is used to populate a UITableView. Each UITableViewCell has a couple of buttons that I am using as check boxes, when the user presses one of these text boxes I would like to update coredata and reload the UITableView so all of the arrays I have are updated to reflect the new data.
Thinking about this I have come to the conclusion that its abit redundant or overkill to be reloading the UITableView every time a button is pressed because some of these UITableViews will contain hundreds of rows with two editable UIButtons each.
So I thought that maybe I should update the current array instead then when the view is either exited or the device is put to sleep I could update the coredata object then? the only thing being I don't really know if this is the right thing to do or possible.
The reason this is such a problem is that when I change a button from say a tick to a cross if I scroll away then come back the buttons tick or cross s reverted to its old value.
I would like to know the best way to handle this case as I have never done anything like this before.
You should use an NSFetchedResultsController and its delegate methods to populate the UITableView. Then when the user taps a button, you simply update the corresponding Core Data entity and not the cell. The NSFetchedResultsController will then call its delegate methods, and you can update just that one cell on which the user made a change.
Also, in cellForRowAtIndexPath, you simple fid the corresponding CoreData entity, and use its attributes/properties to adjust the display of the cell.
Remember, that you must always use some data (NSArray usually) from which to read what to do for the cell at the indexPath when the tableView calls cellForRowAtIndexPath:.
This way, when the fetchedResutsController call its delegate methods, you can simply call reloadCellAtIndexPath on the tableView and then the tableView will call cellForRowAtIndexPath again. As the Core Data entity has been updated, your logic for adjusting the display for that cell will cause the cell to look as it should. It's important that you only ever adjust the way a cell looks in cellForRowAtIndexPath, and base the look on a CoreData entity. Change the look of a cell in multiple places, and you will get problems.
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.
In my application, I have a UITableView with a few rows (let's call it TV1), now, at the bottom of these rows is a row that drills down into another (TV2). This new TV2 asks you which type of data you would like to add to the first view. Then, when the user selects which kind, they're brought to another view, in which they fill in some fields, the data is saved, and they're sent back to TV1, however, the data they entered, isn't loaded and I'm not really sure how to do this. Any ideas?
Maybe you did this already, but how about using [TV1 reloadData];? This forces the entire table to reload, yet there are also more specific methods for reloading just the cells that have been altered. See also the documentation: UITableView
Reload your table view by calling [self.tableView reloadData] in the viewcontroller's viewWillAppear: method. It will be called when the user switches back to your view. Right before it is actually put on screen.