以编程方式更改UIPageViewController的页面不会更新UIPageControl
在我的自定义UIPageViewController
类中:
- (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; }
然后我编程设置当前的ViewController
当一个button被击中:
- (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]; } }
如果我不能用属于我的UIPageViewController
的UIPageControl
来做到这一点,我只会尝试做我自己的。 但如果这是可能的,这将是很好的!
要更新您的UIPageControl指标,您需要实现UIPageViewController(UIPageViewControllerDataSource方法)的一个数据源方法:
-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
这个方法负责更新页面控制指示器(当你使用UIPageViewController的时候)。 您只需要返回此方法中的当前页面值。 当您在自定义UIPageViewController上使用/调用setViewControllers时,方法会被默认调用。
所以你需要编写的代码块是:
- (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; }
希望这可以解决你的问题。 🙂
正如接受的答案中所提到的,您需要执行
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
但是对我来说,就像这样使用它就足够了:
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController { // The selected item reflected in the page indicator. return [self.controllers indexOfObject:[pageViewController.viewControllers firstObject]]; }
不需要记住当前的索引。 self.controllers
是在给定的UIPageViewController
显示的UIViewControllers
的NSArray
。 我不确定您的BSTCMWelcomingPageViewModel
是如何工作的,但它应该很容易调整。
如果两个方法都实现,则页面指示符将可见,过渡样式为UIPageViewControllerTransitionStyleScroll
,导航方向为UIPageViewControllerNavigationOrientationHorizontal
。 这两种方法都是为了响应setViewControllers:...
调用而调用的,但是在手势驱动导航的情况下,演示索引会自动更新。
-
(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
:页面指示符中反映的项目数量。 -
(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
:所选项目反映在页面指示器中。
上面的答案是由aansul给出的。
注意:不要忘记将pageViewController的Transition样式设置为Scroll而不是Page Curl。 否则,它将无法正常工作。
// 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
Xamarin / C#解决scheme
我在Xamarin中遇到了这个问题,这里是我的@micromanc3r解决scheme的版本:
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]); } }
确保在调用setViewControllers之前设置currentIndex