Is UIPageControl useless for myself?

I studied using UIPageControl for the scrolling part of the application, and I was wondering how it works. The docs show methods for changing pages, setting the number of pages, etc., but the page control itself does not cover any kind of scrolling.

Are the UIPageControl and UIScrollView classes supposed to be shared when you want to show a page indicator (for example, on the iPhone home screen with application pages)?

+12
objective-c iphone uikit scroll paging
Jul 09 '09 at 13:31
source share
5 answers

The paging bit is actually performed by setting the paging property in UIScrollView. The page control is just a useful UI construct, but it really does nothing to do with the search call itself.

+10
Jul 09 '09 at 14:26
source share

I wrote a class (PagedView) that works just like a UITableView, and combines the concepts of UIPageControl and UIScrollView in a way that is used, for example, on the iPhone home screen.

The concept is basically this: you need to implement PagedViewDelegate to return the number of pages and the view for each page of the PagedView. Reusing views works just like in a UITableView. Use the interface constructor to connect the scrollview and pageControl outputs.

Please let me know if you find this class useful.

.h file:

// // PagedView.h // // Created by Werner Altewischer on 22/10/10. // Copyright 2010 werner-it.com. All rights reserved. // @protocol ReusableObject - (NSString *)reuseIdentifier; - (void)prepareForReuse; @end @class PagedView; @protocol PagedViewDelegate - (NSUInteger)numberOfPagesInPagedView:(PagedView *)view; - (UIView *)pagedView:(PagedView *)view viewForPageAtIndex:(NSUInteger)page; @end @interface PagedView : UIView<UIScrollViewDelegate> { IBOutlet UIScrollView *scrollView; IBOutlet UIPageControl *pageControl; NSMutableDictionary *pageViewDictionary; NSMutableDictionary *reuseViewDictionary; IBOutlet id <PagedViewDelegate> delegate; } @property (nonatomic, assign) IBOutlet id <PagedViewDelegate> delegate; - (UIView<ReusableObject> *)dequeueReusableViewWithIdentifier:(NSString *)identifier; - (void)scrollToPageAtIndex:(NSUInteger)pageIndex animated:(BOOL)animated; - (NSInteger)indexForSelectedPage; - (CGSize)pageSize; - (void)reloadData; @end 

