2012-04-17 13 views
50

Sto creando una semplice visualizzazione di diapositive all'interno della mia app. Vorrei collegare il mio UIPageControl al mio UIScrollView. Questo non dovrebbe essere troppo difficile, ma non sono stato in grado di trovare una soluzione semplice da nessuna parte. Di seguito è il mio codice.Collegamento UIPageControl a UIScrollView a livello di codice

HelpViewController.h

#import <UIKit/UIKit.h> 

@interface HelpViewController : UIViewController{ 
} 
@end 

HelpViewController.m

#import "HelpViewController.h" 

@interface HelpViewController() 

@end 

@implementation HelpViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    CGRect scrollViewFrame = CGRectMake(0, 62, 320, 404); 
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame]; 
    [self.view addSubview:scrollView]; 
    CGSize scrollViewContentSize = CGSizeMake(640, 404); 
    [scrollView setContentSize:scrollViewContentSize]; 
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(200, 200, 50, 21)]; 
    [label setText:@"Hello"]; 
    [scrollView addSubview:label]; 
    [scrollView setPagingEnabled:YES]; 
    scrollView.showsHorizontalScrollIndicator = NO; 
    UIPageControl *pageControl = [[UIPageControl alloc] init]; 
    pageControl.frame = CGRectMake(110,5,100,100); 
    pageControl.numberOfPages = 2; 
    pageControl.currentPage = 0; 
    [self.view addSubview:pageControl]; 
    pageControl.backgroundColor = [UIColor redColor]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

@end 
+0

Ho risposto correttamente qui https://stackoverflow.com/questions/3533047/how-do-you-combine-uiscrollview-with-uipagecontrol-to-show-different-views/14230698#14230698 meglio avere risposta su un posto ... Ho risolto le modifiche proposte lì. – Renetik

risposta

77

Forse questo funziona per voi

Non dimenticare di impostare l'UIScrollView delegato = auto (o dove si ha la selettore sotto).

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 
    CGFloat pageWidth = self.scrollView.frame.size.width; // you need to have a **iVar** with getter for scrollView 
    float fractionalPage = self.scrollView.contentOffset.x/pageWidth; 
    NSInteger page = lround(fractionalPage); 
    self.pageControl.currentPage = page; // you need to have a **iVar** with getter for pageControl 
} 

Per il vostro codice di allora sarebbe:

file h

#import <UIKit/UIKit.h> 

@interface HelpViewController : UIViewController{ 
} 

@property (nonatomic, retain) UIScrollView *scrollView; 
@property (nonatomic, retain) UIPageControl * pageControl; 
@end 

di file .m

#import "HelpViewController.h" 

@interface HelpViewController() 

@end 

@implementation HelpViewController 
@synthesize scrollView=scrollView_; 
@synthesize pageControl=pageControl_; 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    CGRect scrollViewFrame = CGRectMake(0, 62, 320, 404); 
    self.scrollView = [[[UIScrollView alloc] initWithFrame:scrollViewFrame] autorelease]; 
    self.scrollView.delegate = self; 
    [self.view addSubview:self.scrollView]; 
    CGSize scrollViewContentSize = CGSizeMake(640, 404); 
    [self.scrollView setContentSize:scrollViewContentSize]; 
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(200, 200, 50, 21)]; 
    [label setText:@"Hello"]; 
    [self.scrollView addSubview:label]; 
    [self.scrollView setPagingEnabled:YES]; 
    self.scrollView.showsHorizontalScrollIndicator = NO; 
    self.pageControl = [[[UIPageControl alloc] init] autorelease]; 
    self.pageControl.frame = CGRectMake(110,5,100,100); 
    self.pageControl.numberOfPages = 2; 
    self.pageControl.currentPage = 0; 
    [self.view addSubview:self.pageControl]; 
    pageControl.backgroundColor = [UIColor redColor]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { 
     CGFloat pageWidth = self.scrollView.frame.size.width; 
     float fractionalPage = self.scrollView.contentOffset.x/pageWidth; 
     NSInteger page = lround(fractionalPage); 
     self.pageControl.currentPage = page; 
    } 


@end 
+0

Grazie per l'assistenza! La logica è solida, ma non capisco perfettamente l'implementazione. Ho aggiornato il mio intervento per includere i miei file .h e .m completi. –

+0

aggiornato! basta copiare il codice .. :) ... non è testato, c'è forse un refuso. Ma dovrebbe funzionare. –

+0

Grazie mille. Mi hai risparmiato un sacco di mal di testa.Il mio problema è finito con il delegato. –

2

per ottenere indice esatto della pagina senza arrotondamento del valore semplicemente metti pagecontrol.currentpage nel metodo scrollViewDidEndDecelerating delegate della scroll view. Questo funziona per me!

51

Questo è in realtà abbastanza semplice da configurare. In primo luogo è necessario creare la visualizzazione a scorrimento e il controllo della pagina. Assicurati di implementare UIScrollViewDelegate nell'interfaccia della classe.

UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * 3, scrollView.frame.size.height); 
    scrollView.delegate = self; 

    UIPageControl * pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 90, scrollView.frame.size.width, 20)]; 
    pageControl.numberOfPages = scrollView.contentSize.width/scrollView.frame.size.width; 
    [pageControl addTarget:self action:@selector(changePage:) forControlEvents:UIControlEventValueChanged]; 

allora avete bisogno di aggiungere le seguenti due metodi:

- (IBAction)changePage:(id)sender { 
    CGFloat x = pageControl.currentPage * scrollView.frame.size.width; 
    [scrollView setContentOffset:CGPointMake(x, 0) animated:YES]; 
} 

-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    NSInteger pageNumber = roundf(scrollView.contentOffset.x/(scrollView.frame.size.width)); 
    pageControl.currentPage = pageNumber; 
} 

Questi metodi aggiungono la comunicazione necessaria tra il controllo della pagina e la vista di scorrimento.

+0

Per determinare correttamente il numero di pagina necessario per multiplo da paginaControllo.numero Pagine –

0

Tutte queste risposte sono grandi, ma mi piacerebbe offrire una soluzione alternativa, utilizzando ReactiveCocoa!

Il seguente codice presuppone l'esistenza di una proprietà denominata scrollView e una chiamata pageControl.

[RACObserve(self.scrollView, contentOffset) 
    subscribeNext:^(NSValue* value){ 
     CGPoint offset = [value CGPointValue]; 
     CGFloat fractional = offset.x/self.scrollView.width; 
     [self.pageControl setCurrentPage:lroundf(fractional)]; 
    }]; 

Tutto quello che sta succedendo qui è che stai osservando il cambiamento sulla proprietà contentOffset del ScrollView e calcolando l'indice di pagina su ogni evento successivo (vale a dire ogni volta che cambia il valore della proprietà).

L'unico svantaggio di questo è che è necessario rimuovere la casella di posta del CGPoint ma al rialzo non è necessario il codice UIScrollViewDelegate necessario!

Problemi correlati