The property bounces can limit scroll view border, but I want to limit one border, for example: I can drag over top border, but bottom can't. I have make it using two views, but I want to find a direct way.
check scrollview's content offset if it is beyond bottom bounds using scrollViewDidScroll delegate method of UIScrollView and put bounce for scrollview check so it will bounce for top bounds.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height) {
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentSize.height - scrollView.frame.size.height)];
}
}
Note : Set scrollview delegate to self for your scrollview instance like so it will call this delegate method while scrolling . cheers :)
yourScrollviewInstance.delegate = self
Related
I'm trying to implement the following hierarchy
-- UISCrollView
-- ContainerView
-- UITableView
Initially the UITableView scroll is disabled. When the UICollectionView reaches a particular contentOffset of the UIScrollView, I implement this :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y >= 140)
{
[scrollView setContentOffset:CGPointMake(0, 140) animated:NO];
}
}
All this works as intended, but now the UIScrollView is eating the scroll of the UITableView. The scroll of UITableView is erratic now and doesn't scroll properly. The scroll of UITableView happens only after 7-8 attempts and then it stops again.
What might be the reason of this behaviour? I tried setting myScrollView.scrollEnabled = NO inside scrollViewDidScroll and no luck.
You can delay the main scroll view's touch response, then the sub tableview (scrollview) can be scrolled correctly:
myScrollView.panGestureRecognizer.delaysTouchesBegan = YES;
I have a UITableView with a UIView on top. I want the UIView to stick to the top as the tableView cells scroll over it.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (self.tableView.contentOffset.y > 0) {
CGRect newframe = self.publicTopView.frame;
newframe.origin.y = -self.tableView.contentOffset.y;
self.publicTopView.frame = newframe;
NSLog(#"After: %f", self.publicTopView.frame.origin.y);
}
}
You need to set your table view header view to the view you want on top.
Add this code to you viewDidLoad
self.tableView.tableHeaderView = self.publicTopView
I'm not certain what you're trying to accomplish, but I have a guess at what is wrong. As you scroll your contentOffset will continue to change and let's say your tableView has a content size height of 1500, then your contentOffset will eventually be larger than the height of your view controllers view. Now see that you are putting that contentOffset into the origin.y of your publicTopView. So your publicTopView could possibly be moving too much, even offscreen depending on how large your tableview's content size is.
There is a button at the bottom of my view controller. When the user scrolls down the button has to be attached to the scrollview at certain height.
I need to attach a button to the scrollview, immediately when the contentOffset.y reaches a particular value. -(void) scrollviewDidScroll doesn't help me as there might be a jump in contentOffset when the user is scrolling fast. Any leads on this are helpful.
Also, whenever I add a subview to the scrollview, -(void) viewDidLayoutSubviews is called. Which in turn sets the contentOffset to {0,0}. How can I achieve the functionality I need?
I needed to do the same thing with a UITableView and for me using scrollViewDidScroll worked.
I created a view called staticBar and added it as a subview of the tableView, but I had to rearrange the tableview subviews for it to appear in the right place. I don't have my code in front of me, but in -scrollViewDidScroll: it looked something like this:
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
CGFloat staticBarAdjustedY = _staticBarY - scrollView.contentOffset.y;
CGFloat scrollViewYFloor = scrollView.frame.size.height - _staticBar.frame.size.height;
// This way maximum Y the view can have is at the base of the scrollView
CGFloat newY = MIN( staticBarAdjustedY, scrollViewYFloor);
_staticBar.frame = (CGRect){ { _staticBar.frame.origin.x, newY}, _staticBar.frame.size}
}
I will check my code later today and add more details here.
Also, you said the scrollviewDidScroll has jumps in contentOffset, but it's worth mentioning that these jumps are the same that the scrollView uses to scroll its own view. So it's not like you are "losing" frames on this delegate method.
Hope it helps.
PS: So, here is the rest of my code.
//I place my custom view as a subview of the tableView below it's last subview
//The last subview is for scroll indicators.
WTButtonsBar *buttonBar = [[WTButtonsBar alloc] init];
[self.tableView insertSubview:buttonBar belowSubview:self.tableView.subviews.lastObject];
In scrollViewDidScroll:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//In my app I needed my view to stick to the top of the screen
//thats why I use MAX here
//self.buttonsBarOriginalY is the view's position in the scrollView when it isn't attached to the top.
CGFloat newY = MAX(scrollView.contentOffset.y, self.buttonsBarOriginalY)
[_buttonsBar setFrame:(CGRect){{0, newY}, _buttonsBar.frame.size}];
}
I want to implement a kind of infinite UIScrollView which means the following:
If the user scrolls and the scroll view would bounce at the right or left end, the scroll view should expand itself into this direction instead of bouncing. The additional space would be filled with new data, loaded from a a delegate.
Thanks in advance,
Christian
Implement the scrollViewDidScroll: delegate method and check the scrollView's contentOffset. If the offset is close to the edge of the scrollView you increase the contentSize of the scrollView. E.g. to expand the scrollView to the right:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.x + scrollView.frame.size.width > scrollView.contentSize.width - 30) {
scrollView.contentSize = CGSizeMake(scrollView.contentSize.width + 200, scrollView.contentSize.height);
}
}
How can I force a UIScrollView in which paging and scrolling are on to only move horizontally left or horizontally both direction(left and right)?
To be clearer, I'd like to allow the user to 'page only horizontally backward(only bounce when the user try to scroll horizontally right)' OR 'horizontally both direction(this is normal action)' at a given moment.
I am wondering that the solution is the subclass of UIScrollView.
Thanks in advance.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ( only bounce.. ){
// is it right?
if (scrollView.contentOffset.y > 60) {
[scrollView setContentOffset:CGPointMake(0, 60)];
}
}
if ( only paing left... ){
How to do this??
}
}
I'd implement the delegate function scrollViewDidScroll: and store the state (scroll state) of the ScrollView. On subsequent calls, compare with the previous state and have it bounce back (by calling ZoomToRect: maybe) if it is in a particular direction that you don't like.