我一直在寻找到使用UIPageControl为应用程序的一部分滚动,我想知道它是如何工作的。 该文档显示更改的页面,设置页面数等方法,但其本身的页面控制不包括任何种类的滚动视图。
应该在UIPageControl和UIScrollView的类来配合使用时,一个想要显示的页面指示符(像iPhone的主屏幕,应用程序的页面上)?
我一直在寻找到使用UIPageControl为应用程序的一部分滚动,我想知道它是如何工作的。 该文档显示更改的页面,设置页面数等方法,但其本身的页面控制不包括任何种类的滚动视图。
应该在UIPageControl和UIScrollView的类来配合使用时,一个想要显示的页面指示符(像iPhone的主屏幕,应用程序的页面上)?
分页位实际上是由设置在UIScrollView的分页属性来完成。 页面控件只是一个有用的UI概念,但是实际上并没有做任何与分页本身。
我写了一个类(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
UIPageControl做两两件事:(1)它显示点,包括当前所选页面高亮显示的点,和(2)它当用户轻敲上它产生一个UIControlEventValueChanged事件。 轻按控制向右侧页面的右侧; 点击左侧页面左侧。 你应该实现这一行为是与HIG一致!
要捕获的事件中,添加:
[myUiPageControl addTarget:self action:@selector(pageChanged:) forControlEvents:UIControlEventValueChanged];
和委托功能,以及:
-(void)pageChanged:(UIPageControl*)thePageControl;
该名称可以是任何你想要的; 我用“pageChanged”为例。 回调签名可以pageChanged,pageChanged :,或pageChanged:forEvent :. 这个回调函数应当引起你的滚动视图(或你有什么)来更新。
分页本身,通常是通过使用分页启用和滚动条隐藏一个UIScrollView完成。 告诉使用寻呼和笔触奇迹般地页面移动页面滚动视图; 确保你陷阱,改变更新UIPageControl的当前页属性。
你是正确的 - UIPageControl本身并不比在页面底部的点其他画任何东西; 你需要另一种观点认为这样做。
要使用沃纳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];
}