Dans ma classe UIPageViewController
personnalisée:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.model = [[BSTCMWelcomingPageViewModel alloc] init];
self.dataSource = self.model;
self.delegate = self;
self.pageControl = [UIPageControl appearance];
self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
self.pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
}
return self;
}
Ensuite, je configure par programmation la ViewController
courante lorsqu'un bouton est enfoncé:
- (void)scrollToNext
{
UIViewController *current = self.viewControllers[0];
NSInteger currentIndex = [self.model indexForViewController:current];
UIViewController *nextController = [self.model viewControllerForIndex:++currentIndex];
if (nextController) {
NSArray *viewControllers = @[nextController];
// This changes the View Controller, but PageControl doesn't update
[self setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
//Nothing happens!
[self.pageControl setCurrentPage:currentIndex];
//Error: _installAppearanceSwizzlesForSetter: Not a setter!
[self.pageControl updateCurrentPageDisplay];
}
}
Si je ne peux pas faire cela avec la UIPageControl
qui "appartient" à ma UIPageViewController
, je vais simplement essayer de créer le mien. Mais ce serait bien si cela était possible tho!
pour mettre à jour votre indicateur UIPageControl, vous devez implémenter une méthode de source de données de UIPageViewController (la méthode UIPageViewControllerDataSource):
-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
Cette méthode est responsable de la mise à jour de l'indicateur de contrôle de page (lorsque vous utilisez UIPageViewController). Il vous suffit de renvoyer la valeur de la page en cours dans cette méthode. La méthode est appelée par défaut lorsque vous utilisez/appelez setViewControllers sur votre UIPageViewController personnalisé.
Ainsi, le morceau de code que vous devez écrire est le suivant:
- (void)scrollToNext
{
UIViewController *current = self.viewControllers[0];
NSInteger currentIndex = [self.model indexForViewController:current];
UIViewController *nextController = [self.model viewControllerForIndex:++currentIndex];
if (nextController) {
NSArray *viewControllers = @[nextController];
// This changes the View Controller and calls the presentationIndexForPageViewController datasource method
[self setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return currentIndex;
}
J'espère que ceci résoudra votre problème. :)
Comme mentionné dans la réponse acceptée, vous devez implémenter
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
Mais pour moi, il suffisait de l'utiliser comme ceci:
Objectif c:
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return [self.controllers indexOfObject:[pageViewController.viewControllers firstObject]];
}
Swift 3+:
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
guard let index = viewControllers?.index(of: (pageViewController.viewControllers?.first)!) else { return 0 }
return index
}
Sans la nécessité de se souvenir de l'index actuel. Où self.controllers
est une NSArray
de UIViewControllers
affichée dans une UIPageViewController
donnée. Je ne sais pas exactement comment fonctionne votre BSTCMWelcomingPageViewModel
, mais il devrait être facile de l'ajuster.
J'ai eu ce problème sous Xamarin, voici ma version de la solution de @ micromanc3r:
public class PageViewControllerDataSource : UIPageViewControllerDataSource
{
UIViewController[] pages;
public PageViewControllerDataSource(UIViewController[] pages)
{
this.pages = pages;
}
...
public override nint GetPresentationIndex(UIPageViewController pageViewController)
{
return Array.IndexOf(pages, pageViewController.ViewControllers[0]);
}
}
// ViewController.h File
#import <UIKit/UIKit.h>
#import "PageContentViewController.h"
@interface ViewScreen : UIViewController<UIPageViewControllerDataSource,UIPageViewControllerDelegate>
- (IBAction)Startwalkthrough:(id)sender;
@property(strong, nonatomic)UIPageViewController *pageViewController;
@property(strong, nonatomic)NSArray * pageTitles;
@property(strong,nonatomic)NSArray * pageImages;
@end
// ViewController.m File
#import "ViewScreen.h"
@interface ViewScreen ()
@end
@implementation ViewScreen
@synthesize pageTitles,pageImages;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
pageTitles =@[@"dianna",@"images",@"image",@"i1",@"hulk1",@"assasins"];
pageImages =@[@"dianna",@"images",@"image",@"i1",@"hulk1",@"assasins"];
self.pageViewController =[self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
self.pageViewController.dataSource=self;
PageContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray * viewController =@[startingViewController];
[self.pageViewController setViewControllers:viewController direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:_pageViewController];
[self.view addSubview:_pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
}
-(IBAction)Startwalkthrough:(id)sender
{
PageContentViewController * startingViewController =[self viewControllerAtIndex:0];
NSArray * viewControllers =@[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
}
- (PageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.pageTitles count] == 0) || (index >= [self.pageTitles count])) {
return nil;
}
// Create a new view controller and pass suitable data.
PageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageContentViewController"];
pageContentViewController.imageFile = self.pageImages[index];
pageContentViewController.titletext = self.pageTitles[index];
pageContentViewController.pageIndex = index;
return pageContentViewController;
}
#pragma mark - Page View Controller Data Source
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index =((PageContentViewController *) viewController).pageIndex;
if (index == NSNotFound) {
return nil;
}
index--;
if (index ==[self.pageTitles count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = ((PageContentViewController*) viewController).pageIndex;
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.pageTitles count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
return [self.pageTitles count];
}
-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
@end
// Second File
PageViewController.h File
#import <UIKit/UIKit.h>
@interface PageContentViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *txtLabel;
@property (strong, nonatomic) IBOutlet UIImageView *backgroundImageView;
@property NSUInteger pageIndex;
@property NSString *titletext;
@property NSString * imageFile;
@end
// SecondFile.M File
#import "PageContentViewController.h"
@interface PageContentViewController ()
@end
@implementation PageContentViewController
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self =[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.backgroundImageView.image =[UIImage imageNamed:self.imageFile];
self.txtLabel.text =self.titletext;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
Assurez-vous de définir le currentIndex AVANT d'appeler setViewControllers
Un indicateur de page sera visible si les deux méthodes sont implémentées, le style de transition est UIPageViewControllerTransitionStyleScroll
et l'orientation de navigation est UIPageViewControllerNavigationOrientationHorizontal
. Les deux méthodes sont appelées en réponse à un appel setViewControllers:...
, mais l'index de présentation est mis à jour automatiquement dans le cas d'une navigation par gestes.
(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
: nombre d'éléments reflétés dans l'indicateur de page.
(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
: L'élément sélectionné reflété dans l'indicateur de page.
La réponse ci-dessus, donnée par aansul, fonctionne.
Remarque: N'oubliez pas de définir le style de transition de pageViewController sur Scroll au lieu de Page Curl. Sinon, ça ne marchera pas.
Swift 4.2
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
guard let currentController = pageViewController.viewControllers?.first else {
return 0 }
guard let index = viewControllerList.index(of: currentController) else { return 0 }
return index
}