.m file:

 // // PagedView.m // // Created by Werner Altewischer on 22/10/10. // Copyright 2010 werner-it.com. All rights reserved. // #define TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; } @interface PagedView (Private) - (NSUInteger)pageCount; - (UIView *)loadViewForIndex:(NSUInteger)pageIndex; - (void)unloadViewForIndex:(NSUInteger)pageIndex; - (void)loadViewsForVisiblePages:(BOOL)reloadData; - (UIView *)viewForIndex:(NSUInteger)pageIndex; @end @implementation PagedView @synthesize delegate; - (void)dealloc { TT_RELEASE_SAFELY(pageViewDictionary); TT_RELEASE_SAFELY(reuseViewDictionary); TT_RELEASE_SAFELY(scrollView); TT_RELEASE_SAFELY(pageControl); [super dealloc]; } - (CGSize)pageSize { return scrollView.frame.size; } - (void)reloadData { if (!pageViewDictionary) { //First time initialization pageViewDictionary = [NSMutableDictionary new]; reuseViewDictionary = [NSMutableDictionary new]; [pageControl addTarget:self action:@selector(pageChanged:) forControlEvents:UIControlEventValueChanged]; scrollView.delegate = self; scrollView.pagingEnabled = YES; } CGSize size = self.pageSize; NSUInteger numberOfPages = self.pageCount; pageControl.numberOfPages = MAX(1, numberOfPages); [scrollView setContentSize:CGSizeMake(size.width * numberOfPages, size.height)]; pageControl.currentPage = self.indexForSelectedPage; pageControl.hidden = (numberOfPages == 0); [self loadViewsForVisiblePages:YES]; } - (void)layoutSubviews { if (!pageViewDictionary) { [self reloadData]; } } - (void)scrollToPageAtIndex:(NSUInteger)pageIndex animated:(BOOL)animated { if (pageIndex < self.pageCount) { CGSize size = scrollView.frame.size; CGRect rect = CGRectMake(size.width * pageIndex, 0, size.width, size.height); [scrollView scrollRectToVisible:rect animated:animated]; } } - (NSInteger)indexForSelectedPage { CGFloat cx = scrollView.contentOffset.x; NSUInteger index = (NSUInteger)(cx / scrollView.frame.size.width); if (index >= self.pageCount) { index = NSNotFound; } return index; } #pragma mark - #pragma mark UIScrollViewDelegate implementation - (void)scrollViewWillBeginDragging:(UIScrollView *)theScrollView { theScrollView.userInteractionEnabled = NO; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)theScrollView { if (theScrollView == scrollView) { pageControl.currentPage = self.indexForSelectedPage; [self loadViewsForVisiblePages:NO]; theScrollView.userInteractionEnabled = YES; } } - (void)pageChanged:(UIPageControl *)thePageControl { if (pageControl == thePageControl) { [self scrollToPageAtIndex:pageControl.currentPage animated:YES]; [self loadViewsForVisiblePages:NO]; } } - (UIView<ReusableObject> *)dequeueReusableViewWithIdentifier:(NSString *)identifier { UIView<ReusableObject> *v = [[[reuseViewDictionary objectForKey:identifier] retain] autorelease]; if (v) { [v prepareForReuse]; [reuseViewDictionary removeObjectForKey:identifier]; } return v; } @end @implementation PagedView (Private) - (NSUInteger)pageCount { return [self.delegate numberOfPagesInPagedView:self]; } - (UIView *)viewForIndex:(NSUInteger)pageIndex { id key = [NSNumber numberWithUnsignedInteger:pageIndex]; return [pageViewDictionary objectForKey:key]; } - (UIView *)loadViewForIndex:(NSUInteger)pageIndex { id key = [NSNumber numberWithUnsignedInteger:pageIndex]; UIView *v = [pageViewDictionary objectForKey:key]; if (!v) { CGSize size = self.pageSize; UIView *v = [self.delegate pagedView:self viewForPageAtIndex:pageIndex]; if (v) { v.frame = CGRectMake(pageIndex * size.width, 0, size.width, size.height); [scrollView addSubview:v]; [pageViewDictionary setObject:v forKey:key]; } } return v; } - (void)unloadViewForIndex:(NSUInteger)pageIndex { id key = [NSNumber numberWithUnsignedInteger:pageIndex]; UIView *v = [pageViewDictionary objectForKey:key]; if (v) { if ([v conformsToProtocol:@protocol(ReusableObject)]) { NSString *reuseIdentifier = [(id <ReusableObject>)v reuseIdentifier]; [reuseViewDictionary setObject:v forKey:reuseIdentifier]; } [v removeFromSuperview]; [pageViewDictionary removeObjectForKey:key]; } } - (void)loadViewsForVisiblePages:(BOOL)reloadData { //load the selected view and the one in front and behind NSUInteger selectedPage = self.indexForSelectedPage; NSUInteger numberOfPages = self.pageCount; int intSelectedPage = (selectedPage == NSNotFound) ? -2 : (int)selectedPage; //Find the max number present in the pageViewDictionary NSUInteger existingPageCount = 0; for (NSNumber *key in pageViewDictionary) { if ([key unsignedIntegerValue] >= existingPageCount) { existingPageCount = [key unsignedIntegerValue] + 1; } } for (int i = 0; i < MAX(numberOfPages, existingPageCount); ++i) { if (i >= numberOfPages || i < (intSelectedPage - 1) || i > (intSelectedPage + 1)) { [self unloadViewForIndex:i]; } else { if (reloadData) { //Unload the view if we're reloading all the data [self unloadViewForIndex:i]; } [self loadViewForIndex:i]; } } [reuseViewDictionary removeAllObjects]; } @end 
