i have a view that is required to be stayed on the view when the user scroll up or down in a scrollview.
i managed to let it stay on top of the view but how can i allow it to stay at the bottom of the view when i scroll down ? EDIT: attached picture to explain better.
the view will alway be visible on the view.
-(void) scrollViewDidScroll:(UIScrollView *)scrollView
{
NSLog (#"Content Offset: %f", self.playlistTableview.contentOffset.y);
if (self.playlistTableview.contentOffset.y > playerPosition) // will keep the view at the top
{
CGRect newFrame = self.playerView.frame;
newFrame.origin.x = 0;
newFrame.origin.y = +self.playlistTableview.contentOffset.y;
[self.playerView setFrame: newFrame];
}
}
you can see how the NZD have a top overlay that stops
Try to add your ScrollView and Always Stay view in a container view. So it will not scroll when you do scroll the scroll view. and anytime you can change your always stay view to different frame to top or bottom as u needed
UIView--->
1st subview--->UIScrollView
2nd subview--->Don't ScrollMeView/Always Stay view
I think you have added your view in contain of UIScrollView.
I mean, main container for your view is UIScrollview, so it'll work as subview of UIScrollview and will follow scrollview properties.
Can you please try to add your view on main view.
[self.view addSubView:yourViewObj];
If that comes behind the scrollView, then please try with
[self.view bringSubviewToFront:yourViewObj];
Related
I am having a (UIView and UICollectionView in a UIScrollView) as 1stVC. I have to scroll both at the same time for which I already unable the collection view scrolling. So first time When I launch that screen I am able to scroll the whole view, But when I push to (next ViewController) 2ndVC and then press Back Button to 1stVC my scroll view is not preforming it got Freeze.
Tried this Method:-
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
dispatch_async(dispatch_get_main_queue(), ^ {
CGRect contentRect = CGRectZero;
for(UIView *view in self.scrollView.subviews)
contentRect = CGRectUnion(contentRect,view.frame);
self.scrollView.contentSize = contentRect.size;
});
}
Tried this Method:-
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[_scrollView setContentSize:CGSizeMake(_scrollView.frame.size.width, _scrollView.frame.size.height)];
}
And For Getting Dynamic Height of the Collection view I have Done This
CGFloat height = _collectionCompass.contentSize.height;
Which I Have provided to ScollView ContentSize.
_scrollView.contentSize = CGSizeMake(_scrollView.frame.size.width, height);
Please help me.
What I really suggest it's to remove scroll view and do all stuff in collection view, since with scroll view you're missing some of benefits (e.g. cells reusing). Also collection view in scroll view it's a bad practice.
From Apple style guide:
Don’t place a scroll view inside of another scroll view. Doing so creates an unpredictable interface that’s difficult to control.
If your UI as list, you can add view as header of collection view or as another cell. With this approach you can remove the code from viewDidLayoutSubviews
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.
I have to divide the view int two,on the first half i have to add a scroll view(i.e to call a specific method in scroll view for setting a page) and on the second half i have to add another scroll view.I have to do this programmatically.Please help.
You can easily split a UIView into two.
If I understand you right I would do something like this
UIScrollView scroller1 = [UIScrollView alloc]initWithFrame:CGRectMake(0,0, splittedView.frame.size.width /2, splittedView.frame.size.height) ];
UIScrollView scroller2 = [UIScrollView alloc]initWithFrame:CGRectMake(splittedView.frame.size.width /2,0, splittedView.frame.size.width /2, splittedView.frame.size.height) ];
[splittedView addSubView: scroller1];
[splittedView addSubView: scroller2];
Now you have a view with two scrollviews on it. And every scrollview has half the size of your main view.
I have 2 scroll views, both of which are supposed to scroll vertically. The outer scroll view (red) contains a search bar and the inner scroll view (blue). The inner scroll view is supposed to scroll infinitely (it contains images/items and has an endless scrolling implementation).
The way I want this controller to work is as follows:
When I scroll down, the outer scroll view should scroll first and the search bar should disappear (scroll out of the content area). Only after that the inner scroll view should start scrolling.
When scrolling back up, the inner scroll view should scroll all the way to its top. Only then the outer scroll view should take the scroll events and finally scroll up to make the search bar visible again.
If I just nest them in IB without any modifications the inner scroll view catches all the scroll events and it works the other way around.
Please bear in mind that I'm using the inner scroll view as a simplifying metaphor here. In my app I actually have a control here, which has a scroll view with nested table views (scroll view lets me page horizontally, table views let me scroll vertically).
If you are able to, set a common UIScrollViewDelegate on the 2 scroll views, and implement the following:
- (void) scrollViewDidScroll: (UIScrollView*) scrollView
{
if (scrollView == self.mainScrollView)
{
/* Handle instances when the main scroll view is already at the bottom */
if ( scrollView.contentOffset.y
== scrollView.contentSize.height - scrollView.bounds.size.height)
{
/* Stop scrolling the main scroll view and start scrolling the
* inner scroll view
*/
self.innerScrollView.scrollEnabled = YES;
self.mainScrollView.scrollEnabled = NO;
}
else
{
/* Start scrolling the main scroll view and stop scrolling the
* inner scroll view
*/
self.innerScrollView.scrollEnabled = NO;
self.mainScrollView.scrollEnabled = YES;
}
}
else if (scrollView == self.innerScrollView)
{
/* Handle instances when the inner scroll view is already at the top */
if (self.innerScrollView.contentOffset.y == 0)
{
/* Stop scrolling the inner scroll view and start scrolling the
* main scroll view
*/
self.innerScrollView.scrollEnabled = NO;
self.mainScrollView.scrollEnabled = YES;
}
else
{
/* Start scrolling the inner scroll view and stop scrolling the
* main scroll view
*/
self.innerScrollView.scrollEnabled = YES;
self.mainScrollView.scrollEnabled = NO;
}
}
}
Please note that I haven't tested this, but the logic could be somewhat like this (either you set scrolling enabled or you disable user interaction, or something). Most probably this will not be enough of a solution as you would like, but I'm sure a common UIScrollViewDelegate is the solution to your problem.
I given the example for one scrollview, samething you have to create onemore scrollview and add based on dynamic height and content size it will work.
// .h file
#property (nonatomic, strong) UIScrollView *scrlSearch;
// .m File // ViewDidLoad
scrlSearch = [[UIScrollView alloc] init];
// For first scroll screen height was ((total screen height / 100 )* 10% )
// For Second scroll screen height was ((total screen height / 100 )* 90% )
scrlSearch.frame = CGRectMake(0, 0, (YourScreenWidth), (YourScreenHeight));
// YourVIEW = add any view to scrollbar
[scrlSearch addSubview:YourVIEW];
CGSize contentSize = scrlSearch.frame.size;
// YourContentHeight = dynamic content or static content height
contentSize.height = YourContentHeight;
// set the ContentHeight for scrolling
[scrlSearch setContentSize:contentSize];
// add the scrollview into delegate
[scrlSearch setDelegate:self];
Use just one scrollView and set the contentInset/contentOffset for the search bar. Something along this line:
UIEdgeInsets oldEdgeInset = [[self scrollView] contentInset];
CGRect f = [[self searchBar] frame];
UIEdgeInsets newEdgeInset = UIEdgeInsetsMake(CGRectGetMaxY(f), 0, 0, 0);
CGPoint offset = [[self scrollView] contentOffset];
offset.y += oldEdgeInset.top - newEdgeInset.top;
[[self scrollView] setContentOffset:offset];
[[self scrollView] setContentInset:newEdgeInset];
[[self searchBar] setFrame:f];
I am not sure about the structure you have and want to implement..
I have made a test project find here
But the project will definitely help you to manage different scrollviews all together..
The application might not be perfect though, but will give you some idea to achieve the solution.
Hope it helps..
Cheers
You should add inner scrollview on outer scrollview, but inner scrollview 'y' position should be content off set of outer scrollview like...
innerScrollView.frame = CGRectMake(10, outerScrollView.contentSize.height, 300, 440);
After this you can add any view on this innerScrollView, you can set contentOffset etc for innerScrollView.
Finally you should increase the contentSize for outer scrollview.
outerScrollView.contentSize = CGSizeMake(320, innerScrollView.frame.size.height+actualContentSizeOfOuterScroolView);
I think it helps for you!
Create a swipe gesture recognizer to your top-most view (above all the scroll views, on your view controller's view), and make it recognize UISwipeGestureRecognizerDirectionUp.
Then, you need to notify your controller whenever the outer scroll view scrolls.
Once it's scrolled down, add the gesture recognizer. When it hits the top again (outerScrollView.contentOffset == (0,0)), remove the gesture recognizer.
The gesture should 'eat' all the swiping events while it's present, making your inner scroll views to not receive the touch event and therefore will not scroll
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];