我们可以在UIPageViewController中自定义页面指示器吗?

时间:2013-07-04 09:29:14

标签: ios objective-c uipageviewcontroller

现在是黑色背景的白点。如果我希望它是带有白色背景的黑点呢?

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0)
{
    return _imageArrays.count;
}// The number of items reflected in the page indicator.
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0)
{
    return self.intCurrentIndex;
}// The selected item reflected in the page indicator.

11 个答案:

答案 0 :(得分:129)

您可以使用UIAppearance更改UIPageControl的颜色。请在AppDelegate的didFinishLaunchingWithOptions函数中尝试此操作。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIPageControl *pageControl = [UIPageControl appearance];
    pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
    pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
    pageControl.backgroundColor = [UIColor blueColor];

    return YES;
}

编辑:

要仅将样式应用于特定视图控制器,请改为使用appearanceWhenContainedIn,如下所示:

UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];

现在,只有UIPageControl中包含的MyViewController个对象才能适应这种风格。

感谢Mike& Shingoo!

修改 如果您在屏幕底部看到UIPageControl周围的黑色背景,则归因于UIPageViewController而非UIPageControl的背景颜色。您可以按以下方式更改此颜色:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blueColor]; //Set it to whatever you like
}

答案 1 :(得分:33)

我不相信你可以操纵UIPageViewController的页面控件。我的解决方案:

我有一个“root”UIViewController,它是UIPageViewControllerDelegate和UIPageViewControllerDataSource。

在这个根视图控制器上,我有@property (strong, nonatomic) IBOutlet UIPageControl *pageControl。在相应的storyboard笔尖中,我添加一个UIPageControl,定位它,并选中“Hides for Single Page”。如果我愿意,我也可以改变颜色。

然后,我在根视图控制器的viewDidLoad中添加以下内容:self.pageControl.numberOfPages = [self.features count]

我的根视图控制器也有@property (strong, nonatomic) UIPageViewController *pageViewController。并在实施中:

self.pageViewController = [[UIPageViewController alloc]
          initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll 
            navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal 
                          options:nil];


self.pageViewController.delegate = self;
DataViewController *startingViewController = [self viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = @[startingViewController];
[self.pageViewController setViewControllers:viewControllers
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:NO
                                 completion:NULL];
self.pageViewController.dataSource = self;      
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
self.pageViewController.view.frame = CGRectMake(0.0, 0.0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height + 10.0);
[self.pageViewController didMoveToParentViewController:self];
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;

(侧面注意:设置框架的那条线使得UIPageViewController视图的高度超过了屏幕大小,因此本机页面控件不再可见。我的应用程序仅限肖像,仅限iPhone,所以我稍微离开了这里很简单。如果你需要处理旋转,你必须找到一种方法来保持屏幕外的本机页面控制。我尝试使用自动布局,但是UIPageViewController创建了一组魔术视图,它们具有一堆自动布局掩码约束我找不到覆盖的方法。)

无论如何...然后我添加了一个额外的UIPageViewController委托方法来将我的新的非本地UIPageControl更改为当前选择的页面:

- (void)pageViewController:(UIPageViewController *)viewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
  if (!completed){return;}

  // Find index of current page
  DataViewController *currentViewController = (DataViewController *)[self.pageViewController.viewControllers lastObject];
  NSUInteger indexOfCurrentPage = [self indexOfViewController:currentViewController];
  self.pageControl.currentPage = indexOfCurrentPage;
}

并不像我想的那样漂亮,但Apple的这个类的API并不完全适合优雅。

答案 2 :(得分:6)

您实际上可以抓住它并将其存储在您自己的属性中的一个委托调用中。

将此代码放入您的委托中以访问UIPageViewController中的UIPageControl:

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
    [self setupPageControlAppearance];
    return kPageCount;
}

- (void)setupPageControlAppearance
{
    UIPageControl * pageControl = [[self.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(class = %@)", [UIPageControl class]]] lastObject];
    pageControl.pageIndicatorTintColor = [UIColor grayColor];
    pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
}

答案 3 :(得分:4)

您可以在子视图中递归搜索

- (void)findAndConfigurePageControlInView:(UIView *)view
{
    for (UIView *subview in view.subviews) {
        if ([subview isKindOfClass:[UIPageControl class]]) {
            UIPageControl * pageControl = (UIPageControl *)subview;
            //customize here
            pageControl.hidesForSinglePage = YES;
            break;
        } else {
            [self findAndConfigurePageControlInView:subview];
        }
    }
}

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
    [self findAndConfigurePageControlInView:self.view];
    return self.promotionsVCs.count;
}

它对我有用

答案 4 :(得分:2)

UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];
pageControl.backgroundColor = [UIColor blackColor];

这将改变“MyViewController”的外观。如果您想在同一视图中的不同页面指示器中使用不同的颜色,则必须创建不同的子视图并单独进行自定义。

答案 5 :(得分:1)

如果您使用UIPageViewController创建的“自动生成”页面指示器,我认为您无法自定义它。你能做到的唯一方法就是添加一个额外的PageControl,可以是Apple提供的,也可以是@Maschel提出的自定义PageControl。

答案 6 :(得分:1)

可以通过外观进行自定义。你可以在AppDelegate中这样做。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   UIPageControl *pageControl = [UIPageControl appearance];
   pageControl.pageIndicatorTintColor = [UIColor whiteColor];
   pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
   pageControl.backgroundColor = [UIColor lightGrayColor];

   return YES;
}

如果您只想为某个视图控制器执行此操作,请将pageControl替换为此。

UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];

答案 7 :(得分:1)

这个完美适用于自定义图像

self.pageControl.pageIndicatorTintColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"page_indicater"]];

self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"page_indicater_selection"]];

答案 8 :(得分:1)

这是我在Swift 4中所做的。我在viewDidLoad中首先尝试了类似的答案,但这最终起作用了。这个片段用于回答类似的SO问题。

    override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    for view in self.view.subviews{
        if view is UIPageControl{
            (view as! UIPageControl).currentPageIndicatorTintColor = .yellow
            }
        }
    }

在此块中拥有UIPageControl后,您应该能够自定义其指示器颜色

答案 9 :(得分:0)

您可以使用SMPageControl:Github。它的工作方式与UIPageControl类似,但具有更多自定义功能。

答案 10 :(得分:0)

通过定义这样的计算属性,您可以轻松访问UIPageViewController的{​​{1}}:

pageControl

然后自定义它以适应您的需求,如下所示:

var pageControl: UIPageControl? {
    for subview in view.subviews {
        if let pageControl = subview as? UIPageControl {
            return pageControl
        }
    }
    return nil
}

一个明显的警告:如果Apple决定更改override func viewDidLoad() { super.viewDidLoad() pageControl?.backgroundColor = .white pageControl?.pageIndicatorTintColor = .red pageControl?.currentPageIndicatorTintColor = .blue } 视图层次结构,它将停止工作。