Reputation: 215
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!
Upvotes: 4
Views: 5369
Reputation: 5893
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
Upvotes: 0
Reputation: 367
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.
Upvotes: 0
Reputation: 167
Put your page controller out side of ScrollView in xid and give the apposite color to page controller.
Upvotes: 0
Reputation: 2674
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."
Upvotes: 3