UICollectionView change layout - change cells - ios

I have a UICollectionView which uses UICollectionViewDelegateFlowLayout. I've added a method which changes the layout when tapping a cell setCollectionViewLayout.
All the cells have a text label with text and I would like to empty all the text labels on every cell when changing the layout. What's the best way to accomplish that?
Thanks,

I would imagine the simplest way is just to call reloadData on your collection view at the same time that you change the layout (and have a conditional in your cellForItem data source method that empties the text labels upon each layout change).
Alternatively, you could have your UICollectionViewCells keep track of the layout they're currently displayed in, and adjust their views accordingly.

Related

How to redraw custom collection layout when keyboard is visible?

I have custom collection layout to draw cells using uicollectionview. Each collection view cells have input text view. When user enters text need to resize cell height.So I call collection view invalidate layout. But it redraws all sections and rows in prepare layout and keyboard dismissed automatically. I want to keyboard stay up until user taps close button. When user typing text need to increase height of cell height.
Why I go for custom layout is my app needs row span and col span options (Merge and unmerge cells) in uicollectionview. This can't be implemented in normal uicollectionviewflowlayout. Can anyone help me to advise this issue?
About redraws
I have a custom layout in my current app. It consists of all kinds of cells including cells with text fields. I start editing the cell with field, keyboard appears. Then I press the button on another visible wishlist cell which adds the product to wishlist. When product is added I invalidate the layout and the wishlist cell is reloaded. During all these manupulations the field cell remains first responder and the keyboard goes nowhere.
But it redraws all sections and rows in prepare layout and keyboard dismissed automatically
Are you sure that you are not calling the reloadData()? It's not the layout who redraws everything, it's usually the developer who calls reloadData().
I want to keyboard stay up until user taps close button.
So, if you switch from reloadData() to batch updates - the keyboard will stay.
About resize
When you invalidate your layout you prepare new attributes for cells. Attributes with new sizes/frames. But the data source is the same. It means that UICollectionView will just move the cells around but they won't be reloaded. You don't have to reload anything! Just invalidate and provide new attributes. The field cell will automatically grow.
Example
In About redraws I described the way I reload the wishlish cell. Also, I added field attributes size change. You can now see that the keyboard remains and the field cell size changes. It now looks this way:
So, I believe, you just have to work on your layout. It is possible to implement the desired behavior. Good luck and happy coding (:

UITableView Visible Cells Not Laying Out Subviews When View Appears

I have a UITableView that has multiple sections, with custom UITableViewCell subclasses populating the table. Within these UITableViewCell subclasses, I am implementing layoutSubviews to customize the position of labels, etc.
All of the cell's subviews are adjusting as they should, except the first batch of visible cells upon the view loading. They are identical to how they are laid out in storyboard, which is not what I want. For example:
http://i.stack.imgur.com/L5GJh.png
Note: The green and orange borders are a visual aid to see if the labels are resizing.
Upon scrolling, all of the new cells that appear have their subviews the way that I programmed them to be in layoutSubviews. As far as the first batch of visible cells, I can scroll them offscreen and then back on, and then the subviews are laid out perfectly. For example:
http://i.stack.imgur.com/jgjch.png
Within tableView: cellForRowAtIndexPath:, I call [cell layoutIfNeeded] before the method returns the cell. If I change this to [cell layoutSubviews], then the inverse happens, where the first batch of visible cells are laid out as they should be, but all of the cells that get loaded upon scrolling are not laid out properly.
I have tried to put [cell layoutIfNeeded] within [tableview: willDisplayCell: with no luck. Any ideas on how to fix this?
Thanks in advance!
This is the behavior you'd see if you were setting frames in your layout code with Auto Layout enabled. This won't work. The Auto Layout system is responsible for setting frames and will overwrite the values you set.
You should either specify your layout using constraints or turn off Auto Layout.

How to dynamically resize UITableViewCell based on UITableView scrolling?

I have tried looking for an answer to this question but so far I haven't got any luck.
Context
I have a UITableView inside a standard UIViewController (NOT a UITableViewController..). I have subclassed UITableViewCell and all the cells in the tableview are from the same class.
Requirement
I would like to find an efficient way to resize the cells based on the scrolling of the tableview. For example, when the cell is at the bottom of the visible list, the height is X. When the cell moves up on the screen, its height should proportionally increase to 2X.
Additional Info
I am close to just ditch the UITableView way and start making my own control that would implement such a feat by subclassing a UIScrollView. However, I would like to see if it is possible before going this path. I did see some very interesting SO posts but nothing that would put me on the right path.
Any hint or help would be highly appreciated.
You would need to respond to the scroll view delegate method scrollViewDidScroll: and implement it to record the cell at the top of the table view and reload the table view. Then your table view delegate method tableView:heightForRowAtIndexPath: sets the cell height by the relationship between the index path and the top cell index path.
Your main issue is performance while reloading the table view all the time.
If you wanted to roll your own solution it would be along the lines of the above description anyway, but you would be able to be more efficient than the table view as the table view will call the tableView:heightForRowAtIndexPath: method once for every row for every reload in order to calculate the total height of the table content.

Custom UITableViewCell's subviews using auto layout - no xibs, all in code

Custom UITableViewCell's subviews added in code using auto layout works (verified). However the whole point of doing this was to not have to calculate the height of each tableview cell and the delegate method heightForRowAtIndexPath expects a height while drawing the tableview.
How can I figure out this height based on content using the auto-layout (visual format language based addition in code already added and working) and return it to this heightForRowAtIndexPath?
Also I'm I can't really do this on a background thread (or can I?) and therefore if I have a UITableView using this backed by a list of say 1000 records, this will take forever, is that right?
Autolayout in this case just means that you don't need to calculate the frame sizes of your subviews within each cell. It's got nothing to do with the heightForRowAtIndexPath method - this is used by the table view to define the cell's frame, which will then inform the layout of the subviews.
Using Autolayout to determine the heights would likely be pretty slow, and you can't do it on a background thread. If you have 1000 rows then I'd consider a hierarchical structure instead of a single table as that will be pretty tedious to scroll through. You could also consider calculating the heights at the point of setting or creating the data.
You may be able to set up an offscreen view using your constraints, populate it with your data for each item, then record and cache the height. However you'd have to do this at the data end rather than in the height method, as it would be far too slow.

Getting real width of UITableViewCell's contentView before it displays

I have a grouped table view with custom cells (created programmatically by subclassing, not with IB). To properly position custom cell's subviews (such as labels and text fields), I need to know the current width of the cell's contentView just before the cell displays (taking into account that real cell width in a table view can change (according to screen orientation, modal presentation style, etc.)).
if I override in custom cell class the layoutSubviews method, it works perfectly, but it can be called frequently, thus I have to reposition my subviews every time when it's called, even when there's no need to do that.
Please, recommend me more elegant solution.
The recommended way of doing this is by setting the autoresizingMask of the table cell. If you need to have more control over the layout, you can store the last used view width in a member variable, and only layout the subviews if this differs from the current view width.

Resources