是UIPageControl无用本身?(Is UIPageControl Useless By It

2019-06-25 12:37发布

我一直在寻找到使用UIPageControl为应用程序的一部分滚动,我想知道它是如何工作的。 该文档显示更改的页面,设置页面数等方法,但其本身的页面控制不包括任何种类的滚动视图。

应该在UIPageControl和UIScrollView的类来配合使用时,一个想要显示的页面指示符(像iPhone的主屏幕,应用程序的页面上)?

Answer 1:

分页位实际上是由设置在UIScrollView的分页属性来完成。 页面控件只是一个有用的UI概念,但是实际上并没有做任何与分页本身。



Answer 2:

我写了一个类(PagedView),它的工作原理就像的UITableView并合并UIPageControl和的UIScrollView的概念用于例如在iPhone主屏幕上的方式。

这个概念基本上是如下:你需要实现PagedViewDelegate返回的页数和你们每个页面PagedView视图。 意见重用工作原理相同的UITableView。 使用Interface Builder来连接滚动视图和的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


Answer 3:

UIPageControl做两两件事:(1)它显示点,包括当前所选页面高亮显示的点,和(2)它当用户轻敲上它产生一个UIControlEventValueChanged事件。 轻按控制向右侧页面的右侧; 点击左侧页面左侧。 你应该实现这一行为是与HIG一致!

要捕获的事件中,添加:

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

和委托功能,以及:

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

该名称可以是任何你想要的; 我用“pageChanged”为例。 回调签名可以pageChanged,pageChanged :,或pageChanged:forEvent :. 这个回调函数应当引起你的滚动视图(或你有什么)来更新。

分页本身,通常是通过使用分页启用和滚动条隐藏一个UIScrollView完成。 告诉使用寻呼和笔触奇迹般地页面移动页面滚动视图; 确保你陷阱,改变更新UIPageControl的当前页属性。



Answer 4:

你是正确的 - UIPageControl本身并不比在页面底部的点其他画任何东西; 你需要另一种观点认为这样做。



Answer 5:

要使用沃纳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];
}


文章来源: Is UIPageControl Useless By Itself?