iOS - `UIViews` behind `UICollectionViewCell`disappear - ios

I have a gallery using UICollectionView that prepared using main.storyboard. I have a few UIViews and UIButton placed between UICollectionView and UICollectionViewCell. When I test the app, some of the UIViews and UIButtons disappear.
But I have another catalog scene which prepared using the same way and everything is there. What seems to be the issue?

I wouldn't mess with the UICollectionView's view hierarchy this way. Since it handles its own list of subviews, yours may be obstructed. I would suggest one of those two methods:
Set your UICollectionView background as [UIColor clearColor], and put your own views behind that UICollectionView, in a hierarchy similar to this:
UIView
Your Custom Views
UICollectionView
Use the UICollectionView's decoration views. You can read more about them here, in the "Including Decoration Views in Your Custom Layouts" section.
Decoration views are visual adornments that enhance the appearance of
your collection view layouts. Unlike cells and supplementary views,
decoration views provide visual content only and are thus independent
of the data source. You can use them to provide custom backgrounds,
fill in the spaces around cells, or even obscure cells if you want.
Decoration views are defined and managed solely by the layout object
and do not interact with the collection view’s data source object.

Related

Can I load a UITableViewCell directly from a xib with a specific size class or trait collection?

I'm trying to do the following in my iOS app:
Embed a UITableView into a parent scroll view; the table view will have its frame expanded to show all its contents (I need to do this because the table view data is a small component of a much larger more complex screen, and I don't want nested scrolling behavior)
I have different layouts for iPhone and iPad, so the cells in this table view are using size classes defined in a table view cell xib.
Since I want the content size of the table view to be accurate, I don't think I can use UITableViewAutomaticDimenstion as the rowheight, so I implement tableView:heightForRowAtIndexPath: and load an instance of my tableview cell from the nib directly and store that view as a property with which I can figure out how tall the cell should be according to autolayout.
My problem stems here; when I load the cell directly from the nib, on iPad the cell uses the constraints and layout in the 'Any' size class as defined in the nib, which is incorrect because the iPad's layout uses the regular width class only in my nib. This causes my table view cell heights to be wrong and too large in my case.
What I need to know is if there's a way to force the trait collection on the cell I load, such that the proper constraints for my views are used on each device type. I can't seem to find anything in the docs that allows for this directly in UIViews, only in UIViewControllers and I'm not keen on holding an offscreen UITableViewCell in a random offscreen UIViewController if i can help it. Any ideas?
After writing this I found this question: Offscreen UITableViewCells (for size calculations) not respecting size class? which seems to ask a similar thing, and the answer in there worked for me (add the offscreen table view cell as a subview of the tableview, or some other view that provides a trait environment). It's not pretty but it seems to work out.

What's the best way to build a very flexible/dynamic "header" in UICollectionView

I need to build a UICollectionView with a UICollectionViewFlowLayout and a very dynamic "header" (for clarity, I'll call it "view A" to avoid mixing it with a true collection view header) but I'm not sure about what can be the best way to do that: collectionViewCell, header or supplementary view?
What I mean by flexible, the bullet point being ordered by decreasing importance:
View A will contain buttons and subviews that need to detect gestures so I must be able to detect actions on subviews of view A.
I need to be able to reload data on the collection view without reloading view A.
I need to be able to update the layout of subviews of view A whenever I want (on viewDidScroll of the collection view delegate for example, update according to contentOffset changes).
If possible, I'd like to be able to change the frame of view A dynamically (I mean without having to invalidate the layout). I would like view A to be sticky at the top and shrink while scrolling until it disappear. Have a look at recently launched "Secret" app to see what I mean (done on UITableView for them). Though I could just scroll without changing the frame and cheat by changing the layout of subviews (see point 3) in order to give the sensation of a sticky header.
What do you think is the best component to do that? Can I use a UICollectionViewCell, a header or a supplementary view? If so which one? If not, do you think of an alternative way I could use to have the same behavior (transparent header and view A behind the collection view? adding view A somewhere else, where, in the view hierarchy?).
Thanks for your help!
Take a look at the UICollectionReusableView class.
You can register your nib on the CollectionView as "SupplementaryView" (registerNib:forSupplementaryViewOfKind:withReuseIdentifier:, use the UICollectionElementKindSectionHeader kind of view)
then you have to implement the collectionView:viewForSupplementaryElementOfKind:atIndexPath: method in your delegate and make sure to return something for the UICollectionElementKindSectionHeader kind.
and finally you have to implement the collectionView:layout:referenceSizeForHeaderInSection: method of your UICollectionViewDelegateFlowLayout to set the size of your header.
Let me know if it help.

UIcollectionview decoration view VS supplementary view

I'm starting my development of an ios app using ios 6 and UICollectionView.
I've noticed there's support for both supplementary views and decoration views.
Can someone please explain in bullet points the difference between the two? They sound very similar.
If I want to add a loader to my collection view (that will appear at the bottom of each section, while the section is loading) should it be a supplementary view or a decoration view?
Thanks
Decoration views are just what the name says: decoration, chrome. Only the collection view layout decides what they are and where to put them (for instance, if you want to draw lines on the screen every 5 items).
Supplementary views are more related to your data. The collection view layout still decides where to put them, but they are provided by the collection view data source, just like regular cells. For instance, if you wanted to put titles for sections, you would use supplementary views because the title would be different for each section and you need to call the data source for each.
If your loader is generic, it could be a decoration view, however decorations views are not really accessible (the layout object says where to put them, and that is it, they are created by the collection view and you never get a reference to them), so if you want to start/stop animating it, a decoration view is not the best choice. If you use a supplementary view, then you have access to it at creation time (in your data source collectionView:viewForSupplementaryElementOfKind:atIndexPath: method). However, you can only query the collection view for regular data cells once they are laid out on screen.
Also, you will have to write your own UICollectionViewLayout class if you want to use custom decoration or supplementary views. The base UICollectionViewFlowLayout only provides for a footer and a header supplementary view.
from UITableView perspective :
Supplementary = sections.
Decoration = tableFooterView tableHeaderView

iOS: UICollectionView cell selection not working

I have a UICollectionView as the top view on my view hierarchy in IB. It's making use of a custom layout that splits the cells (registered from nibs) along the left and right edges of the view, with decoration views behind and a supplementary view the size of the entire view on top of the cells. All of that works as expected.
What doesn't work is that selecting cells is simply not being registered. They're not firing calls to collectionView: didSelectItemAtIndexPath: (the delegate is set correctly), nor is the highlighted state of the images within the nib working. It's acting rather like a view higher up is consuming the tap, but the collectionView is the top view. I've tried removing the overlaid supplementary view and background decoration views, and also tried temporarily converting to using a flow layout in case my custom layout was doing something screwy - still nothing. Making this even more frustrating is the fact I'm using collectionViews on other view controllers in this app (governed by flow layouts), and they work perfectly fine without any special customisation. I'm out of options, any ideas?
Problem solved. Turned out the nib I was using had a single view that was, for some reason, an instance of UICollectionReusableView, not UICollectionViewCell. Presumably, the reusable view class is designed to not allow selection by default.

UITableViewController or UIViewController when adding additional controls

I have a number of views that include tableviews, but other controls as well. Up till now I have been subclassing UIViewController and manually adding a tableview to it (with my other controls above/below it). Not too much hassle, other than having to manually handle the scrolling, and sometimes some resizing (if the table's content is dynamic).
I only just found that the tableHeaderView and tableFooterView of a UITableView can pretty much handle anything you throw at them. I guess I skimmed them previously, thinking they were related to section headers/footers when they are of course not related at all.
So with that in mind, and before I convert a bunch of classes over to subclass UITableViewController instead of UIViewController, is this standard practice? If I have a view, for example, that is mostly non-table content but with a dynamic tableview half way down, is it a good idea simply to use a UITableViewController and put everything around it in the header/footer?
The table view header and footer are scrolled with the table view's content. If you need them to always be visible, your current approach is the best. If you don't mind the header views being scrolled, you can indeed refactor your app.
A UIViewController manages a view hierarchy. If your view contains significant non-UITableView content, I would manage the view hierarchy with aUIViewController and include the UITableView as a subview in the view controller's view property.

Resources