do you know a way in order to detect when a user has scrolled to the end (or the beginning) of an UICollectionView (in order to load new content). Since the UICollectionView scrolls horizontally and not vertically, I am not interested to the scrolling to top/bottom but to leftmost/rightmost.
The only way I found so far is to subclass the UICollectionView and then register the view controller as a delegate that is informed of when the collection view willLayoutSubviews and perform calculations accordingly.
But let's say I don't want to subclass UICollectionView, is there a way to detect the scrolling to the end/beginning of UICollectionView?
EDIT:
since UICollectionView inherits from UIScrollView, I can use its delegate methods. How does it work with with horizontal scrolling?
Thank you
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offsetX = scrollView.contentOffset.x;
CGFloat contentWidth = scrollView.frame.size.width;
NSLog(#"offset X %.0f", offsetX);
// If your UICollectionView has 3 cell, the contentWidth is 320,
// When you scroll from beginning to end of the UICollectionView, it will print:
// offset X 0
// offset X 1
// offset X 2
// ......
// offset X 320
// offset X 640
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ([scrollView isKindOfClass:[UICollectionView class]] == YES) {
CGFloat threshold = 100.0 ;
CGFloat contentOffset = scrollView.contentOffset.x;
CGFloat maximumOffset = scrollView.contentSize.width - scrollView.frame.size.width;
if ((maximumOffset - contentOffset <= threshold) && (maximumOffset - contentOffset != -5.0) ){
//Your code
}
}
}
Related
Is there any way while the user is scrolling an uitableview to know when one of the many uitableviewcells is offscreen by 70% when reaching the top? Should i use willdisplaycell for this? Any help appreciated.
Implement scrollViewDidScroll...
get the frame of the row / cell you want to track
compare it to the scroll offset to see how much of it is visible
In this simple example, rowToTrack is an NSInteger, such as 2 for the 3rd row, sectionToTrack is an NSInteger, such as 0 for the 1st section:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// index path for row we want to track
NSIndexPath *p = [NSIndexPath indexPathForRow:rowToTrack inSection:sectionToTrack];
// get frame for that row
CGRect r = [self.tableView rectForRowAtIndexPath:p];
// get bottom of row frame
CGFloat t1 = CGRectGetMaxY(r);
// get scroll content offset
CGFloat t2 = scrollView.contentOffset.y + scrollView.adjustedContentInset.top;
// height of visible portion of row frame
CGFloat visibleHeight = t1 - t2;
// as a percentage between 0 and 1
CGFloat pct = MAX(0.0, MIN(1.0, visibleHeight / r.size.height));
NSLog(#"Row %ld is %0.2f percent visible", rowToTrack, pct * 100);
}
I could not found any where for this kind sticky issue.My issue is when the user started scrolling i need to change the alpha value.At starting of scrolling alpha value should be 1, then at middle of scrolling alpha value should be 0.5, at end it must be 0.This what i need to do.i could not find with googling. help me plz
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
/* This is the offset at the bottom of the scroll view. */
CGFloat totalScroll = scrollView.contentSize.height - scrollView.bounds.size.height;
/* This is the current offset. */
CGFloat offset = - scrollView.contentOffset.y;
/* This is the percentage of the current offset / bottom offset. */
CGFloat percentage = offset / totalScroll;
/* When percentage = 0, the alpha should be 1 so we should flip the percentage. */
scrollView.alpha = (1.f - percentage);
}
Here is how to do it in Swift, i have 2 UILabel in my controller, and i need to increase alpha for the first UILabel and decrease alpha for the second :
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
// Bottom
}
if (scrollView.contentOffset.y < 0){
// Top
lblTitleHeader.alpha = 0
lblTitleBody.alpha = 1
}
if (scrollView.contentOffset.y >= 0 && scrollView.contentOffset.y < (scrollView.contentSize.height - scrollView.frame.size.height)){
// Middle
let percentage: CGFloat = (scrollView.contentOffset.y) / 20
// This label loses alpha when you scroll down (or slide up)
lblTitleHeader.alpha = (percentage)
// This label gets more alpha when you scroll up (or slide down)
lblTitleBody.alpha = (1 - percentage)
}
}
I have a UIScrollView which holds a custom drawing view. The drawing view is used to draw a large content (10000x10000 pixels). Since I cannot embed huge view inside scrollview [due memory limitations], I have created a custom view which is almost twice the size of the scrollView. I have used the StreetScroller [apple sample] logic to implement the same. This works fine but there is a problem with identifying touches. You can download the updated sample from here https://github.com/praveencastelino/SampleApps/tree/master/StreetScroller
Since the contentOffset of scrollview is reset to center whenever it moves 'X amount of pixels' from its center. Hence, the scrollView content offset is different from what we actually need. This what we do in scrollView.
- (void)recenterIfNecessary
{
CGPoint currentOffset = [self contentOffset];
CGFloat contentHeight = [self contentSize].height;
CGFloat contentWidth = [self contentSize].width;
CGPoint centerOffset,distanceFromCenter;
centerOffset.y = (contentHeight - [self bounds].size.height) / 2.0;
distanceFromCenter.y = fabs(currentOffset.y - centerOffset.y);
centerOffset.x = (contentWidth - [self bounds].size.width) / 2.0;
distanceFromCenter.x = fabs(currentOffset.x - centerOffset.x);
if (distanceFromCenter.y > (contentHeight / 6.0))
{
self.contentOffset = CGPointMake(currentOffset.x, centerOffset.y);
[_labelContainerView didResetByVerticalDistancePoint:CGPointMake(currentOffset.x, centerOffset.y - currentOffset.y) visibleFrame:[self bounds]];
}
if (distanceFromCenter.x > (contentWidth / 6.0))
{
self.contentOffset = CGPointMake(centerOffset.x, currentOffset.y);
[_labelContainerView didResetByHorizontalDistancePoint: CGPointMake(centerOffset.x - currentOffset.x, currentOffset.y) visibleFrame:[self bounds]];
}
}
Whenever scrollview resets the center, the custom view notified and it tracks the virtual content offset.
-(void)didResetByVerticalDistancePoint:(CGPoint)distance visibleFrame:(CGRect)frame
{
_contentOffsetY += distance.y;
NSLog(#"_contentOffsetY %f",_contentOffsetY);
[self setNeedsDisplay];
}
However, I wanted to calculate the virtual content offset whenever scroll view scrolls [At present the content offset is calculated only when we reset content offset of scrollview to center]. This would eventually help me in handling touches.
Also, I need a way to restrict the bounds of the scrollview from scrolling infinitely. I want to display only the content and avoid the scrolling if user tries to scroll it further.
I have Scrollview using for displaying images along with two buttons previous and next.
Now my problem is when the user is scrolling the image I want to identify whether it is from right to left scroll or vice versa. For this purpose I have to calculate scrollview contentOffset and scrollview frame size but I don't know how to calculate those values.
Still now I used:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0){}
this method.
need any suggestions.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView1 willDecelerate:(BOOL)decelerate;
{
CGFloat pageWidth = scrollView.frame.size.width;
float fractionalPage = scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
if (previousPage != page){
if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x > 0){
NSLog(#"-1");
} else {
NSLog(#"+1");
}
}
}
Hi if you are scrolling Horizontally you will get to know whether you are going next or previous depending upon velocity.x
velocity.x > 0 ?(int) _currentIndex + 1 :(int) _currentIndex - 1;
-(void) scrollViewWillBeginDragging:(UIScrollView *)scrollView {
CGFloat xAxisVisible= self.uiScrollDetails.contentOffset.x;
self.currentIndex=xAxisVisible/320;
NSLog(#"Dragging - You are now on page %i",(int) self.currentIndex);
}
How can I find if the webview has been scrolled till the top or till the last?
What checks do I need to keep on scroll offset for these two cases and which function/ delegate menthod, do I need to check it so that I know that the user has scrolled till the end or till the top?
Actually I have to change the frame of UIWebview and other views in my screen for this purpose.
Take a look at the UIScrollViewDelegate.
https://developer.apple.com/library/ios/documentation/uikit/reference/uiscrollviewdelegate_protocol/reference/uiscrollviewdelegate.html
Update
Here's an example:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
float scrollViewHeight = scrollView.frame.size.height;
float scrollContentSizeHeight = scrollView.contentSize.height;
float scrollOffset = scrollView.contentOffset.y;
if (scrollOffset == 0)
{
// then we are at the top
}
else if (scrollOffset + scrollViewHeight == scrollContentSizeHeight)
{
// then we are at the end
}
}