如何将UIPageControl作为 UIViewController的容器

UIPageControl控件
当用户界面需要按页面进行显示时,使用iOS提供的UIPageControl控件将要显示的用户界面内容分页进行显示会使工作变得非常快捷,如图3-47所示就是一个使用UIPageControl控件逐页进行图片显示的程序,用户按下屏幕即可进行左右滚动显示,在屏幕的正上方使用白色的点显示当前滚动到的页面位置。
程序自定义一个SwipeView类,该类通过子类化UIView类并重载其touchesMoved()方法捕获用户滚动的方向,类的定义如下。
//& SwipeView.h
#import &UIKit/UIKit.h&
#import &QuartzCore/QuartzCore.h&
@interface SwipeView : UIView {
&CGPoint startTouchP
&NSString *dirS
&UIViewController *
- (void) setHost: (UIViewController *) aH
//& SwipeView.m
- (id)initWithFrame.:(CGRect)frame. {
&&& if ((self =
[super initWithFrame.:frame])) {
// Initialization code
&&& return
- (void) setHost: (UIViewController *) aHost
&host = aH
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
&UITouch *touch = [touches anyObject];
&startTouchPosition = [touch
locationInView:self];
&dirString = NULL;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
&UITouch *touch = touches.anyO
&CGPoint currentTouchPosition = [touch
locationInView:self];
#define HORIZ_SWIPE_DRAG_MIN 12
#define VERT_SWIPE_DRAG_MAX 4
&if (fabsf(startTouchPosition.x -
currentTouchPosition.x) &=
&&HORIZ_SWIPE_DRAG_MIN
&&fabsf(startTouchPosition.y -
currentTouchPosition.y) &=
&&VERT_SWIPE_DRAG_MAX)
&&// Horizontal Swipe
&&if (startTouchPosition.x
& currentTouchPosition.x) {
&&&dirString =
kCATransitionFromL
&&&dirString =
kCATransitionFromR
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
&if (dirString) [host swipeTo:dirString];
在 捕获用户滚动的方向后,SwipeView类通过用户设置的host成员变量回调其swipeTo()方法,host成员变量在类中定义为
UIViewController,在编译时编译器会产生警告,这里不用管它,只需要SwipeView类的使用者设置host成员变量并实现
swipeTo()方法即可。
SwipeView类的使用者为PageViewController类,该类实现程序的主界面,在这个自定义的UIViewController类中实现swipeTo()方法,代码如下。
//& PageViewController.m
- (void) swipeTo: (NSString *) aDirection{
&UIPageControl *pageControl = [[[contentView
superview] subviews] lastObject];
&if ([aDirection
isEqualToString:kCATransitionFromRight])
&&if (currentPage == 5)
&&[pageControl
setCurrentPage:currentPage + 1];
&&if (currentPage == 0)
&&[pageControl
setCurrentPage:currentPage - 1];
&[self pageTurn:pageControl];
该回调方法中根据用户滚动的方向来设置UIPageControl的currentPage属性,如果是向右方滚动则页面计数加一,如果用户滚动的方向是
向左,则页面计数减一。设置UIPageControl的currentPage属性以后,PageViewController对象再调用其
pageTurn()方法交换页面显示内容,并将图片显示出来,代码如下。
- (void) pageTurn: (UIPageControl *) pageControl{
&CATransition *
&int secondPage = [pageControl currentPage];
&if ((secondPage - currentPage) &
&&transition = [self
getAnimation:@"fromRight"];
&&transition = [self
getAnimation:@"fromLeft"];
&UIImageView *newView = (UIImageView
*)[[contentView subviews] objectAtIndex:0];
&[newView setImage:[UIImage imageNamed:[NSString
stringWithFormat:@"ipad_ wallpaperd.jpg", secondPage + 1]]];
&[contentView exchangeSubviewAtIndex:0
withSubviewAtIndex:1];
&[[contentView layer] addAnimation:transition
forKey:@"transitionView Animation"];
&currentPage = [pageControl currentPage];
在主pageTurn()方法实现中,PageViewController类通过UIView的exchangeSubview
AtIndex()方法实现页面内容的切换。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。主题 : 【求助】关于UIPageControl中如何加载collectionView子页面
级别: 侠客
UID: 226149
可可豆: 315 CB
威望: 271 点
在线时间: 177(时)
发自: Web Page
来源于&&分类
【求助】关于UIPageControl中如何加载collectionView子页面&&&
一个UIPageControl例子,ViewController中有UIScrollView、UIPageControl实现连续几张图片页面翻动。想加在UIPageControl连接的page1,page2页面中加一个子view(集合视图CollectionView)page1,page2作为了ViewController的成员变量了,不知道这时该如何加载collectionView的数据了;比如实现以下函数等:- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath于是,定义了一个viewController,继承自UICollectionViewController,想处理这个情况@interfaceJHPageViewController : UICollectionViewController但是,这个如何跟page1,page2联系起来呢,仅仅从storyboard上修改page1,page2的viewController行不通额。。。 [upload=1] 代码如下:&pre class=\\\\\\\\\\\\\\\&brush: toolbar: auto-links:\\\\\\\\\\\\\\\&&// .h ================================================#import &UIKit/UIKit.h&@interface ViewController : UIViewController &UIScrollViewDelegate&@property (strong, nonatomic) UIView *page1;@property (strong, nonatomic) UIView *page2;@property (weak, nonatomic) IBOutlet UIScrollView *scrollV@property (weak, nonatomic) IBOutlet UIPageControl *pageC- (IBAction)changePage:(id)@end// .m ================================================#import \\\&ViewController.h\\\&@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{&&&&[super viewDidLoad];&&&&// Do any additional setup after loading the view, typically from a nib.&&&&&&&&self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height);&&&&self.scrollView.frame = self.view.&&&&&&&&UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@\\\&Main\\\& bundle:nil];&&&&UIViewController *page1ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@\\\&page1\\\&];&&&&self.page1 = page1ViewController.&&&&self.page1.frame = CGRectMake(0.0f, 0.0f, 320.0f, 420.0f);&&&&&&&&UIViewController *page2ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@\\\&page2\\\&];&&&&self.page2 = page2ViewController.&&&&self.page2.frame = CGRectMake(320.0f, 0.0f, 320.0f, 420.0f);&&&&&&&&&&&&self.scrollView.delegate =&&&&&&&&[self.scrollView addSubview:self.page1];&&&&[self.scrollView addSubview:self.page2];}- (void)didReceiveMemoryWarning{&&&&[super didReceiveMemoryWarning];&&&&// Dispose of any resources that can be recreated.}- (void)scrollViewDidScroll:(UIScrollView *)aScrollView{&&&&CGPoint offset = aScrollView.contentO&&&&self.pageControl.currentPage = offset.x / 320.0f;}- (IBAction)changePage:(id)sender{&&&&[UIView animateWithDuration:0.3f animations:^{&&&&&&&&int whichPage = self.pageControl.currentP&&&&&&&&self.scrollView.contentOffset = CGPointMake(320.0f * whichPage, 0.0f);&&&&}];}@end&/pre&请大家指导一下啊~  谢谢了~[ 此帖被mifeione在 23:09重新编辑 ]
级别: 侠客
UID: 226149
可可豆: 315 CB
威望: 271 点
在线时间: 177(时)
发自: Web Page
怎么传不了图片。。。代码也没格式呢。。。
图片:pageControl页面中的collectionView子页面.png
级别: 新手上路
UID: 283836
可可豆: 447 CB
威望: 226 点
在线时间: 61(时)
发自: Web Page
级别: 侠客
UID: 226149
可可豆: 315 CB
威望: 271 点
在线时间: 177(时)
发自: Web Page
盼大侠指点一下啊~~~&&谢谢了哈
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版如何将UIPageControl作为 UIViewController的容器 - 技术翻译 - 开源中国社区
如何将UIPageControl作为 UIViewController的容器
【已翻译100%】
英文原文:
推荐于 4年前 (共 6 段, 翻译完成于 11-27)
参与翻译&(1人)&:
虽然看上去用 UIPageControl 在一系列 UIView或UIViewController中导航是很平常的事情,但实际上Apple公司并没有提供一个这样的方法或者演示Demo:
在最新的iOS版本中(5.0 现在已经不是最新的),Apple公司提供了很多如何用其他方式实现
UIViewController容器的方式(可以从这里参考),但悲剧的是它们与 UIPageControl 没多大关系。
那么我们今天就来专门解决这个问题。
&翻译得不错哦!
首先我们需要在 Interface Builder 中在一个UIViewController里面创建一个UIPageControl与UIScrollView。当然你可以创建很多类似的UIViewController。
&翻译得不错哦!
设置 PageViewController 类
这里的 PageViewController 对象将包含一个 UIScrollView 与一个 UIPageControl。而且 UIScrollView 将会包含所有的 subview, 这些subview就是被UIPageControl控制的子页面。
你也许会在 viewController 中添加一些算法来专门处理页面转换: addChildViewController:方法。然而在我这个案例中却不是这么做的,来一起看看代码:
@interface PagerViewController : UIViewController
@property (nonatomic, strong) IBOutlet UIScrollView *scrollV
@property (nonatomic, strong) IBOutlet UIPageControl *pageC
- (IBAction)changePage:(id)
在实现的代码文件中,首先我先不让它能够旋转屏幕。然后 当 PagerViewController 预备显示时,我们需要标记一下当前哪一个view是被激活的,即被显示的,那么需要在 viewDidApplear 以及 viewWillDisappear方法中加入以下代码:
- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
return NO;
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
if (viewController.view.superview != nil) {
[viewController viewDidAppear:animated];
- (void)viewWillDisappear:(BOOL)animated {
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
if (viewController.view.superview != nil) {
[viewController viewWillDisappear:animated];
[super viewWillDisappear:animated];
- (void)viewDidDisappear:(BOOL)animated {
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
if (viewController.view.superview != nil) {
[viewController viewDidDisappear:animated];
[super viewDidDisappear:animated];
viewWillAppear 可能会有点复杂,因为我们也需要加载所有的子view到 scrollView中,而且必须确保scrollview的contentsize比子view要大。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
for (NSUInteger i =0; i & [self.childViewControllers count]; i++) {
[self loadScrollViewWithPage:i];
self.pageControl.currentPage = 0;
_page = 0;
[self.pageControl setNumberOfPages:[self.childViewControllers count]];
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
if (viewController.view.superview != nil) {
[viewController viewWillAppear:animated];
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [self.childViewControllers count], scrollView.frame.size.height);
为了将UIViewController的内容加载到UIScrolView的contentView中,需要如下代码:
- (void)loadScrollViewWithPage:(int)page {
if (page & 0)
if (page &= [self.childViewControllers count])
// replace the placeholder if necessary
UIViewController *controller = [self.childViewControllers objectAtIndex:page];
if (controller == nil) {
// add the controller's view to the scroll view
if (controller.view.superview == nil) {
CGRect frame = self.scrollView.
frame.origin.x = frame.size.width *
frame.origin.y = 0;
controller.view.frame =
[self.scrollView addSubview:controller.view];
&翻译得不错哦!
为了处理滚动,我们需要实现几个 UIScrollViewDelegate 的方法以及尽早声明方法 - (IBAction)changePage:(id)sender
首先必须先知道滚动是如何实现的,要么是手势,要么就是点击了 UIPageControl 的一侧。
来一起看看下面的代码:
// 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;
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page];
UIViewController *newViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
[oldViewController viewDidDisappear:YES];
[newViewController viewDidAppear:YES];
_page = self.pageControl.currentP
现在,为了当页面改变时也能更新当前的显示,我们只需要实现 scrollViewDidScroll delegate方法以及 changePage IBAction 方法。
- (IBAction)changePage:(id)sender {
int page = ((UIPageControl *)sender).currentP
// update the scroll view to the appropriate page
CGRect frame = self.scrollView.
frame.origin.x = frame.size.width *
frame.origin.y = 0;
UIViewController *oldViewController = [self.childViewControllers objectAtIndex:_page];
UIViewController *newViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
[oldViewController viewWillDisappear:YES];
[newViewController viewWillAppear:YES];
[self.scrollView scrollRectToVisible:frame animated:YES];
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
_pageControlUsed = YES;
- (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 || _rotating) {
// do nothing - the scroll was initiated from the page control, not the user dragging
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = self.scrollView.frame.size.
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
if (self.pageControl.currentPage != page) {
UIViewController *oldViewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
UIViewController *newViewController = [self.childViewControllers objectAtIndex:page];
[oldViewController viewWillDisappear:YES];
[newViewController viewWillAppear:YES];
self.pageControl.currentPage =
[oldViewController viewDidDisappear:YES];
[newViewController viewDidAppear:YES];
&翻译得不错哦!
最后处理旋转
首先在shouldAutorotateToInterfaceOrientation方法中返回 YES,同时也需要传输一下3个消息给当前被显示的子 UIViewController。
willAnimateRotationToInterfaceOrientation:duration:
willRotateToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:
但我们还是要自己处理旋转的问题,比如要重新缩放scrollview的contentView,以及调整子view的帧率,否则会出现一些无法预料的事情。所以来看看以下处理方式
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
return YES;
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
[viewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
_rotating = YES;
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
[viewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * [self.childViewControllers count], scrollView.frame.size.height);
NSUInteger page = 0;
for (viewController in self.childViewControllers) {
CGRect frame = self.scrollView.
frame.origin.x = frame.size.width *
frame.origin.y = 0;
viewController.view.frame =
CGRect frame = self.scrollView.
frame.origin.x = frame.size.width * _
frame.origin.y = 0;
[self.scrollView scrollRectToVisible:frame animated:NO];
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
_rotating = NO;
UIViewController *viewController = [self.childViewControllers objectAtIndex:self.pageControl.currentPage];
[viewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
&翻译得不错哦!
废话少说,这里放出代码,在
&翻译得不错哦!
我们的翻译工作遵照 ,如果我们的工作有侵犯到您的权益,请及时联系我们
暂无网友评论

我要回帖

 

随机推荐