Reputation: 431
I have 3 UIViews Header / Tabar / Container embedded un a ScrollView in a ViewController. So this is my structure :
In the ContainerView I load a UICollectionView (like this) :
let controller = storyboard!.instantiateViewControllerWithIdentifier("myCollectionViewController") as! myCollectionViewController
controller.delegate = self
self.addChildViewController(controller)
controller.view.backgroundColor = UIColor.brownColor()
self.containerView.addSubview(controller.view)
controller.didMoveToParentViewController(self)
Everything works perfectly, each cells of the UICollectionView are loaded,... The only problem is that, all the hidden cells (and even all the parts of cells that are hidden) are not selectable. What I mean is my function "didSelectRowAtIndexPath" doesn't work for every pixel out of the first screen. This is a scheme of my problem :
This is what I have before the scroll (on the left is a scheme, on the right is what I actually have on the screen) -> here everything works fine :
This is what I have after the scroll (on the left is a scheme, on the right is what I actually have on the screen) -> only the pixels that were displayed before the scroll can call "didSelectRowAtIndexPath" :
The problem reside in the fact self.view.frame is not refreshing well. Do you have an idea of how I should change this frame and when?
Upvotes: 9
Views: 4189
Reputation: 10475
This seems like the continuation of another problem you have mentioned in another question.
Looking at the storyboard hierarchy, i suspect the problem is, you are not changing the height of your tab bar view
when you are changing scroll view content size and the collection view height. Collection view is still visible, probably because your container tab bar view
does not clip contents (clipToBounds=false
). But since the view itself does not extend that far below, touches are not recognised by the view and it's subviews.
Make sure you main view, scroll view's content view (content size), tab bar view AND collection view are all resized correctly. Since you have decided not to go with standard view hierarchy (supplementary view or header view), you have to handle the overhead of managing the view bounds yourself.
Upvotes: 0
Reputation: 24195
Problem Definition:
All the time we face a situation were our UIViewController
, in addition to the scroller view, displays headers and tab bars. The problem is that those additional views reduces the area associated to our scroller (in this case UICollectionView
). In small screen devices our scroller will display a small number of items at a time.
Proposed Solution:
Let those additional views scrolls along with the scroller items.
How to Apply it?!
The most convenient solution to achieve that. Appears in the Scroller View itself. The UICollectionView
for example, provides Supplementary Elements (Headers and Footers) which scrolls with the collection view items. Move your header and tabbar to the header area of the UICollectionView
. then, implement the viewForSupplementaryElementOfKind
in your view controller:
- (nonnull UICollectionReusableView *)collectionView:(nonnull UICollectionView *)collectionView viewForSupplementaryElementOfKind:(nonnull NSString *)kind atIndexPath:(nonnull NSIndexPath *)indexPath
{
UICollectionReusableView *reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"Header1" forIndexPath:indexPath];
return reusableview;
}
Interface Builder:
The header area for the UICollectionView
already exists. But, you need to set the height for it via the interface builder in-order to appear in design time. Do not forget to set the Collection Reusable View Identifier for the header.
Note: This also requires you some extra work in order to set the gestures on your header and TabBar.
Update:
Consider to remove the header and tabbar container and re-add it as a subview in it's proper place at runtime. when the UICollectionView tab get clicked pass it to the header reusable view in the viewForSupplementaryElementOfKind
method. when a tab of labels get clicked add it on top of the labels container view. and when it's a tableview pass it to the UITableView header in the headerForRow method.
Upvotes: 1
Reputation: 18591
You have to define the scroll view content size
Create an outlet to your scrollview
@IBOutlet weak var scrollview : UIScrollView!
Make its height equal the sum of the heights of the header, the tabBar and the container:
self.scrollView.contentSize = CGSizeMake(self.view.frame.width, header.frame.height + tabBar.frame.height + container.frame.height)
Upvotes: 2