iOS: UITableView scrollbar hidden by subview - ios

My UITableView has a subview with a fixed position. But when I scroll, the scrollbar is hidden by the subview. How can I avoid this?
## EDIT ##
self.menuViewRelative = [[UIView alloc] init];
self.menuViewRelative.backgroundColor = [UIColor whiteColor];
self.menuViewRelative.opaque = YES;
self.menuViewRelative.frame = CGRectMake(0.0, -1.0, 320.0, 50.0);
[self.view insertSubview:self.menuViewRelative atIndex:11];
This subview is now above 10 other subviews and exactly 1 layer under the scrollView (so it displays the scroll indicator perfectly).

Adding as an answer as per Jesse Rusak's comment.
Set scrollIndicatorInsets for the table view in such a way that the scroller will be moved in a place where subview wont overlap.
For eg:-
self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 7.0);

Are you using addSubview: for this? That will make it the top-most subview, which will cover the scroll bars. If you instead use insertSubview:atIndex: and ensure it's just above the other content in your table view, it will be below the scroll bars.
You might need to override layoutSubviews of the UITableView (like I describe in this related question) and look through the contents of the table view in order to keep your floating view just above the table view cells.

Related

IOS/Objective-C: Unhindered scrolling of tableview created in code (remove rubber band effect)

I have created a tableview in code as follows:
_myTableView = [[UITableView alloc] initWithFrame:
CGRectMake(160, 80, 140, 100) style:UITableViewStylePlain];
_myTableView.delegate = self;
_myTableView.dataSource = self;
_myTableView.scrollEnabled = YES;
[self.view addSubview:_myTableView];
It largely works as it should with the following exception. Because the results in the table vary, I manually adjust the height of the tableview so that it only takes up as much space as the returned rows need as follows:
-(void) changeTVHeight: (float) height {
//height calculated from number of items in array returned.
CGRect newFrame = CGRectMake(120, 80, 180, height);
self.myTableView.frame = newFrame;
}
This works great for shrinking the tableview if there aren't that many results.
However, if there are a lot of results, the tableview expands below the visible part of the screen or the keyboard. In this case, I would like to be able to scroll the Tableview to see the lower rows.
scrollEnabled is set to YES.
But while it does allow one to scroll a bit, the scroll is resisted so with effort you can scroll a little bit but due to rubber band effect you cannot get further than a few rows below the screen and you cannot tap on the lower rows.
I am using autolayout in storyboard for much of the screen. The overall screen scrolls fine but this merely moves the tableview anchored to the screen up and down. There are no constraints on this tableview but it is added as a subview of the view.
My question is how can I make the tableview scrollable so that it scrolls without resistance?
Thanks in advance for any suggestions.
Edit:
I tried adding the tableView to self.scrollView instead of self.view. This anchored the tableView to the scrollview so it is possible to scroll the whole screen down and see the bottom of the tableview. However, this is not ideal because the rest of the screen is empty way down and you can't see the context for the tableview. (It's an autocomplete for a textfield at top of screen.)
In contrast when the tableview is added to self.view, it is in correct place, it semi-scrolls or bounces. It just doesn't scroll down to where I need it to scroll.
You need to set a limit so that the table view cannot be larger than the view itself. Tableviews are built on UIScrollView and will handle scrolling on their own, you don't need to try to size it manually. The reason the table view bounces but doesn't scroll is because it is extending below the bottom of the screen. It wont scroll because it has already scrolled to the bottom, you just can't see it because it's outside of the superview.
-(void) changeTVHeight: (float) height {
CGFloat limitedHeight = MIN(height, self.view.frame.size.height)
CGRect newFrame = CGRectMake(120, 80, 180, limitedHeight);
self.myTableView.frame = newFrame;
}

Scrollable UITableView as an overlay

I'm trying to replicate the following GIF from Postmates checkout - a scrollable UITableView positioned on top of a MapView. This tableview can be scrolled, with the normal bounce effect if I go too far down or up.
Currently, I have the MapView and UITableView added as sibling views to my ViewController's view. I have adjusted the frame of the table view to move it down.
CGRect rect = CGRectMake(
0.f,
200.f,
self.view.bounds.size.width,
self.view.bounds.size.height - self.navigationController.navigationBar.bounds.size.height - 200.f
);
The two main issue's I'm having are:
I cannot figure out how to drag the entire tableview down when pulling down. E.g. the grey (my tableView.backgroundColor) sticks when I scroll down. If however, I make that background clear, then when I drag up, you see the map emerging from behind the view.
My cells keep disappearing when I scroll up. I have clipsToBounds = false, and I'm not actually dequeuing cells, just creating them in my cellForRow method, but they still disappear.
I feel like this should be a straightforward layout, but I'm missing something!
I've tried adjusting the contentInset of the table view, but then the scrollbar does not align with the cells as it does in the gif and does not look nice.
We needed similar effect in our app, along with parallax in the underlying view(map here/ we had a photos gallery).
I assume you want something like shown on this blogs video here
I wrote a small blog on how to achieve this. You can find this here
Basically its just a play of contentInsets and contentOffset properties of UITableView
If this does not suits you, here my suggestion in your two main points.
Controller's View has subviews
Map View (fills complete super view)
UITableView (fills complete super view) and in code set content insets.top = kHeightOfVisibleMap
The solution was simpler than I thought, no autolayout or crazy weird tricks required.
Add a full screen table view to your controller, and insert a full screen map view behind it.
self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
[self.view insertSubview:self.mapView belowSubview:self.tableView];
Add a dummy view with the background color of your table view with a height of around 200 pixels, and a full width, into the tableFooterView on your table view.
CGFloat footerHeight = 200.0;
UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, footerHeight)];
dummyView.backgroundColor = [UIColor whiteColor];
self.tableView.tableFooterView = dummyView;
Set the content offset of the table view to be the inverse of that footer view's height:
CGFloat footerHeight = dummyFooterView.bounds.height;
self.tableView.contentOffset = CGPointMake(0, -footerHeight);
Set the content inset of your table view to offset the footer view.
self.tableView.contentInset = UIEdgeInsetsMake(footerHeight, 0, -footerHeight, 0)
Adjust the scrollbar position, again, based on the footer's height.
self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(footerHeight, 0, 0, 0);
This will push down the tableview, ensure the scroll bars match the table view, but allow it to bounce 'up' above its initial position and will ensure the background does not peek through the bottom of the tableview.

