ios 以编程方式更改 UIPageViewController 的页面不会更新 UIPageControl
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22554877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing UIPageViewController's page programmatically doesn't update the UIPageControl
提问by Johannes
In my custom UIPageViewController
class:
在我的自定义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;
}
Then I programmatically set the current ViewController
when a button is hit:
然后我以编程方式设置ViewController
按下按钮时的电流:
- (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];
}
}
If I can't do this with the UIPageControl
that "belongs" to my UIPageViewController
I will just try to make my own. But it would be nice if this was possible tho!
如果我不能用UIPageControl
“属于”我的东西来做到这一点,UIPageViewController
我将尝试自己制作。但如果这是可能的,那就太好了!
回答by anshul
to update your UIPageControl indicator, you need to implement one data source method of UIPageViewController (the UIPageViewControllerDataSource method) :
要更新 UIPageControl 指示器,您需要实现 UIPageViewController 的一种数据源方法(UIPageViewControllerDataSource 方法):
-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
This method is responsible for updating the page control indicator (when you use UIPageViewController). You only need to return the currentpage value in this method. The Method gets called by default when you use/make a call for setViewControllers on your custom UIPageViewController.
此方法负责更新页面控件指示器(当您使用 UIPageViewController 时)。您只需要在此方法中返回 currentpage 值。当您在自定义 UIPageViewController 上使用/调用 setViewControllers 时,默认情况下会调用该方法。
So the chunk of code that you need to write is:
因此,您需要编写的代码块是:
- (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;
}
Hope this solves your problem. :)
希望这能解决您的问题。:)
回答by micromanc3r
As mentioned in accepted answer, you need to implement
正如接受的答案中所述,您需要实施
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
But for me it was enough to use it like this:
但对我来说,像这样使用它就足够了:
Objective-C:
目标-C:
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return [self.controllers indexOfObject:[pageViewController.viewControllers firstObject]];
}
Swift 3+:
斯威夫特 3+:
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
guard let index = viewControllers?.index(of: (pageViewController.viewControllers?.first)!) else { return 0 }
return index
}
Without the need to remember the current index. Where self.controllers
is an NSArray
of UIViewControllers
displayed in given UIPageViewController
. I'm not sure how exactly your BSTCMWelcomingPageViewModel
works, but it should be easy to adjust.
无需记住当前索引。当self.controllers
被一个NSArray
的UIViewControllers
显示中给出UIPageViewController
。我不确定你的BSTCMWelcomingPageViewModel
工作到底如何,但应该很容易调整。
回答by Mark Moeykens
Xamarin/C# Solution
Xamarin/C# 解决方案
I had this problem in Xamarin, here is my version of @micromanc3r's solution:
我在 Xamarin 中遇到了这个问题,这是我的 @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]);
}
}
回答by apunn
Make sure to set the currentIndex BEFORE you call setViewControllers
确保在调用 setViewControllers 之前设置 currentIndex
回答by Alexander
SWIFT 4.2
斯威夫特 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
}
回答by Hemanshu Liya
A page indicator will be visible if both methods are implemented, transition style is UIPageViewControllerTransitionStyleScroll
and navigation orientation is UIPageViewControllerNavigationOrientationHorizontal
. Both methods are called in response to a setViewControllers:...
call, but the presentation index is updated automatically in the case of gesture-driven navigation.
如果实现了这两种方法,过渡样式为UIPageViewControllerTransitionStyleScroll
且导航方向为,则页面指示器将可见UIPageViewControllerNavigationOrientationHorizontal
。这两种方法都被调用以响应setViewControllers:...
调用,但在手势驱动导航的情况下,演示索引会自动更新。
(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
: The number of items reflected in the page indicator.(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
: The selected item reflected in the page indicator.
(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
:反映在页面指示器中的项目数。(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0);
:所选项目反映在页面指示器中。
The answer above, given by aansul, works.
上面由 aansul 给出的答案有效。
Note : Don't forget to set the pageViewController's Transition style to Scroll instead of Page Curl. Otherwise it won't work.
注意:不要忘记将 pageViewController 的 Transition 样式设置为 Scroll 而不是 Page Curl。否则它不会工作。
回答by Kiran Bhoraniya
// 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