+20
Oct 25 2018-10-10
source share

The UIPageControl has two functions: (1) it displays the points, including the selected point for the currently selected page, and (2) it generates the UIControlEventValueChanged event when the user clicks on it. Click the right side of the control on the page on the right; click on the left side of the page to the left. You must implement this behavior according to HIG!

To catch an event, add:

 [myUiPageControl addTarget:self action:@selector(pageChanged:) forControlEvents:UIControlEventValueChanged]; 

and delegate function:

 -(void)pageChanged:(UIPageControl*)thePageControl; 

The name can be whatever you want; For example, I used "pageChanged". Callback signatures can be: pageChanged, pageChanged :, or pageChanged: forEvent :. This callback function should trigger a scroll update (or whatever you have).

Paging itself is usually done using a UIScrollView with paging enabled and hidden scrollbars. Tell scrollview to use paging and clicks to magically move page by page; make sure you catch this change to update the currentPage property of UIPageControl.

+7
Jun 07 '11 at 10:18
source share

You are right - UIPageControl does not draw anything except points at the bottom of the page; you need a different view to do this.

+2
Jul 09 '09 at 13:36
source share

To use the Werner Altewischer class, add a PagedViewDelegate to interact and complete your class, as shown below:

 @interface ViewController (){ //header view UIPageControl* headPageControl; UIScrollView* headScrollView; PagedView* headerView; NSMutableArray* headerViews; } //header view -(void)initHeader; -(void)setHeaderViews:(NSMutableArray*)views; -(void)addHeaderView:(UIView*)view; -(void)popHeader; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self initHeader]; [self popHeader]; } -(void)initHeader { float frameWidth = self.view.frame.size.width; headPageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, HEADER_HEIGHT-PAGE_CONTROL_HEIGHT, frameWidth, PAGE_CONTROL_HEIGHT)]; [headPageControl setBackgroundColor:[UIColor colorWithWhite:0.0 alpha:0.5]]; headerViews = [NSMutableArray array]; headScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, frameWidth, HEADER_HEIGHT)]; headScrollView.showsHorizontalScrollIndicator = NO; headerView = [[PagedView alloc] initWithFrame:CGRectMake(0, 0, frameWidth, HEADER_HEIGHT)]; headerView.delegate = self; headerView.pageControl = headPageControl; headerView.scrollView = headScrollView; [headerView addSubview:headScrollView]; [headerView addSubview:headPageControl]; [headerView setBackgroundColor:[UIColor darkGrayColor]]; [self.view addSubview:headerView]; } -(NSUInteger)numberOfPagesInPagedView:(PagedView *)view { //NSLog(@"number of pages %i", headPageControl.numberOfPages); return headPageControl.numberOfPages; } -(UIView*)pagedView:(PagedView *)view viewForPageAtIndex:(NSUInteger)page { //NSLog(@"open page %i", page); return [headerViews objectAtIndex:page]; } -(void)setHeaderViews:(NSMutableArray*)views { headerViews = views; headPageControl.numberOfPages = headerViews.count; } -(void)addHeaderView:(UIView*)view { [headerViews addObject:view]; headPageControl.numberOfPages = headerViews.count; } -(void)popHeader { float frameWidth = self.view.frame.size.width; CGRect _frame = CGRectMake(0, 0, frameWidth, HEADER_HEIGHT); UIView* v = [[UIView alloc] initWithFrame:_frame]; [v setBackgroundColor:[UIColor greenColor]]; [self addHeaderView:v]; UIView* v0 = [[UIView alloc] initWithFrame:_frame]; [v0 setBackgroundColor:[UIColor purpleColor]]; [self addHeaderView:v0]; UIView* v1 = [[UIView alloc] initWithFrame:_frame]; [v1 setBackgroundColor:[UIColor yellowColor]]; [self addHeaderView:v1]; } 
+1
Oct 18 '12 at 12:39 on
source share



All Articles