4
votes

I'd like to make use of a page control to switch between several viewControllers. I have the following viewController whose associated nib contains a UIScrollView and a UIPageControl. I've placed the scroll view above the page control by using Xcode's IB in a way that both controls are visible, and this is the .h file:

@interface NewForm : UIViewController <UIScrollViewDelegate>
{
   BOOL pageControlUsed;
}
@property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
@property (nonatomic, strong) IBOutlet UIPageControl *pageControl;
@property (nonatomic, retain) NSMutableArray *viewControllers;

- (IBAction)changePage:(id)sender;

@end

The view and the scrollView outlet are linked to File's owner, as well as the scroll view's delegate. pageControl outlet and changePage are linked to the UIPageControl.

This is the .m file (only relevant methods, actually):

@implementation STNewAccountTest
@synthesize scrollView, viewControllers, pageControl;

- (void)viewDidLoad
{
  [super viewDidLoad];

  NSMutableArray *controllers = [[NSMutableArray alloc] init];
 [controllers addObject:[[Page1 alloc] initWithNibName:@"Page1" bundle:nil]];
 [controllers addObject:[[Page2 alloc] initWithNibName:@"Page2" bundle:nil]];
 self.viewControllers = controllers;

 scrollView.pagingEnabled = YES;
 scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * numberOfPages, scrollView.frame.size.height);
 scrollView.showsHorizontalScrollIndicator = NO;
 scrollView.showsVerticalScrollIndicator = NO;
 scrollView.scrollsToTop = NO;
 scrollView.delegate = self;

 self.pageControl.currentPage = 0;
 self.pageControl.numberOfPages = numberOfPages;

 [self loadScrollViewWithPage:0];
}

- (void)loadScrollViewWithPage:(int)page
{
  if ((page < 0) || (page >= numberOfPages))
    return;

  Page1 *controller1 = nil;
  Page2 *controller2 = nil;

  if (page == 0) {
    controller = [self.viewControllers objectAtIndex:page];

    if (controller == nil) {
        controller = [[Page1 alloc] initWithNibName:@"Page1" bundle:nil];
        [self.viewControllers replaceObjectAtIndex:page withObject:controller];
    }
}
if (page == 1) {
    controller = [self.viewControllers objectAtIndex:page];

    if (controller == nil) {
        controller = [[Page2 alloc] initWithNibName:@"Page2" bundle:nil];
        [self.viewControllers replaceObjectAtIndex:page withObject:controller];
    }
}

if (controller.view.superview == nil)
{
    CGRect frame = self.scrollView.frame;
     frame.origin.x = frame.size.width * page;
     frame.origin.y = 0;
     controller.view.frame = frame;
    [self.scrollView addSubview:controller.view];
}
}

- (void)scrollViewDidScroll:(UIScrollView *)sender
{
  if (pageControlUsed)
  {
    return;
  }

  // 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;

  // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
  [self loadScrollViewWithPage:page - 1];
  [self loadScrollViewWithPage:page];
  [self loadScrollViewWithPage:page + 1];
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
  pageControlUsed = NO;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
  pageControlUsed = NO;
}

- (IBAction)changePage:(id)sender
{
  int page = pageControl.currentPage;

  // load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
  [self loadScrollViewWithPage:page - 1];
  [self loadScrollViewWithPage:page];
  [self loadScrollViewWithPage:page + 1];

// update the scroll view to the appropriate page
  CGRect frame = scrollView.frame;
  frame.origin.x = frame.size.width * page;
  frame.origin.y = 0;
  [scrollView scrollRectToVisible:frame animated:YES];

// Set the boolean used when scrolls originate from the UIPageControl
  pageControlUsed = YES;
}

When I run the app, what I see is that pages' views take up the whole screen, and I am able to navigate through pages by means of the scroll view's paging functionality, but the page control and its dots are not displayed. What can I be missing?

Thanks!

5

5 Answers

3
votes

Answered here: https://stackoverflow.com/a/4245642/1455770

"If the page control's and container's background color is the same (by default white) page control won't be visible."

0
votes

It's either the color or the order of the objects in IB.

0
votes

Put your page controller out side of ScrollView in xid and give the apposite color to page controller.

0
votes

I spent a few days trying to figure this out and just could not find any solutions on the web that solved it for me. Here's what hit me and actually worked for me- Your UIScroll View may be taking up the entire View Controller, therefor covering the Page Control. Try simply shortening the Scroll View a little and your Page Control will obviously be visible now. Match up the background of the Page Control to the background of the View Controller for a seamless finish.

0
votes
    private func setupPageControl() {

     pageControl = UIPageControl(frame:.zero)
     pageControl.translatesAutoresizingMaskIntoConstraints = false
     pageControl.currentPageIndicatorTintColor = UIColor.orange
     pageControl.pageIndicatorTintColor = UIColor.lightGray.withAlphaComponent(0.8)
     pageControl.numberOfPages = 3;
     pageControl.currentPage = 0;
     self.bringSubviewToFront(pageControl)
     addSubview(pageControl)

    let widthConstraint = NSLayoutConstraint(item: pageControl, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 50)
    let heightConstraint = NSLayoutConstraint(item: pageControl, attribute: NSLayoutConstraint.Attribute.height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: NSLayoutConstraint.Attribute.notAnAttribute, multiplier: 1, constant: 50)
    let horizontalConstraint = NSLayoutConstraint(item: pageControl, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1, constant: 0)
    let verticalConstraint = NSLayoutConstraint(item: pageControl, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self, attribute: NSLayoutConstraint.Attribute.bottom, multiplier: 1, constant: 0)
    self.addConstraints([widthConstraint, heightConstraint, horizontalConstraint,verticalConstraint])
}

Please try the above code Add this as a subview of View where scroll view is kept i.e., PageControl and Scrollview should be subviews of same UIView