If I've got a uiscrollview which is five pages wide, what code would tell me what page I am on, when I scroll to a new page? Also, what code would scroll to a specific page?
Thanks!
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGFloat pageWidth = scrollView.frame.size.width;
int currentPage = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = currentPage;
}
I have the scrollview frame width as the page width. If you are using something else as page width, make respective changes to get this to work
for scrolling to current page - if I understand it right, you have an option to enter page number and choose to scroll to that page:
Just the code above, do it reverse order, and solve for contentOffset.X
once you have the x value, create a frame with that x in it, and scrollToRect: animated: will do the work.
Check out the PageControl example from Apple:
http://developer.apple.com/iphone/library/samplecode/PageControl/Listings/ReadMe_txt.html
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat scroller_x = [scrollView contentOffset].x;
CGFloat scroller_y = [scrollView contentOffset].y;
NSLog(#"%f, %f",scroller_x,scroller_y);
}
Once this delegate method fires (on scroll) check it against each views frame.origin.x and frame.origin.y The view's frame that matches will be the view that you scrolled to.
[scrollView setContentOffset:<#(CGPoint)#>];
use this method to scroll to a specific view.frame.origin. So suppose you have an action to go to a specific view, you can use [scrollView setContentOffset:view.frame.origin] to get there.
(assumed paging is enabled)
Related
Is there a way that I can use those paging dots independently in my app,
add them to my UIView/NIB and call the functions on it to set total number of dots or current page/dot.
Basically I've UIViewImage in a nib file, i'm displaying images (names taken off an array) on swipe gestures and want to show those paging dots on the bottom for the navigation information.
UIPageControl has it's total page & current page/dot just as you described, let's say pageControl is a instance of UIPageControl, then you can initiate the numberOfPages & currentPage as below:
pageControl.numberOfPages = [images count];
pageControl.currentPage = 0;
Also, you can add action for it when the pageControl's dots was tapped. changePage: method here is just a example:
[pageControl addTarget:self action:#selector(changePage:) forControlEvents:UIControlEventValueChanged];
You can add your images to a UIScrollView and use its delegate method: scrollViewDidScroll::
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// Update the page number
CGFloat pageWidth = scrollView.frame.size.width;
pageControl.currentPage = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
}
It'll change the pageControl's current dot when your swiped to a new image.
I'm a beginner when it comes to page control, and that's why I'm not sure 100% if my title agrees with what I want. I want to make a UIPageControl that when the user swipes on the screen, the view would switch over to another view and the UIPageController at the bottom of the screen would update itself. Also, to make my request even more confusing, I want a tab bar at the bottom of the screen that would stay put as the views change.
A great example of this is The Iconfactory's Ramp Champ:
http://img.slidetoplay.com/screenshots/ramp-champ_5.jpg
The bar at the bottom stays put while the rest of the items on the screen moves. What would be the easiest way to do this?
EDIT: I know I have to use a UISrollView, I just don't know how to go about implementing it...
I believe what you're looking for is actually a UIScrollView with pagingEnabled set to YES. You can leave the scrollview as a view above a regular UITabBar. You'll use a UIPageControl to get the little dots. You can update it programmatically when the UIScrollView scrolls to a page by implementing an appropriate delegate method of the scroll view, maybe -scrollViewDidScroll:.
Assume you have two ivars: scrollView and pageControl. When you know how many pages your scroll view will have, you can set the contentSize of scrollView. It should be a multiple of the scrollView's bounds. For example, if the number of pages is static you can hardcode it in your -viewDidLoad...
- (void)viewDidLoad {
// Any other code.
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.bounds.size.width * 3, scrollView.bounds.size.height); // 3 pages wide.
scrollView.delegate = self;
}
Then, to update your little dots...
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = scrollView.bounds.size.width;
NSInteger pageNumber = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = pageNumber;
}
You need to use a UIScrollView
Assuming you have a named ivar called scrollView
int amountOfFrames = 10;
scrollView.pagingEnabled = TRUE;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * amountOfFrames, scrollView.frame.size.height);
scrollView.delegate = self;
You will then need to implement the required delegate methods, so that you can update your page control
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
}
You need to place whatever content you want to be scrollable inside these scrollview, ideally lazyload into it, if the content you will displaying will require a lot of heap memory, use the scrollviewDidScroll to remove and add content at the required positions
How do I navigate to a specific page programmatically. Basically I have an app with a scrollView populated with a bunch of subviews (tableViews in this case). When clicking on a subview it zooms in and the user can edit and navigate the table, however when I zoom back out I reload the entire view in case there were any changed made by the user. Of course reloading the view sends the user back to page 0. I've tried setting the pageControl.currentpage property but all that does is change the dot of the pageControl. Does that mean that something is wrong or do I need to do something else as well??
All that is controlling the page scrolling is this method:
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
NSString *listName = [self.wishLists objectAtIndex:self.pageControl.currentPage];
self.labelListName.text = listName;
}
You have to calculate the corresponding scroll position manually. To scroll to page i:
[scrollView setContentOffset:CGPointMake(scrollView.frame.size.width*i, 0.0f) animated:YES];
Swift 5 you can easily use scrollView.scrollRectToVisible
If the Horizontal paging scroll view implemented, which has the size of default view width of the device and wanted to navigate to number n page:
scrollView.scrollRectToVisible(CGRect(x: self.view.center.x * n, y: self.view.center.y, width: self.view.frame.width, height: self.view.frame.height) ,animated: true)
You just have to define the CGRect() position according to your scrollview configurations.
Swift 5 version of above answer by Ole Begemann
scrollView.setContentOffset( CGPoint(x: scrollView.frame.size.width * i, y: 0.0), animated: true)
I have a paging UIScrollView that pages through multiple full screen images. I am tiling the pages, queuing and dequeuing the UIViews dynamically as the scroll view pages through the collection of images, based on Apple example code.
I have a toolbar button the calls scrollRectToVisible:animated: to move the UIScrollView to a specific image. That works perfectly.
The problem is that if you then do a single touch in the UIScrollView, it scrolls back to the page it was displaying before the button was touched and the scrollRectToVisible:animated: method call scrolled the view.
If your touch is moving, the UIScrollView scrolls as expected, and subsequent touches do not cause the UIScrollView to move back to the original page.
How do I prevent this behavior?
Thanks
jk
You need to use content offset rather than scrollRectToVisible, eg:
[pagingScrollView setContentOffset:[self offsetForPageAtIndex:page] animated:YES];
where offsetForPageAtIndex looks like this:
- (CGPoint)offsetForPageAtIndex:(NSUInteger)index {
CGRect pagingScrollViewFrame = [self frameForPagingScrollView];
CGPoint offset;
offset.x = (pagingScrollViewFrame.size.width * index);
offset.y = 0;
return offset;
}
This is based off the Apple "photoscroller" example code from WWDC 2010, which had a frameForPagingScrollView that looks like this:
- (CGRect)frameForPagingScrollView {
CGRect frame = [[UIScreen mainScreen] bounds];
frame.origin.x -= PADDING;
frame.size.width += (2 * PADDING);
return frame;
}
A full copy of that version of the Photoscroller sample code is here:
https://github.com/jogu/WWDC-2010/tree/master/PhotoScroller
Though Joseph's answer sent me the right way, I had some odd behaviour when rotating the device. I found that using offset.x = (pagingScrollView.bounds.size.width * index); instead worked better.
I'm trying to do a horizontal scroll of UILabels with different widths.
I've already put all labels next to each other inside the UIScrollView, but since the page scrolling, bouncing and snapping is done in scrollview.frame.width "steps", i cannot set it to work as I'd wish.
Can this be done? Thank you so much :)
What happens if you set the size of your width property to be the width of the next label? Something like (in your scroll view delegate) :
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
// Get the label that's going to slide into view
UIView *label = [self getCurrentLabel];
// Get it's width
float width = [label frame].size.width;
// Set our size
CGRect frame = [scrollView frame];
frame.size.width = width;
[scrollView setFrame:frame];
}
PS I've not tried this so it might just fail horribly!