UITableView embedded in UIScrollView - ios

I am trying to embed a table view into a scroll view. I would like the scrolling to happen on the scroll view level. I am able to embed the table view into the scroll view but I am stuck at trying to resize the scroll view content size to fit the full height of the table view..how can I achieve this?

you can calculate tableview height in heightForFooterInSection or viewForFooterInSection of table
_tblOption.scrollEnabled = NO;
Frame = _tblOption.frame;
Frame.size.height = _tblOption.contentSize.height;
_tblOption.frame = Frame;
_mainScrollView.contentSize = CGSizeMake(_mainScrollView.contentSize.width, _tblOption.frame.origin.y + _tblOption.contentSize.height);

Your hierarchy should be as follow: UIView -> UIScrollView -> UITableView. That mean you simple create UIViewController, then place UIScrollView, connect delegates and so forth, then place in it UITableView controller.
But im wonder why would you put tableView inside scroll view, better design would be place separately UITableView and UIScrollView.
I much rather recommend you to have UIView with UITableView AND UIScrollView, placed separately.
In XCode you may use Editor->Embed In.

Related

Create a UICollectionView that scrolls with another UICollectionView

I have already built out 2 collection views, 1 horizontally scrolling (at the top) & 1 vertically scrolling (at the middle - bottom) that are used to view 2 different sets of content in my Objective-C iOS application similar to this Instagram screenshot:
I am trying to add functionality to make it so that the horizontally scrolling Collection View disappears when the user scrolls up on the vertically scrolling one. What is the best way to accomplish this task? I have looked up tutorials on adding a collection view in another collection view's cell but I cant find anything on just adding a collection view to the 1st cell of another collection view. What would be the best way to accomplish this functionality?
I think you should you use UITableView with UICollectionView. On the screeshot, I think horizontal collectionview is embedded in first cell of the tableview. And when use starts to scroll tableview, first row is gone as you want.
Edit
Create uitableview with 2 prototype cells. Create horizontall collectionview and embed it in first cell of tableview, this is first prototype cell. Then create second prototype cell for images. And when user will start scroll the tableview first cell will gone, as you want.
If you don't want to go with the other suggested method of embedding the horizontal collection view into the top cell of the vertical collection view, you could use the vertical collection view's scrolling callbacks (scrollViewDidScroll, since UICollectionView subclasses UIScrollView). When the vertical collection view scrolls, you can apply a transform to the top collection view to move it off the top of the screen based on the contentOffset of the vertical collection view, and then have it reappear once the contentOffset approaches 0.
Keep in mind that with this approach, the vertical collection view's frame will likely be the height of the screen minus the height of the horizontal collection view. Therefore, you will need a bit of extra logic to expand the vertical collection view's frame to take up the whole screen once the horizontal collection view has disappeared from sight. Otherwise, you will have an awkward blank bar at the top of the screen where the horizontal collection view initially was while you scroll.
You have two scroll view lets call it "cvHorizontal" and "cvVertical".
You can manage scrollViewDidScroll method to hide cvHorizontal when scrolled up and show cvHorizontal when scrolled down.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (lastContentOffset > scrollView.contentOffset.y){
[self showCategory:YES];
lastContentOffset = scrollView.contentOffset.y;
} else if (lastContentOffset < scrollView.contentOffset.y) {
[self showCategory:NO];
lastContentOffset = scrollView.contentOffset.y;
}
}
-(void)showCategory:(BOOL)flag{
if(flag){
[UIView animateWithDuration:0.6 animations:^{
if(cvHorizontal.hidden ){
cvHorizontal.hidden=NO;
cvHorizontalHeight.constant=65.0f;//manage the cvHorizontal height and all the other constraints calculation if any
}
}];
}else {
[UIView animateWithDuration:0.6 animations:^{
cvHorizontal.hidden=YES;
cvHorizontalHeight.constant=0;
}];
}
}

How to make a UICollectionViewCell span entire row?

Context
I am trying to create something similar to a Table view using UICollectionView.
I am using Xcode7 and storyboarding.
The way I do it is that I drag the collection view across the entire controller view.
And then I drag the entire cell across the row and align it with the right and left boundaries.
Problem
But, when I place a label inside the cell, then it gets displayed correctly only when the device is in a horizontal position.
When the device is vertical, it gets cut off at the left boundary.
Question
How do I ensure that the width of the collection view cell matches that of the container width?
1) Implement the function of cell size and return the collection width:
-(CGSize) collectionView: (UICollectionView*) collectionView layout:(UICollectionViewLayout*) collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath*) indexPath {
CGFloat height = 50; //set the wanted height
return CGSizeMake(collectionView.frame.size.width,height);
}
2) Reload the collection when the screen size change (i.e. orientation change).
It is because you are not using autolayout. You can achieve this entirely in storyboard or through code.
Using Storyboard
Add UICollectionView in your UIViewController in storyboard.
Drag UICollectionView to fill up in your UIViewController.
Add Constraints as shown in image.
Drag UICollectionView to fill up in UICollectionView.
Add UILabel (Or whatever you want to have in cell). Also add constraints in that element.
Build and run.

How to make DPFBannerView in UITableview did not scroll