UITableViewCells scroll over header when scrolling down

I'm trying to figure out what my options are for having the top of a UITableView be able to stay at rest about 1/3 down the screen but still be able to scroll over the top of an image above it.
I was thinking UITableView on a UIScrollView but I haven't seen this exact thing while googling around for it.
Basically I'm looking to have a header and then the table view will scroll over the top of the header without the header moving. If I set the table view below a simple uiview or imageview, it will always be below it.
Any suggestions?
Add your header as a separate view below your table view. Your table view should completely overlap the underlying view, as if it would obscure it. Then set the table view's tableHeaderView to a transparent UIView, through which you will be able to see your underlying header view. Your table view's background colour should also be clear.
CGRect headerFrame = self.underlyingHeaderView.bounds;
UIView *transparentView = [UIView alloc] initWithFrame:headerFrame];
transparentView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = transparentView;

Add a footer to UITableView at the bottom

I am doing a slide menu using a UITableView and I have 2 options on the menu and I want to put a button at the bottom like in this image:
I try to do that add a tableFooterView like that.
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 500, 320, 70)];
footerView.backgroundColor = [UIColor blackColor];
self.tableView.tableFooterView = footerView;
However, the view appears just after the second cell, but I want it at the bottom.
Thanks for help.
No you shouldn't add any empty cells, that's just hacky. If you really need the button to be at the bottom, you should use layoutSubviews to control the frame of the tableView and the footerView.
- (void)layoutSubviews
{
[super layoutSubviews];
self.tableView.frame = // top 80% of the screen
self.footerView.frame = // bottom 20% of the screen
}
You should know that every UITableViewCell has its height and footer is part of a UITableView and will appear at the bottom of a UITableView. If you want to make your UITableView look like what that image shows, you should make sure that your cells are high enough to make sure that your UITableView are high enough so that footer will appear at the bottom of UITableView
My suggestion is to add extra "empty" cell(I mean a cell with no content but has a height).
Add a Container View with View Controller from storyboard. You can use autoresizing to set the buttons on right place.

how to expand image on UITableView like in CNN app

I have the CNN app on my iPhone.
If you open it will show "top stories", and has always a picture on the top of the table.
When we slide our finger down it expands/zooms the image.
When we slide our finger up to show more rows it does not move the image upwards at the same speed has the table rows instead the table rows move faster than the picture going off the screen.
Do you know how to do this effect?
You need UIImageView to UIScrollView contentInset and set top inset more than zero.
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
UIImage *topImage = [UIImage imageNamed:#"photo"];
topImage.frame = CGRectMake(0, -topImage.frame.size.height, topImage.frame.size.width, topImage.frame.size.height);
[scroll addSubview:topImage];
self.contentInset = UIEdgeInsetsMake(topImage.frame.size.height, 0, 0, 0);
After that set UIScrollView's contentOffset like this
scroll.contentOffset = CGPointMake(0, topImage.frame.size.height);
So you have the UIScrollView with image inside it. Now you just need to add delegate to UIScrollView and wait for - (void)scrollViewDidScroll:(UIScrollView *)scrollView. Resize image and change contentInset right after this method called.
This advice you also can apply to UITableView similar way, or create category on UIScrollView.
I also advice you to read code of this project https://github.com/samvermette/SVPullToRefresh. It's also about UITableView and adding view to it's top side
It seems like a completely custom effect that you will have to implement yourself. To point you in the right direction, I'd first monitor contentOffset changes in the scrollViewDidScroll: messages sent by your myTableView instance, and when the contentOffset.y < 0, change the scale of your imageView via
[myImageView setValue:[NSNumber numberWithFloat:scaleIncrementAmountFloat] forKeyPath:#"transform.scale"];
My guess is that the top cell (or cells) of the tableview are transparent and there is a UIImageView behind the tableview that is resized/moved based on how the table view is scrolled.
Since the table view inherits from UIScrollView, its delegate (UITableViewDelegate) inherits from the UIScrollViewDelegate protocol which is notified when a the user scrolls the scroll view. Implement the - (void)scrollViewDidScroll:(UIScrollView *)scrollView method to receive these notifications and check the contentOffset property on the scroll view.
You may have to implement you own table view controller to build the desired UI in the interface builder.

Resources