web-dev-qa-db-fra.com

Pouvons-nous personnaliser l'indicateur de page dans UIPageViewController?

Maintenant, ce sont des points blancs avec un fond noir. Et si je veux que ce soit des points noirs avec un fond blanc?

- (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.
43
Septiadi Agus

Je ne crois pas que vous puissiez manipuler le contrôle de page UIPageViewController. Ma solution:

J'ai un UIViewController "racine" qui est UIPageViewControllerDelegate et UIPageViewControllerDataSource.

Sur ce contrôleur de vue racine, j'ai @property (strong, nonatomic) IBOutlet UIPageControl *pageControl. Dans la plume de storyboard correspondante, j'ajoute un UIPageControl, le positionne et vérifie "Masque pour une seule page". Je peux également changer les couleurs, si je le souhaite.

Ensuite, j'ajoute ce qui suit dans le viewDidLoad du contrôleur de vue racine: self.pageControl.numberOfPages = [self.features count]

Mon contrôleur de vue racine a également @property (strong, nonatomic) UIPageViewController *pageViewController. Et dans la mise en œuvre:

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;

(NOTE LATÉRALE: Cette ligne qui définit le cadre fait que la hauteur de la vue de UIPageViewController dépasse la taille de l'écran afin que le contrôle de page natif ne soit plus visible. Mon application est uniquement en mode portrait, iPhone uniquement, donc je suis descendu un peu facile ici. Si vous devez gérer les rotations, vous devrez trouver un moyen de garder ce contrôle de page natif hors écran. J'ai essayé d'utiliser la mise en page automatique, mais UIPageViewController crée un ensemble de vues magiques qui ont un tas de contraintes de masque de mise en page automatique que je ne pouvais pas trouver un moyen de contourner.)

Quoi qu'il en soit ... alors j'ajoute une méthode de délégué UIPageViewController supplémentaire pour changer mon nouveau UIPageControl non natif à la page actuellement sélectionnée:

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

Pas aussi joli que je le souhaiterais, mais l'API d'Apple pour cette classe ne se prête pas exactement à l'élégance.

33
sirvine

Vous pouvez utiliser UIAppearance pour changer la couleur de UIPageControl. Essayez ceci dans la fonction didFinishLaunchingWithOptions de votre AppDelegate.

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

MODIFIER:

Pour appliquer le style uniquement à un contrôleur de vue particulier, utilisez à la place appearanceWhenContainedIn, comme suit:

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

Désormais, seuls les objets UIPageControl contenus dans le MyViewController vont adapter ce style.

Merci Mike et Shingoo!

EDIT: Si vous voyez un fond noir autour de UIPageControl en bas de votre écran, c'est à cause de la couleur d'arrière-plan de votre UIPageViewController pas UIPageControl . Vous pouvez changer cette couleur comme suit:

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

Vous pouvez réellement le récupérer et le stocker localement dans votre propre propriété dans l'un des appels de délégué.

Mettez ce code à l'intérieur de votre délégué pour accéder à l'UIPageControl à l'intérieur de l'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];
}
6
Yariv Nissim

Vous pouvez le rechercher récursivement dans vos sous-vues

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

ça marche pour moi

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

Cela changera l'apparence juste pour "MyViewController". Si vous souhaitez avoir différentes couleurs dans différents indicateurs de page sur la même vue, vous devez créer différentes sous-vues et les personnaliser individuellement.

2
Shingoo

Voici ce que j'ai fait en Swift 4. J'ai essayé des réponses similaires en premier, dans viewDidLoad, mais c'est ce qui a finalement fonctionné. Ce même extrait de code a été utilisé pour répondre à des SO questions.

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

Une fois que vous avez l'UIPageControl dans ce bloc, vous devriez pouvoir personnaliser ses couleurs d'indicateur

1
wsgeorge

Il est possible de le personnaliser par l'apparence. Vous pouvez le faire dans AppDelegate comme ceci.

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

Si vous voulez le faire uniquement pour un certain contrôleur de vue, remplacez plutôt la pageControl par ceci.

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

Celui-ci fonctionne parfaitement pour une image personnalisée

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

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

Si vous utilisez l'indicateur de page "généré automatiquement" créé par UIPageViewController, je pense que vous ne pouvez pas le personnaliser. La seule façon de le faire est d'ajouter un PageControl supplémentaire, soit celui fourni par Apple ou un personnalisé comme l'a proposé @Maschel.

1
Heckscheibe

Vous pouvez facilement accéder aux UIPageViewController des pageControl en définissant une propriété calculée comme ceci:

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

Et puis personnalisez-le pour répondre à vos besoins comme ceci:

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

Mise en garde évidente: si Apple décide jamais de changer la hiérarchie de vue UIPageViewController cela cessera de fonctionner.

0
boliva

Vous pouvez utiliser SMPageControl: Github . Il fonctionne exactement comme UIPageControl mais avec plus de possibilités de personnalisation.

0
Maschel