繁体   English   中英

以编程方式更改UIPageViewController的页面不会更新UIPageControl

[英]Changing UIPageViewController's page programmatically doesn't update the 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

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

如果我不能做到这一点与UIPageControl是“属于”我的UIPageViewController我只是尽量让我自己。 但如果这是可能的话会很好!

要更新您的UIPageControl指标,您需要实现UIPageViewController的一个数据源方法(UIPageViewControllerDataSource方法):

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController

此方法负责更新页面控件指示符(当您使用UIPageViewController时)。 您只需要在此方法中返回当前页面值。 当您在自定义UIPageViewController上使用/调用setViewControllers时,默认情况下会调用Method。

所以你需要编写的代码块是:

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

但对我来说,使用它就足够了:

Objective-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
}

无需记住当前索引。 其中self.controllers是在给定的UIPageViewController显示的UIViewControllersNSArray 我不确定你的BSTCMWelcomingPageViewModel是如何工作的,但它应该很容易调整。

Xamarin / C#解决方案

我在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]);
    }
}

如果两种方法都已实现,则页面指示器将可见,过渡样式为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

确保在调用setViewControllers之前设置currentIndex

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM