2009-07-09 11 views
12

我一直在尋找使用UIPageControl滾動應用程序的一部分,我想知道它是如何工作的。文檔顯示了更改頁面,設置頁面數量等方法,但是頁面控件本身並不包含任何類型的滾動視圖。UIPageControl本身無用嗎?

UIPageControl和UIScrollView類是否應該在需要顯示頁面指示符時使用(例如在具有應用程序頁面的iPhone主屏幕上)?

回答

10

分頁位實際上是通過在UIScrollView上設置分頁屬性來完成的。頁面控件只是一個有用的UI構造,但實際上並沒有對分頁本身做任何事情。

2

你是對的 - UIPageControl除了頁面底部的點外本身並不繪製任何東西;你需要另一種觀點來做到這一點。

20

我已經寫了一個類(PagedView),其工作方式與UITableView類似,並以例如在iPhone主屏幕上使用的方式合併UIPageControl和UIScrollView的概念。

這個概念基本上如下:你需要實現PagedViewDelegate來爲你的PagedView的每個頁面返回頁數和視圖。視圖的重用與UITableView的工作方式相同。使用界面生成器連接scrollview和pageControl插座。

請讓我知道,如果你覺得這個類有用。

.H-文件:

// 
// PagedView.h 
// 
// Created by Werner Altewischer on 22/10/10. 
// Copyright 2010 werner-it.com. All rights reserved. 
// 

@protocol ReusableObject 

- (NSString *)reuseIdentifier; 
- (void)prepareForReuse; 

@end 

@class PagedView; 

@protocol PagedViewDelegate 

- (NSUInteger)numberOfPagesInPagedView:(PagedView *)view; 
- (UIView *)pagedView:(PagedView *)view viewForPageAtIndex:(NSUInteger)page; 

@end 

@interface PagedView : UIView<UIScrollViewDelegate> { 
    IBOutlet UIScrollView *scrollView; 
    IBOutlet UIPageControl *pageControl; 
    NSMutableDictionary *pageViewDictionary; 
    NSMutableDictionary *reuseViewDictionary; 

    IBOutlet id <PagedViewDelegate> delegate; 
} 

@property (nonatomic, assign) IBOutlet id <PagedViewDelegate> delegate; 

- (UIView<ReusableObject> *)dequeueReusableViewWithIdentifier:(NSString *)identifier; 

- (void)scrollToPageAtIndex:(NSUInteger)pageIndex animated:(BOOL)animated; 
- (NSInteger)indexForSelectedPage; 

- (CGSize)pageSize; 
- (void)reloadData; 

@end 

的.m文件:

// 
// PagedView.m 
// 
// Created by Werner Altewischer on 22/10/10. 
// Copyright 2010 werner-it.com. All rights reserved. 
// 



