contentOffset without many items in UITableView - ios

I am adding a UISearchBar to my UITableView. Like in many apps, the search bar would initially be hidden behind the navigation bar until the user scrolls upwards, revealing it. I use the code bellow to initially hide the search bar which works very well when the table view has enough cells to need scrolling, but does not hide the bar when there are only a few cells in the table view. How can I go about hiding the search bar when there are less than enough cells to cause the table view to scroll.
Current Code:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
if (!self.layedOutHeader) {
CGPoint contentOffset = self.alertsTableView.contentOffset;
if (contentOffset.y == -64 || contentOffset.y == 0) {
contentOffset.y += CGRectGetHeight(self.alertsTableView.tableHeaderView.frame);
self.alertsTableView.contentOffset = contentOffset;
}
self.layedOutHeader = YES;
}
}
Here is an example of how when only a few cells are present, the search bar is not hidden:

Try to add tableFooterView with the required height to fill the screen when you don't have enough cells.

Related

iOS - Collapsible header view inside a tableview(uiscrollview)

I am trying to achieve something similar to the parallax effect. Wont say exactly the parallax. I have a header view that is a part of the table view.
I did set the contentInset of the table view to change the location of the first cell.
The amount of the top contentInset added is the height of the header view as header view is placed in blank space created by changing the content inset.
As tableview has a default scrollview along with it so in viewDidScroll i added the following code to hide the header view as the scrollview scrolls down.
var scrollOffsetY = abs(scrollView.contentOffset.y);
scrollOffsetY -= headerView.bounds.size.height;
if(scrollView.contentOffset.y <= 0-self.topDistance && abs(scrollView.contentOffset.y) <= headerView.bounds.size.height ){
print("\(scrollOffsetY)");
//
self.headerView.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, scrollOffsetY);
}
self.headerView.setNeedsLayout();
self.headerView.layoutIfNeeded();
}
Now the problem is, the as the scroll down sometimes the header view is not fully collapsed. Is there any other way or some modifications that can help to make the transition smooth.

How to stop a UIView from scrolling with tableview?

I have a UITableViewController and I put a UIView right under the navigation item and above the actual table. The problem that I have is that the view scrolls with the tableview.
How would I get it to behave exactly like the nav bar, and have the items in the tableview scroll behind it.
Rather than having the view scroll, it should remain in its position and have everything go behind it. Sorry for reiterating, but I've found thats necessary sometimes.
The view you're placing above the cell in the storyboard becomes the table view's tableHeaderView.
You can make the header view appear fixed by resetting its frame.origin to the table view's bounds.origin every time the table view lays out its subviews:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
UIView *header = self.tableView.tableHeaderView;
CGRect frame = header.frame;
frame.origin = self.tableView.bounds.origin;
header.frame = frame;
}
Result:
Assuming you don't want the map view to move then you could set its user interaction to false.
Alternatively you could set the header of your tableView (if you only have one section) to the map view.

Collapsing toolbar layout for ios

I have a new design for my app and it include a parallax scroll for a image display on top of tableView.
I know how to add a parallax effect with putting a image in to a cell, like this -
when table scrollViewDidScroll get called :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint currentOffset = scrollView.contentOffset;
if (currentOffset.y > _lastContentOffset.y) {
//Scroll Up
_containerView.clipsToBounds = true;
_bottomSpaceConstraint.constant = -scrollView.contentOffset.y / 2;
_topSpaceConstraint.constant = scrollView.contentOffset.y / 2;
} else {
//Scroll Down
_topSpaceConstraint.constant = scrollView.contentOffset.y;
_containerView.clipsToBounds = false;
}
_lastContentOffset = currentOffset;
}
(the _bottomSpaceConstraint and _topSpaceConstraint are the Image top and Bottom constraint which inside the tableView cell in section 0)
But my problem is I needs to stop the image scrolling up when it reached the size of my navigation bar. (my navigation bar background is transparent) I don't want the image to go all the way top. But it is a cell which is inside my tableView so it is going all the way to top until it disappear when scrolling. I need help for stop this image get scrolled. Maybe my approach is not correct if I want to achieve this effect.
This effect is on android and its called "collapsing toolbar layout".
http://antonioleiva.com/collapsing-toolbar-layout/
Does someone know how to do this "collapsing toolbar layout" effect for iOS.
Thanks a lot for any help!
Try creating a UIView that will contain the image and set the tableHeaderView in the tableView. Then in scrollViewDidScroll: update the height and top constraints of the header view.

How to add a search bar at the bottom of a table view in Xcode?

I am developing an iOS application, and I want to add a search button that initiates a search of a table view. When searching, the search bar should not be scrolled with the table cells.
To make a search bar (or any view really) "stick" to the top or bottom of a UITableView there are two approaches:
Adjust the frame of the table to be the view height minus the height of your bar, and then set the bar's frame to {0, 0, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(self.tableView.frame)}, which would position it statically at the bottom of the view. If you are using a stock UITableViewController, you'll need to do some additional work because self.view and self.tableView both point to the same object. You'll need to set a new UIView to self.view which will then be the container for the table view and your search bar view.
Add the bar as a subview of table, then implement UIScrollViewDelegate in your controller and use scrollViewDidScroll: (which fires whenever the user scrolls the view) to update the bar's position. The new position would be something like:
CGRect adjustedFrame = self.searchBarView.frame;
adjustedFrame.origin.y = self.tableView.contentOffset.y + CGRectGetHeight(self.tableView.frame) - CGRectGetHeight(self.searchBarView.frame);
self.searchBarView.frame = adjustedFrame;

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