UICollectionVIew inside UIView adds a huge amount of padding to the top of the collectionView - ios

I am trying to add collection view to UIView and there is a problem that doesn't make any sense. Screenshot. I made the background color of the collection view, to make show the view area more clearly.
If I add the collection view straight to the controller (just like in UICollectionViewController), the top padding doesn't exist.
In this example, I have autolayouted the collection view to resize to the whole view but the problem existed the moment I added collection view to the UIView.
Also, if I add another collection view right after this view, there items start from the top, without any margins.
If there is anything else you need me to provide, I will do it. I think this is a storyboard bug or something because there are no insets, in the view's attributes.

Related

UICollectionView Bug When Top Subview in "Structure" Pane

After banging my head against all the walls of the building, I have noticed that whenever I have a UICollectionView as a subview of my view controller's main view, the following holds:
If the collection view is the first subview in the "Structure" pane in Interface builder, the cells are pushed down by about 128 points (see images below:)
(red background is collection view)
However, if I add another view above the collection view, the item cells line up at the top (as expected), no extraneous margin:
...but it has to be placed above the collection view: If I re-arrange the views and place the dummy below the collection view, the bug resurfaces.
This collection view is horizontal scroll, one line (section). Ideally, the collection view height is the same as the cell height (no margin), so the bug caused the cells to not show at all. I had to try and enlarge the the collection view's canvas vertically to finally realize what was going on.
Is this a documented feature I am somehow missing, or is it a bug?
I fell like naming my dummy view "spacer.gif" and enjoying some late-nineties nostalgia.
ADDENDUM: I have further investigated and discovered that, the dummy view placed above the collection view is a necessary condition for it to work, but not sufficient. Moving it around (mostly to hide it) or adding/changing constraints on it makes the bug resurface in some cases. Very annoying, can't quite figure out the exact conditions...

How do I structure a table view to load halfway down a view?

I would like to make my UITableView load covering half of the window with a background view that starts visible, and as the window scrolls, is gradually covered by the table's cells.
Initially, I want to style is like so:
As the user scrolls, the cells will cover the background element.
The only way I could think to accomplish this would be to put the background element behind (and outside) a ScrollView (which is sized to fit over the background element and has a transparent background), put the TableView inside the ScrollView, and set the load coordinates to start the table far enough down. Is there a better way to accomplish my desired design?
I would prefer to avoid this layout because I would like to be able to easily add more cells dynamically as the user scrolls, ideally without having to deal with resizing the ScrollView.
You can take a view inside table view just above the table view cell and make its height whatever you want space in table view and make a outlet of that view. Then in view did load assign the view as table header view like this.
self.tableView.tableHeaderView = self.headerView;
This will be displayed exactly like you given and when user scrolls it will show the below cells and when you want you can change the frame of the header view and your header become invisible. You can do it whenever you want i mean if you want to change height on scrolling or if you want to change on adding more cells.

How should I approach structuring this view?