#define TT_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; } 

    @interface PagedView (Private) 

    - (NSUInteger)pageCount; 

    - (UIView *)loadViewForIndex:(NSUInteger)pageIndex; 
    - (void)unloadViewForIndex:(NSUInteger)pageIndex; 
    - (void)loadViewsForVisiblePages:(BOOL)reloadData; 
    - (UIView *)viewForIndex:(NSUInteger)pageIndex; 

    @end 

    @implementation PagedView 

    @synthesize delegate; 

    - (void)dealloc { 
     TT_RELEASE_SAFELY(pageViewDictionary); 
     TT_RELEASE_SAFELY(reuseViewDictionary); 
     TT_RELEASE_SAFELY(scrollView); 
     TT_RELEASE_SAFELY(pageControl); 
     [super dealloc]; 
    } 

    - (CGSize)pageSize { 
     return scrollView.frame.size; 
    } 

    - (void)reloadData { 
     if (!pageViewDictionary) { 
      //First time initialization 
      pageViewDictionary = [NSMutableDictionary new]; 
      reuseViewDictionary = [NSMutableDictionary new]; 
      [pageControl addTarget:self action:@selector(pageChanged:) forControlEvents:UIControlEventValueChanged]; 
      scrollView.delegate = self; 
      scrollView.pagingEnabled = YES; 
     } 

     CGSize size = self.pageSize; 

     NSUInteger numberOfPages = self.pageCount; 
     pageControl.numberOfPages = MAX(1, numberOfPages); 
     [scrollView setContentSize:CGSizeMake(size.width * numberOfPages, size.height)]; 
     pageControl.currentPage = self.indexForSelectedPage; 

     pageControl.hidden = (numberOfPages == 0); 

     [self loadViewsForVisiblePages:YES]; 
    } 

    - (void)layoutSubviews { 
     if (!pageViewDictionary) { 
      [self reloadData]; 
     } 
    } 

    - (void)scrollToPageAtIndex:(NSUInteger)pageIndex animated:(BOOL)animated { 
     if (pageIndex < self.pageCount) { 
      CGSize size = scrollView.frame.size; 
      CGRect rect = CGRectMake(size.width * pageIndex, 0, size.width, size.height); 
      [scrollView scrollRectToVisible:rect animated:animated]; 
     } 
    } 

    - (NSInteger)indexForSelectedPage { 
     CGFloat cx = scrollView.contentOffset.x; 
     NSUInteger index = (NSUInteger)(cx/scrollView.frame.size.width); 
     if (index >= self.pageCount) { 
      index = NSNotFound; 
     } 
     return index; 
    } 

    #pragma mark - 
    #pragma mark UIScrollViewDelegate implementation 

    - (void)scrollViewWillBeginDragging:(UIScrollView *)theScrollView { 
     theScrollView.userInteractionEnabled = NO; 
    } 

    - (void)scrollViewDidEndDecelerating:(UIScrollView *)theScrollView { 
     if (theScrollView == scrollView) { 
      pageControl.currentPage = self.indexForSelectedPage; 
      [self loadViewsForVisiblePages:NO]; 
      theScrollView.userInteractionEnabled = YES; 
     } 
    } 

    - (void)pageChanged:(UIPageControl *)thePageControl { 
     if (pageControl == thePageControl) { 
      [self scrollToPageAtIndex:pageControl.currentPage animated:YES]; 
      [self loadViewsForVisiblePages:NO]; 
     } 
    } 

    - (UIView<ReusableObject> *)dequeueReusableViewWithIdentifier:(NSString *)identifier { 
     UIView<ReusableObject> *v = [[[reuseViewDictionary objectForKey:identifier] retain] autorelease]; 
     if (v) { 
      [v prepareForReuse]; 
      [reuseViewDictionary removeObjectForKey:identifier]; 
     } 
     return v; 
    } 

    @end 


    @implementation PagedView (Private) 

    - (NSUInteger)pageCount { 
     return [self.delegate numberOfPagesInPagedView:self]; 
    } 

    - (UIView *)viewForIndex:(NSUInteger)pageIndex { 
     id key = [NSNumber numberWithUnsignedInteger:pageIndex]; 
     return [pageViewDictionary objectForKey:key]; 
    } 

    - (UIView *)loadViewForIndex:(NSUInteger)pageIndex { 
     id key = [NSNumber numberWithUnsignedInteger:pageIndex]; 
     UIView *v = [pageViewDictionary objectForKey:key]; 
     if (!v) { 
      CGSize size = self.pageSize; 
      UIView *v = [self.delegate pagedView:self viewForPageAtIndex:pageIndex]; 
      if (v) { 
       v.frame = CGRectMake(pageIndex * size.width, 0, size.width, size.height); 
       [scrollView addSubview:v];  
       [pageViewDictionary setObject:v forKey:key]; 
      } 
     } 
     return v; 
    } 

    - (void)unloadViewForIndex:(NSUInteger)pageIndex { 
     id key = [NSNumber numberWithUnsignedInteger:pageIndex]; 
     UIView *v = [pageViewDictionary objectForKey:key]; 
     if (v) { 
      if ([v conformsToProtocol:@protocol(ReusableObject)]) { 
       NSString *reuseIdentifier = [(id <ReusableObject>)v reuseIdentifier]; 
       [reuseViewDictionary setObject:v forKey:reuseIdentifier]; 
      } 
      [v removeFromSuperview]; 
      [pageViewDictionary removeObjectForKey:key]; 
     } 

    } 

    - (void)loadViewsForVisiblePages:(BOOL)reloadData { 

     //load the selected view and the one in front and behind 

     NSUInteger selectedPage = self.indexForSelectedPage; 
     NSUInteger numberOfPages = self.pageCount; 

     int intSelectedPage = (selectedPage == NSNotFound) ? -2 : (int)selectedPage; 

     //Find the max number present in the pageViewDictionary 
     NSUInteger existingPageCount = 0; 
     for (NSNumber *key in pageViewDictionary) { 
      if ([key unsignedIntegerValue] >= existingPageCount) { 
       existingPageCount = [key unsignedIntegerValue] + 1; 
      } 
     } 

     for (int i = 0; i < MAX(numberOfPages, existingPageCount); ++i) { 
      if (i >= numberOfPages || 
       i < (intSelectedPage - 1) || 
       i > (intSelectedPage + 1)) { 
       [self unloadViewForIndex:i]; 
      } else { 
       if (reloadData) { 
        //Unload the view if we're reloading all the data 
        [self unloadViewForIndex:i]; 
       } 
       [self loadViewForIndex:i]; 
      } 
     } 

     [reuseViewDictionary removeAllObjects]; 
    } 

    @end 