i am new in Google admob development. In this case i need to add an admob inside my uitableview, I make an implementation like this on :
the problem is, the cell that contain the ads (I Use DFPBannerView) is scrollable, i want to make it unscrollable. I just want to make the uitableview scrollable but the banner view is not. I already implement some suggestion from UIScrollView doesn't scroll when touching GADBannerView subview
but it still can not make the ads unscrollable. is there anyone can help me?
There are basic 2 solutions to this:
Add the view to the superview of your table view instead of to the table view itself. Then you just set the frame of the tableview to be shorter so that it is not cut off by the banner. This is provided you are not using a UITableViewController because if you're using one of those, the table view is the root view.
Add the subview to your tableview directly, and implement scrollViewDidScroll: and change its frame based on that. The implementation would look something like this:
- (void) scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect bannerFrame = myBanner.frame;
bannerFrame.origin.y = CGRectGetMaxY(scrollView.bounds) - bannerFrame.size.height;
myBanner.frame = bannerFrame;
}

Scrolling ViewController Content

What I have in the view controller view are :
An image of fixed height
Few labels
Table view with n rows.
Once rendered I want everything here to be inside the scroll the view so the user can scroll the entire screen as needed. Note that the scrollView needs to expand to the entire size of the tableView to show its full contents. I have tried different ways of doing this but unable to do it. I would appreciate any pointers or code segment to get this done.
There are essentially two ways to do so.
tableHeaderView
The first way involves the tableHeaderView property of the UITableView instance you have. You can simply add the UITableView with the constraints/frame/autoresizingMask that allows you to put it full-screen. Done that, you simply do (i.e. in your viewDidLoad):
UIView *headerView = [UIView new];
// Here I am supposing that you have a 200pt high view and a `self.tableView` UITableView
headerView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 200.0);
UIImageView *fixedImageView = [UIImageView new];
// configure your imageView..
[headerView addSubview:fixedImageView];
// configure labels as you want and add them to headerView as subviews
// Now set `UITableView` headerView
self.tableView.tableHeaderView = headerView;
If you want to use AutoLayout for your tableHeaderView, I suggest you to take a look at this question
Dynamic scrollView
Another way to do this is to to create an UIScrollView, put everything inside, and let it scroll. The downside of this method is that if you are using floating section headers for your UITableView, they will not float due to the fact that the tableView is going to stay fixed, while the parent scrollView is going to scroll.
On the other side, this approach is more AutoLayout friendly due to the fact you can use constraints easily.
To do so, you start adding an UIScrollView to your view, and placing all your other views inside it.
Be sure to add a Vertical Spacing constraint between the first view inside your scrollView (I suppose the UIImageView) and the scrollView top, and between the last view (I suppose the UITableView) and the scrollView bottom, to avoid an ambiguous content size.
You should have something like that (I omitted the labels for the sake of brevity):
Note that every view is inside a parent UIScrollView
After that, add an Height constraint to the tableView, and add an IBOutlet to your view controller subclass, i.e. like this:
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewHeightConstraint;
Now you only need to configure this constraint to reflect the tableView natural height, given by its rows, etc. To do so, you simply calculate the height in this way:
// Resize TableView
CGFloat height = self.tableView.contentSize.height;
self.tableViewHeightConstraint.constant = height;
Now the tableView will resize, and due to its constraints it will adapt the parent scrollView contentSize.
Just be sure to refresh this height constraint anytime you reload the UITableView dataSource.

Make UIView scroll with UITableView but pin to top out of view

I currently have a view controller that is comprised of a Navigation bar, followed by a UIView that has two UIButtons added as subViews. There is then a UITableView underneath that begins at the bottom of the container UIView.
At the moment, when the user scrolls the UITableView it goes behind the UIView and UIButtons. What I actually want to happen is for the UIView and UIButtons to move up with the table view but only by the value of their height which in this case is 58 pixels. The flow would be like this...
1) Table scrolls and the UIView moves with it for the first 58 pixels.
2) The user continues to scroll the table but the UIView "pins" itself just out of view under the navigation bar.
3) When the user scrolls the table back down the UIView is then picked up and dragged back into view. I believe the new Facebook app does something similar in the timeline.
I don't want to set the UIView as the TableHeaderView of the table as I also have a pull-to-refresh which then sits above the buttons and looks terrible. I've tried playing around with the contentOffset properties of the underlying scrollview of the table but have hit a brick wall.
Any advice on where to start would be appreciated.
Thanks
EDIT: I am gotten a little further and using this code to move the frame of the UIView.
-(void) scrollViewDidScroll:(UIScrollView *)scrollView
{
NSLog (#"Content Offset: %f", self.tableView.contentOffset.y);
NSLog (#"Button Frame: %f", self.btnBackground.frame.origin.y);
if (self.tableView.contentOffset.y > 0)
{
CGRect newFrame = self.btnBackground.frame;
newFrame.origin.x = 0;
newFrame.origin.y = -self.tableView.contentOffset.y;
[self.btnBackground setFrame: newFrame];
}
}
The problem now is that the scrollViewDidScroll delegate method doesn't get fired quickly enough if the table view is scrolled fast. The result is that the UIView doesn't quite make all way back to its original position when scroll quickly.
The scroll content offset is a good idea. Also if you tableview has only one section one approach is to do a custom header view representing the top level widgets. If there is more than one sections create an additional empty section which would return your custom header.
You can refer to this stack overflow post.
Customize UITableview Header Section
Well Asked Question (y)
well , for me i would first : use a main UIScrollView that contains both your topView and the tableView under it and that has the same width as your top UIView and UITableView and set its height to be height(tableView) + height(topView).
Second : since UITableView is a subClass of UISCrollView you can use scrollViewDidScroll delegate to know if the tableview is scrolled up or down.
in this cas you will have Two cases :
1) tableview is scrolled up = > you set the content offset of the main scrollView to be
[scrollView setContentOffset:CGPointMake(0, 58) animated:YES];
2) when the table view is scrolled down you can reset the content offset again
[scrollView setContentOffset:CGPointMake(0, 0) animated:YES];

Resources