andreas
andreas

Reputation: 8014

UIPageControl doesn't properly react to taps

In my TestApp, I created a class "Carousel" which should let me create a swipe menu with a UIPageControl in an easy way (by simply creating an instance of the class Carousel).

I don't know if this is the proper way to do it, but my example worked quite well in my TestApp. Swiping between pages works perfectly and the display of the current page in the UIPageControl is correct.

If there were not one single problem: The UIPageControl sometimes reacts to clicks/taps (I only tested in Simulator so far!), sometimes it doesn't. Let's say most of the time it doesn't. I couldn't find out yet when it does, for me it's just random...

As you can see below, I added

[pageControl addTarget:self action:@selector(pageChange:) forControlEvents:UIControlEventValueChanged];

to my code. I thought this would do the proper handling of taps? But unfortunately, pageChange doesn't get always called (so the value of the UIPageControl doesn't change every time I click).

I would appreciate any input on this because I couldn't find any solution on this yet.

This is what I have so far:

Carousel.h

#import <UIKit/UIKit.h>

@interface Carousel : UIView {
    UIScrollView *scrollView;
    UIPageControl *pageControl;
    BOOL pageControlBeingUsed;
}

- (void)addView:(UIView *)view;
- (void)setTotalPages:(NSUInteger)pages;
- (void)setCurrentPage:(NSUInteger)current;
- (void)createPageControlAt:(CGRect)cg;
- (void)createScrollViewAt:(CGRect)cg;

@end

Carousel.m

#import "Carousel.h"

@implementation Carousel

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];

    if (self) {

        // Create a scroll view
        scrollView = [[UIScrollView alloc] init];
        [self addSubview:scrollView];

        scrollView.delegate = (id) self;

        // Init Page Control
        pageControl = [[UIPageControl alloc] init];
        [pageControl addTarget:self action:@selector(pageChange:) forControlEvents:UIControlEventValueChanged];
        [self addSubview:pageControl];

    }

    return self;

}

- (IBAction)pageChange:(id)sender {
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * pageControl.currentPage;
    frame.origin.y = 0;
    [scrollView scrollRectToVisible:frame animated:TRUE];
    NSLog(@"%i", pageControl.currentPage);
}

- (void)addView:(UIView *)view {
    [scrollView addSubview:view];
}

- (void)createPageControlAt:(CGRect)cg {
    pageControl.frame = cg;
}

- (void)setTotalPages:(NSUInteger)pages {
    pageControl.numberOfPages = pages;
}

- (void)setCurrentPage:(NSUInteger)current {
    pageControl.currentPage = current;
}

- (void)createScrollViewAt:(CGRect)cg {
    [scrollView setPagingEnabled:TRUE];
    scrollView.frame = cg;
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width*pageControl.numberOfPages, scrollView.frame.size.height);
    [scrollView setShowsHorizontalScrollIndicator:FALSE];
    [scrollView setShowsVerticalScrollIndicator:FALSE];

}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    float frac = scrollView.contentOffset.x / scrollView.frame.size.width;
    NSUInteger page = lround(frac);
    pageControl.currentPage = page;

}

@end

ViewController.m (somewhere in viewDidLoad)

Carousel *carousel = [[Carousel alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];

for (int i=0; i<5; i++) {
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(i * 320, 0, 320, 420)];
    UIColor *color;
    if(i%3==0) color = [UIColor blueColor];
    else if(i%3==1) color = [UIColor redColor];
    else color = [UIColor purpleColor];
    view.backgroundColor = color;
    [carousel addView:view];
    view = nil;
}

[carousel setTotalPages:5];
[carousel setCurrentPage:0];

[carousel createPageControlAt:CGRectMake(0,420,320,40)];
[carousel createScrollViewAt:CGRectMake(0,0,320,420)];

Upvotes: 6

Views: 4269

Answers (1)

WrightsCS
WrightsCS

Reputation: 50727

Your code is correct. Most likely the frame of your pageControl is pretty small, so theres not a lot of area to look for touch events. You would need to increase the size of the height of pageControl in order to make sure taps are recognized all of the time.

Upvotes: 4

Related Questions