UICollectionView How to implement horizontal align scrolling - ios

I have a UICollection which is implemented and works, however I cannot achieve the scrolling I want.
Here is a picture of my UICollectionView, I have resized the grey cell to 250 by 250.
My issue is, when I start scrolling, this is what happens.
My cell first starts off on the far left, but notice what happens if I start to scroll horizontally.
As you can see, the seam between the cells moves over to the left the more I scroll through the cells. This is not what I want.
What I want to achieve is: the cell is aligned to the center, and when you scroll, instead of the center of the cells moving to the left more and more, I want the cell to stay in the middle. Much like a PageViewController does except I want it to be UICollectionViewCells.
I have tried adding in the following code for example:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
float pageWidth = 210;
float currentOffset = scrollView.contentOffset.x;
float targetOffset = targetContentOffset->x;
float newTargetOffset = 0;
if (targetOffset > currentOffset)
newTargetOffset = ceilf(currentOffset / pageWidth) * pageWidth;
else
newTargetOffset = floorf(currentOffset / pageWidth) * pageWidth;
if (newTargetOffset < 0)
newTargetOffset = 0;
else if (newTargetOffset > scrollView.contentSize.width)
newTargetOffset = scrollView.contentSize.width;
targetContentOffset->x = currentOffset;
[scrollView setContentOffset:CGPointMake(newTargetOffset, 0) animated:YES];
}
Which achieves the even scrolling, however I want to have paging enabled aswell as bounce.
Because if I enable paging and bounce, the scrolling is very smooth and elegant, however If I use the code up above the scrolling is very rugged and mechanical.
So How can I achieve even scrolling that is smooth like apples default scrolling, with my UICollectionViewCell being centred in the middle?
If I didn't explain the problem well enough, this post here explains my problem except I am using one cell instead of three, and I want the scrolling to be smooth and bounce etc.

I think this should work (disable paging):
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (!decelerate) {
// do your calculations
[scrollView setContentOffset:CGPointMake(newTargetOffset, 0) animated:YES];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// do your calculations
[scrollView setContentOffset:CGPointMake(newTargetOffset, 0) animated:YES];
}

Related

How to detect scrolling to an end of an horizontal UICollectionView

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
}
}
}

How to Calculate Scrollview width and height on every scroll in iOS

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 to find if the scroll position in the webview for scrolling till the end or till the top?

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
}
}

Make a UI scroll view scroll with a UIPageViewController

I am creating an app where I am trying to have a pagescrollviewcontroller swipe through screens and have the top "nav" bar titles scroll real time with the titles
i have the title bar view as a custom view and I am able to access the scroll delegate methods for both the custom scroll view and the pageview controller. However. I don't see how to access the real time scroll pos? I know it is possible because twitter does it (really can't shouldn't be in anyone's vocabulary) but I am not sure how to achieve this.
a picture
the home title swipes at the same scroll pos as the pagecontrollers.
current code:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
if(scrollView.tag == 100) {
CGPoint point = CGPointMake(mainScrollView.contentOffset.x * 1,0);
[titleSwipe setContentOffset:point animated:YES];
}
else {
mainScrollView.contentOffset = CGPointMake(0,1);
[mainScrollView setContentOffset:titleSwipe.contentOffset animated:YES];
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate: (BOOL)decelerate {
CGPoint point = CGPointMake(mainScrollView.contentOffset.x * 2,0);
[titleSwipe setContentOffset:point animated:YES];
}
You'll find the real time position in scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// X scroll
//
CGFloat percentage = scrollView.contentOffset.x / scrollView.contentSize.width;
NSLog(#"Scrolled percentage: %f", percentage);
}
Hope that helps!

How do you wrap multiple UIViews in a rounded rectangle for sorting (picture attached)?

In the following picture, how do you have Multi-option picker and the horizontal scroller in the same white rounded rectangle? It looks great for sorting, and I'd love to implement something like that.
You need to have a UITableView with two sections (one named "section 1" and one named "section 2").
Each section has a single row, and each row's "cell" contains an option picker inside it's "Accessory View".
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/tableview_iphone/TableViewCells/TableViewCells.html
That option picker is not part of the system's library of controls, I don't know where it came from.
You could do the option picker as a UIScrollView, attaching a UIPageControl to it, inside a UIView, with two UIViews (or UIImageViews) providing the transparent fading effect. You add n-views to the scrollview, each with the same height/width. If you want the snap, which I imagine you will, track the current page with the UIScrollViewDelegates like so:
-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
float pageWidth = scrollview.frame.size.width;
int page = floor((scrollview.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
[self scrollview:scrollview scrollToPage: page];
}
-(void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if( decelerate == FALSE )
{
float pageWidth = scrollview.frame.size.width;
int page = floor((scrollview.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
[self scrollview:scrollview scrollToPage: page];
}
}
And the scrollview:scrollToPage: method will give you the snap like so:
-(void) scrollview:(UIScrollView*) scrollview scrollToPage:(NSInteger) page
{
[_myPageControl setCurrentPage:page];
CGRect frame = scrollview.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollview scrollRectToVisible:frame animated:YES];
}

Resources