My iOS UIScrollView refreshes only off-screen - ios

In my iOS app, I do have my UIScrollView that contains UITableView with classes (cells) containing UIImages.
Now I do need to update the UIImages programmatically.
However the visible part of my UIScrollView does not update, unless I do scroll the changed item (UIImage) off the visible screen and back.
I've tried setNeedsLayout, setNeedsDidsplay for my UIScrollView, UITableView -- no success.
Any idea on what I could do wrong, or how can I force the ScrollView to update without actual scrolling?

Solved.
At first, UITableView inside UIScrollView was unnecessary since UITableView scrolls itself.
The solution was to use ReloadData method for my TableView.

this is because tableView calls func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell when cell reappear on screen so that it can reuse cell object to save memory, so call tableView.reloadData() or func reloadRows(at indexPaths: [IndexPath], with animation: UITableView.RowAnimation) whenever ( after data is changed obviously ) you want to reload the entire tableView or particular cell respectively.
And no need to use scrollView for tableView since tableView inherits from scrollView.

Related

Q: How can I change the cell size in UITableView, to show all the labels?

I nearly finished making my tableview cell and all the contents in data model shows up in the UI so I think the connection is fine. The problem is that my prototype cell shows only part of what it's supposed to show. I have 3 labels in the cell, but it only shows one and a half. the text is stuck to the left(I wanted to put it in center), and the textlabel is cut off so it doesn't show in the UI.
It's supposed to look like this.
I tried
tableView.estimatedRowHeight = tableView.rowHeight
tableView.rowHeight = UITableView.automaticDimension
this code in the ViewController to make my cell to automatically set height to my labels, but it didn't work.
I also used vertical stack view and made constraints so it fills the cell fully, and it doesn't seem to make a change.
Please help!
You have to use implement the UITableViewDelegate protocol and the function
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat
where you can return the custom height for each cell
You can do this in the Storyboard - you can just drag a cell in the UITableView to be bigger. The UI of resizing the table view cell is the same as resizing any UI element in the Storyboard. The rest of them will be too, though. Hope this helps!

Some custom UITableViewCells are not rendering

I have a custom cell UITableViewCell, sometimes when the tableview loads, I am getting missing cells (cells where the content view is not rendering at all. I get this behavior fairly consistently when I use reloadRowsAtIndexPath (when a custom object the cell is using is updated for example). If I call reloadData on the tableview, I usually don't get this behavior.
Here is what it looks like when view debugging:
Here is the cell under that (which rendered fine):
My initialization of the cell in cellForRowAtIndexPath is the usual pattern:
Edit - entire cellForRowAtIndexPath:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let reuseIdentifier = "WorkOrderListCell"
let cell:WorkOrderListCell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier) as! WorkOrderListCell
If I scroll the tableview so that the cell which did not render is off screen, and then scroll back, the cell will render.
I have also ensured that I am on the main queue by wrapping my reloadRowsAtIndexPath in a main queue closure but that doesn't make a difference.
What am I missing?
Some times there's an issue with table view on first load. So I would suggest reloading tableView data twice. You can use this extension:
extension UITableView {
func reloadDataWithAutoSizingCellWorkAround() {
self.reloadData()
self.setNeedsLayout()
self.layoutIfNeeded()
self.reloadData()
}
}
Which is found in this issue https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8/issues/10
Or you can call directly:
self.reloadData()
self.setNeedsLayout()
self.layoutIfNeeded()
self.reloadData()
Issue was that I had a ambiguous constraint in the content view of the cell. It only got reported when I added setNeedsLayout in the delegate method to reload the row. Once I found that, it was easy to find using the a breakpoint and debugging the view. When I removed the distance constraint that was causing the issue, all the rendering issues went away. Thanks to #DionizB for putting me on a good path.

How to add UIRefreshControl on UITableView bottom?

I want to implement pull to refresh effect but on UITableView bottom using UIRefreshControl ?
Any ideas?
It is not possible to put UIRefreshControll to bottom of UITableView in a manner similar to putting it to top. But anyway, you're able to place everything on table view's background view.
But the solution which I prefer is to download additional items when user scrolls to the most bottom of table view. I handle it via UITableViewControllerDelegate method:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == self.items.count - 1 {
// Download more items
}
}
These are the two things i typically do:
Configure a Footer View which displays the loading Indicator.
Provide a additional cell from the TableViews or CollectionViews
Datasource which presents a loading indicator. Depending on the current loading state it could display a label like "No more items available" or the actual Indicator

Subview of custom UICollectionViewCell apparently not redrawn when cell is reused

I have a UICollectionViewController whose collectionView:cellForItemAtIndexPath: returns a subclass of UICollectionViewCell. This cell has a couple of subviews which are also configured as the cell's outlets (e.g. cell.dot, a custom UIView that draws a colored dot in its drawRect:).
What appears to happen is that (at least some of) those subviews are not refreshed when scrolling the collection, i.e. when cells are reused. The problem goes away if I explicitly mark the subview as needing to be redrawn like so:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
// ...
assert(cell.dot.superview == cell.contentView)
cell.dot.setNeedsDisplay() // apparently required for dot to be redrawn
return cell
}
Is it normal behavior that subviews of reused UICollectionViewCells are not automatically redrawn? Am I missing something else?

iOS UITableViewCell asynchronous image download and change UITableView height accordingly with the use of auto layout

I'm writing an application where images are downloaded asynchronously and when the images are loaded its scaled but I just want to show as the same size within the UITableViewCell.
Since i'm using auto layout I have tried to change the height constraint through an IB but then I have to change the height of the cell and I though of reloading each cell after downloading each image but not sure if it's a good idea.
Its like the Facebook application where images are loaded and the uitableviewcell is dynamically changed.
Have you tried this delegate method?:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
// return downloadedimage.bounds.height etc.
}
Also do not forget to reload data in the viewDidLoad method
tableView.reloadData()

Resources