I'm having a hard time finding the best way to structure this design.
The top view has a minimum height and becomes sticky when it reaches this height. The bottom view hosts a paging controller with three views within. Each of these views hosts either a collection view or table view with vertical scrolling.
I'm really at a loss on how to approach this. Is the entire view scrollable and I should prevent scrolling on the second view until the top view has reached it's sticky height? Or are each of these views separate uitableviews and the pagingcontroller is just one cell? Should I even be using a pagingcontroller or should I use a scrollview with paging enabled? (the latter was a little rough interaction-wise)
Thank you!
Take a look at the Advanced User Interfaces using Collection View from WWDC this year. This view is very very very similar to the iTunes Connect app interface. The entire session video explains how they created that interface.
I used a similar method to this to create the keyboard in the Emojicate app.
I think what I'd do is actually fake the sticky header. So something like this...
Use only one collection view.
Create a "segmented data source" that contains three data sources. (See the video from WWDC about this)
When the segmented control is changed then update the collection view by changing its layout and (if you want) dataSource.
Make the entire top section a header on the collection view.
When the collection view scrolls past a certain point (when you want to sticky the header) then have a second view that is the compressed header and make it visible at the top of the screen. This is not attached to the collection view at all.
When the segmented control changes you can update the collection view by changing the "selected datasource". The datasource can also contain a UICollectionViewLayout that will update it.
Essentially, the tableview you are talking about is just a collection view where the cell width is equal to the screen width. i.e. fake a table view.
The sticky header isn't sticky at all. Just when it starts to go off screen you can put a fake header there instead.
It will require a duplicate (ish) view and some thinking about how to structure the data but I think this will be easier and less resource hungry than having multiple collection views and page controller and stuff.
If you want me to go through it in more detail let me know but it's a complex subject. Watch the video first.
I would make this part a navigation bar. Should be relatively easy. Just have to customize the back button with a barButtonItem and do a couple of labels in the titleView.
I would make the next part a Table View.
The tableView has 2 sections. The first section doesn't have a section header and the second section doesn't have any cells but just a section header.
First and only cell in this section:
And the rest would be the second section header's view:
This gives you the stickiness that you want because the section header will remain there even if you scroll past it and since the collection has only 2 sections the controls will always remain on top.
I think the collection/table paging part is the hardest part and I don't know clearly how it can be done. But I was thinking it could perhaps be a ContainerView. Each view of the container view would be either a tableview or a collectionview. You would have to add some code to handle the movement of the containerview relative to the second section header (possibly an autolayout constraint that attaches the containerview to the buttom of the first tableview that you implemented above).
I don't think having your tables/collections in a scrollview would be a good implementation. I think I have even read in documentation that developers should stay away from that (but I might be remembering it incorrectly).
I would have:
A "header view" with three subviews:
Fixed height top and bottom views (they stay visible at any size).
A middle view that appears/disappears as the superview grows/shrinks.
A scroll view (table or collection view are subclasses) on that partially covers the header view with a top inset set enough to reveal the underlying header view (the same way pull to refresh views are revealed).
The paging buttons could be set as table/collection view section header views.
Finally track the scroll view's scroll position to keep manually adjusting the header view height.
Another way to see this solution.
Two completely separated parts, a header view and a table view.
A simple header view (blue) that adjusts its subviews as its height changes. More precisely hides its middle subview (light blue) when it shrinks.
A table view that a) partially covers the header view in Interface builder but b) has a top inset as to avoid hiding the header view in the actual device (tableView.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);).
The two parts are only "connected" by resizing the header view height as the table view scrolls up/down.

iOS prevent subview of tableview from scrolling with tableview

I have added a subview to my tableview and when ever the user scrolls the tableview, the subview scrolls with it. How do I prevent this? I know it's probably along the lines of not adding the view to the tableview's subviews, but I have no knowledge of any other ways to do this. Thanks.
If you want to make a view a subview of the table view, then you can make it floating (non-scrolling) by changing its origin.y value in the scrollViewDidScroll method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
self.iv.frame = CGRectMake(self.ivOrigin.x, self.ivOrigin.y + self.tableView.bounds.origin.y, self.iv.frame.size.width, self.iv.frame.size.height);
}
In this example, "iv" is a property for an image view, and "ivOrigin" is a property for the initial origin of the image view (defined when I created the image view and its frame in viewDidLoad).
The UITableView is built and intended to be a view of things that scroll.
So, you can either fight that, which as you're discovering is quite hard since everything about the component is built and focused around scrolling and fast display of a subset of the full list data... Or, you can not fight it and put your static item on top of the table as a fixed-position item.
If there's a reason you can't add the table view and your animate-out item in your main view, you can always add a custom UIView class that contains both the table view and your animated view. Have your custom view class expose the contained table view as a .table property, and the container you're putting things in can be tweaked to use "mycontainerObject.tableview" instead of just "tableview" where needed.
Yes, it's a little more work to write the custom UIView subclass and give it a couple properties to hold the UITableView and whatever UIView you're animating out.. but it's likely a lot safer in the long run than trying to "hack" into the UITableView's methods and view hierarchy to try to give it a "fixed in place" behavior.

iOS - Interface layout

I need to achieve the following interface layout:
The obvious path would be a table view, but how would I do the top player and the bottom button set doing that? Embedding buttons in a table view row is a little unsightly I'd say, any suggestions?
It looks like a composed hierarchy of UIViews to me. The topmost element is a custom UIView subclass whose subviews, in turn, are comprised of the appropriate controls. Next down, is a UIButton, then your UITableView (does it scroll? It looks like perhaps not.) Then another row of buttons (trash, etc.)
So, to summarize, your base view is just a UIView that you compose with subviews, including what I assume is a grouped UITableView in the middle. It will be easiest to layout in IB.
You can have multiple table views within a UIView. Or you can put the top and bottom controls in the table header and footer. A quick example:

Resources