Можем ли мы настроить индикатор страницы в 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 ответов


Я не верю, что вы можете манипулировать элементом управления страницы UIPageViewController. Мое решение:

у меня есть "корневой" UIViewController, который является UIPageViewControllerDelegate и UIPageViewControllerDataSource.

на этом контроллере корневого представления у меня есть @property (strong, nonatomic) IBOutlet UIPageControl *pageControl. В соответствующей раскадровке я добавляю uipagecontrol, размещаю его и проверяю "скрывает для одной страницы". Я также могу изменить цвета, если захочу.

затем я добавляю следующее в 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, поэтому я отделался здесь немного легко. Если вам нужно обрабатывать вращения, вам нужно найти способ сохранить этот собственный элемент управления страницей закадровый. Я попытался использовать auto layout, но 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;
}

не так красиво, как хотелось бы, но API Apple для этого класса точно не поддается элегантности.


можно использовать UIAppearance изменить цвет UIPageControl. Попробуйте это в вашем AppDelegate в


вы можете фактически захватить его и сохранить его локально в своем собственном свойстве в одном из вызовов делегата.

поместите этот код внутри делегата для доступа к UIPageControl внутри UIPageViewController:

- (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];
}

вы можете рекурсивно искать его в подпанели

- (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;
}

это работает для меня


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

это изменит внешний вид только для "MyViewController". Если вы хотите иметь разные цвета в разных индикаторах страниц в одном представлении, вам нужно создать разные подвиды и настроить их индивидуально.


Если вы используете индикатор страницы "auto generated", созданный UIPageViewController, я думаю, что вы не можете его настроить. Единственный способ сделать это-добавить дополнительный PageControl, либо предоставленный Apple, либо пользовательский, как предложил @Maschel.


возможно подгонять его через возникновение. Вы можете сделать это в 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];

этот работает отлично для пользовательского изображения

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

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

вы можете использовать SMPageControl:Github. Он работает так же, как UIPageControl, но с большими возможностями настройки.


вот что я сделал в Swift 4. Сначала я попробовал похожие ответы, в viewDidLoad, но это то, что в конце концов сработало. Этот же фрагмент был использован для ответа на подобные вопросы так.

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

после того, как у вас есть UIPageControl в этом блоке, вы должны иметь возможность настроить его цвета индикатора


вы можете легко получить доступ к UIPageViewController ' s pageControl определив вычисляемое свойство следующим образом:

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

а затем настроить его в соответствии с вашими потребностями, как это:

override func viewDidLoad() {
    super.viewDidLoad()
    pageControl?.backgroundColor = .white
    pageControl?.pageIndicatorTintColor = .red
    pageControl?.currentPageIndicatorTintColor = .blue
}

очевидное предостережение: если Apple когда-либо решит изменить UIPageViewController просмотр иерархии это перестанет работать.