Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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).

  • Carousel is a subclass of UIView
  • At init, it creates an UIView, containing UIScrollView, UIPageControl
  • I can add further UIViews to the scroll view

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)];
like image 951
andreas Avatar asked Jul 27 '12 17:07

andreas


1 Answers

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.

like image 197
WrightsCS Avatar answered Oct 27 '22 15:10

WrightsCS