2010-09-09 4 views
0

Pour l'application sur laquelle je travaille, j'ai besoin d'un scrollview avec pagination avec un certain nombre de vues (dans ce cas, vues de table). Configurer cela (en utilisant l'exemple PageControl d'Apple) est assez facile et je n'ai aucun problème à le faire fonctionner en ce qui concerne le défilement et l'accrochage entre les pages. Je veux que les vues de table soient presque comme des représentations miniatures des vues de table dans le scrollview. Une fois que vous cliquez sur celui-ci, il s'ouvre ou zoome pour laisser la vue de la table couvrir tout l'écran. Encore une fois, mettre en place ce n'est pas vraiment un problème, je peux faire les vues à l'intérieur de la scrollview toute taille que je veux et le clic, je suis sûr que je peux me mettre au travail quand j'arrive à cette partie. :)Définition de la quantité de défilement avec UIScrollView et PageControl

Mon problème est le suivant: Dans n'importe quelle vue, quelle que soit la page sur laquelle je suis, je veux que la page suivante et la page précédente soient légèrement visibles sur les côtés droit et gauche respectivement. Bien sûr, sur la première page, il n'y aurait plus qu'une page à droite ou à gauche pour la dernière page. Encore une fois, en définissant l'origine x des vues (vues de table) affichées, je peux obtenir la première page à regarder à droite. Cependant, dès que vous faites défiler le problème devient évident, à savoir que l'écran défile trop loin. Je suppose que mon principal problème est que je ne peux pas sembler changer la quantité de défilement fait lors du changement de pages.

J'apprécierais n'importe quelle aide que je peux obtenir sur ceci, merci.

AppDelegate.h

#import <UIKit/UIKit.h> 

@interface AppDelegate : NSObject <UIApplicationDelegate, UIScrollViewDelegate> { 
UIWindow *window; 
UIView *background; 
UIScrollView *scrollView; 
UIPageControl *pageControl; 
NSMutableArray *viewControllers; 

// To be used when scrolls originate from the UIPageControl 
// I've commented this out (and all references to it) since I've disabled user interaction with the UIPageControl 
//BOOL pageControlUsed; 
} 

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UIView *background; 

@property (nonatomic, retain) IBOutlet UIScrollView *scrollView; 
@property (nonatomic, retain) IBOutlet UIPageControl *pageControl; 
@property (nonatomic, retain) NSMutableArray *viewControllers; 

- (IBAction)changePage:(id)sender; 

@end 

AppDelegate.m

#import "AppDelegate.h" 
#import "MyViewController.h" 

static NSUInteger kNumberOfPages = 4; 

@interface AppDelegate (PrivateMethods) 

- (void)loadScrollViewWithPage:(int)page; 
- (void)scrollViewDidScroll:(UIScrollView *)sender; 

@end 

@implementation AppDelegate 

@synthesize window, scrollView, pageControl, viewControllers, background; 

- (void)dealloc { 
[background release]; 
[viewControllers release]; 
[scrollView release]; 
[pageControl release]; 
[window release]; 
[super dealloc]; 
} 

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

background.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Background.png"]]; 

// view controllers are created lazily 
// in the meantime, load the array with placeholders which will be replaced on demand 
NSMutableArray *controllers = [[NSMutableArray alloc] init]; 
for (unsigned i = 0; i < kNumberOfPages; i++) { 
    [controllers addObject:[NSNull null]]; 
} 
self.viewControllers = controllers; 
[controllers release]; 

// a page is the width of the scroll view 
scrollView.pagingEnabled = YES; 
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height); 
scrollView.showsHorizontalScrollIndicator = NO; 
scrollView.showsVerticalScrollIndicator = NO; 
scrollView.scrollsToTop = NO; 
scrollView.delegate = self; 

pageControl.numberOfPages = kNumberOfPages; 
pageControl.currentPage = 0; 

// pages are created on demand 
// load the visible page 
// load the page on either side to avoid flashes when the user starts scrolling 
[self loadScrollViewWithPage:0]; 
[self loadScrollViewWithPage:1]; 
} 

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

// replace the placeholder if necessary 
MyViewController *controller = [viewControllers objectAtIndex:page]; 
if ((NSNull *)controller == [NSNull null]) { 
    controller = [[MyViewController alloc] initWithPageNumber:page]; 
    [viewControllers replaceObjectAtIndex:page withObject:controller]; 
    [controller release]; 
} 

// add the controller's view to the scroll view 
if (nil == controller.view.superview) { 
    CGRect frame = CGRectMake(50, 50, 220, 330); 
    frame.origin.x = 50 + (250 * page); 
    frame.origin.y = 50; 
    controller.view.frame = frame; 
    [scrollView addSubview:controller.view]; 
} 
} 

- (void)scrollViewDidScroll:(UIScrollView *)sender { 
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in 
// which a scroll event generated from the user hitting the page control triggers updates from 
// the delegate method. We use a boolean to disable the delegate logic when the page control is used. 
/*if (pageControlUsed) { 
    // do nothing - the scroll was initiated from the page control, not the user dragging 
    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]; 

// A possible optimization would be to unload the views+controllers which are no longer visible 
} 

// At the begin of scroll dragging, reset the boolean used when scrolls originate from the UIPageControl 
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
//pageControlUsed = NO; 
} 

// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl 
- (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. See  scrollViewDidScroll: above. 
//pageControlUsed = YES; 
} 

@end 
+0

Je suis à la recherche d'aide sur ce problème ... changer le montant du défilement à quelque chose de moins que la taille de l'écran. J'ai les pages prev/next visibles, mais en faisant défiler jusqu'à la page suivante, il défile trop loin. Puisque les pages suivantes/précédentes sont légèrement visibles, le défilement de la page est très léger. Quelqu'un a une idée? – Valerie

+0

J'ai fini par utiliser cette méthode: http://blog.proculo.de/index.php?url=archives/180-Paging-enabled-UIScrollView-With-Previews.html. J'espère que cela aide – Glitch

Répondre

0

Il semble que vous définissez la taille du cadre de la scrollView et le cadre de controller.view différemment. Le ScrollView est un IBOutlet, cela signifie que vous créez le ScrollView usign le constructeur d'interface, mais vous mettez le contenu à l'aide des lignes:

CGRect frame = CGRectMake(50, 50, 220, 330); 
frame.origin.x = 50 + (250 * page); 
frame.origin.y = 50; 
controller.view.frame = frame; 
[scrollView addSubview:controller.view]; 

et de le mettre dans le ScrollView. Si vous ne voulez pas voir la page précédente/suivante sur le côté de votre scrollView, vous devez changer les chiffres que vous utilisez à la première ligne. Essayez d'utiliser `scrollView.frame.size ou vérifiez la taille d'image du scrollView que vous avez créé à partir de l'IB et utilisez-les à la place des nombres magiques que vous devriez éviter.

Questions connexes