+0

@Warner:能否請您expalin我怎麼可以使用這個類? – 2012-02-17 08:51:02

7

UIPageControl做兩兩件事:(1)它顯示點,包括當前所選頁面高亮點, (2)當用戶點擊它時產生一個UIControlEventValueChanged事件。點擊控件的右側以向右翻頁;點擊左側向左翻頁。你應該實現這個行爲是與HIG一致的!

要捕獲的事件中,添加:

[myUiPageControl addTarget:self action:@selector(pageChanged:) forControlEvents:UIControlEventValueChanged]; 

和委託功能,以及:

-(void)pageChanged:(UIPageControl*)thePageControl; 

名稱可以是任何你想要的;例如,我使用「pageChanged」。回調簽名可以是pageChanged,pageChanged:或pageChanged:forEvent :.此回調函數應該會導致您的滾動視圖(或您有什麼)更新。

分頁本身通常通過使用UIScrollView啓用分頁並隱藏滾動條來完成。告訴滾動視圖使用分頁和幻燈片一頁頁地移動;確保您捕獲該更改以更新UIPageControl的currentPage屬性。

1

要使用沃納Altewischer類添加PagedViewDelegate接口,並完成你的類,如下所示:

@interface ViewController(){ 
    //header view 
    UIPageControl* headPageControl; 
    UIScrollView* headScrollView; 
    PagedView* headerView; 
    NSMutableArray* headerViews; 
} 
//header view 
-(void)initHeader; 
-(void)setHeaderViews:(NSMutableArray*)views; 
-(void)addHeaderView:(UIView*)view; 
-(void)popHeader; 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self initHeader]; 
    [self popHeader]; 
} 

-(void)initHeader 
{ 
    float frameWidth = self.view.frame.size.width; 

    headPageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, HEADER_HEIGHT-PAGE_CONTROL_HEIGHT, frameWidth, PAGE_CONTROL_HEIGHT)]; 
    [headPageControl setBackgroundColor:[UIColor colorWithWhite:0.0 alpha:0.5]]; 

    headerViews = [NSMutableArray array]; 

    headScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, frameWidth, HEADER_HEIGHT)]; 
    headScrollView.showsHorizontalScrollIndicator = NO; 

    headerView = [[PagedView alloc] initWithFrame:CGRectMake(0, 0, frameWidth, HEADER_HEIGHT)]; 
    headerView.delegate = self; 
    headerView.pageControl = headPageControl; 
    headerView.scrollView = headScrollView; 

    [headerView addSubview:headScrollView]; 
    [headerView addSubview:headPageControl]; 

    [headerView setBackgroundColor:[UIColor darkGrayColor]]; 
    [self.view addSubview:headerView]; 
} 

-(NSUInteger)numberOfPagesInPagedView:(PagedView *)view 
{ 
    //NSLog(@"number of pages %i", headPageControl.numberOfPages); 
    return headPageControl.numberOfPages; 
} 

-(UIView*)pagedView:(PagedView *)view viewForPageAtIndex:(NSUInteger)page 
{ 
    //NSLog(@"open page %i", page); 
    return [headerViews objectAtIndex:page]; 
} 

-(void)setHeaderViews:(NSMutableArray*)views 
{ 
    headerViews = views; 
    headPageControl.numberOfPages = headerViews.count; 
} 

-(void)addHeaderView:(UIView*)view 
{ 
    [headerViews addObject:view]; 
    headPageControl.numberOfPages = headerViews.count; 
} 

-(void)popHeader 
{ 
    float frameWidth = self.view.frame.size.width; 
    CGRect _frame = CGRectMake(0, 0, frameWidth, HEADER_HEIGHT); 
    UIView* v = [[UIView alloc] initWithFrame:_frame]; 
    [v setBackgroundColor:[UIColor greenColor]]; 
    [self addHeaderView:v]; 

    UIView* v0 = [[UIView alloc] initWithFrame:_frame]; 
    [v0 setBackgroundColor:[UIColor purpleColor]]; 
    [self addHeaderView:v0]; 

    UIView* v1 = [[UIView alloc] initWithFrame:_frame]; 
    [v1 setBackgroundColor:[UIColor yellowColor]]; 
    [self addHeaderView:v1]; 
}