Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8777903
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T19:23:35+00:00 2026-06-13T19:23:35+00:00

I was wondering how can I implement buttons which will affect the UIPageViewController’s model.

  • 0

I was wondering how can I implement buttons which will affect the UIPageViewController’s model. For example I would like my UIPageViewController model array to load with a single object in it and when a button is tapped a new view controller will be added and will flip automatically the page or something like that (like in the Notes app). Same for deleting the current object that the user is seeing.

So far I tried by implementing some IBActions to my root view controller but no luck so far.

Here is how I have implement my ViewController class:

@implementation ViewController

@synthesize modelArray = _modelArray;
@synthesize pageVC = _pageVC;

#pragma mark - UIPageViewControllerDataSource Methods

// Returns the view controller before the given view controller. (required)
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
      viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentVC *)viewController     labelContents]];
    if(currentIndex==0)
        return nil;

    ContentVC *cVC = [[ContentVC alloc] init];
    cVC.labelContents = [self.modelArray objectAtIndex:currentIndex-1];
    return cVC;
}

// Returns the view controller after the given view controller. (required)
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
   viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentVC *)viewController labelContents]];
    if(currentIndex==self.modelArray.count-1)
        return nil;

    ContentVC *cVC = [[ContentVC alloc] init];
    cVC.labelContents = [self.modelArray objectAtIndex:currentIndex+1];
    return cVC;
}

#pragma mark - UIPageViewControllerDelegate Methods
// Returns the spine location for the given orientation.
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
               spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
    if(UIInterfaceOrientationIsPortrait(orientation)){
        // Set the array with only 1 view controller
        UIViewController *currentVC = [self.pageVC.viewControllers objectAtIndex:0];
        NSArray *viewControllers = [NSArray arrayWithObject:currentVC];
        [self.pageVC setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

        // Set the doubleSided property to NO
        self.pageVC.doubleSided = NO;
        // Return the spine location
        return UIPageViewControllerSpineLocationMin;
    } else { // if landscape
        NSArray *viewControllers = nil;
        ContentVC *currentVC = [self.pageVC.viewControllers objectAtIndex:0];
        NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentVC *)viewControllers labelContents]];
        if(currentIndex==0 || currentIndex %2 == 0){
            UIViewController *nextViewController = [self pageViewController:self.pageVC viewControllerAfterViewController:currentVC];
            viewControllers = [NSArray arrayWithObjects:currentVC, nextViewController, nil];
        } else {
            UIViewController *previousVC = [self pageViewController:self.pageVC viewControllerBeforeViewController:currentVC];
            viewControllers = [NSArray arrayWithObjects:previousVC, currentVC, nil];
        }
        // Set the view controllers as property of the UIPageViewController
        [self.pageVC setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
        return UIPageViewControllerSpineLocationMid;
    }

}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Instantiate the model array
    self.modelArray = [[NSMutableArray alloc] init];
    [self.modelArray addObject:@"Page One"];
    NSLog(@"%@", self.modelArray);

    // Instantiate the UIPageViewController
    self.pageVC = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

    // Assign the delegate and datasource as self
    self.pageVC.delegate = self;
    self.pageVC.dataSource = self;

    // Set the initial view controllers
    ContentVC *cVC = [[ContentVC alloc] initWithNibName:@"ContentVC" bundle:nil];
    cVC.labelContents = [self.modelArray objectAtIndex:0];
    NSArray *viewControllers = [NSArray arrayWithObject:cVC];
    [self.pageVC setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

    // Add the pageViewController as the childViewController
    [self addChildViewController:self.pageVC];

    // Add the view of pageViewController  to the currentView
    [self.view addSubview:self.pageVC.view];

    // Call didMoveToParentViewController: of the childViewController, the UIPageViewController instance in our case.
    [self.pageVC didMoveToParentViewController:self];

    // Assign the gestureRecognizers property of the pageViewController to the view's gestureRecognizers property
    self.view.gestureRecognizers = self.pageVC.gestureRecognizers;

}

Thank you very much!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T19:23:36+00:00Added an answer on June 13, 2026 at 7:23 pm

    The UIPageViewController uses a datasource to obtain the next or previous view controller. So the solution is to add your new view controller to the datasource once the button is touched.

    Say your datasource is implemented as an NSArray (see the XCode’s Page-based Application template for an example of this) you just add your new vc to that array and set the new vc by calling [UIPageViewController setViewControllers:direction:animated:completion:].

    Since you didn’t provide any details on how you implemented your hierarchy I can’t be more specific.

    Edit:

    Now that I have some code, here’s what I’d do:

    First I wouldn’t save the labelContents but rather the view controller itself in the modelArray. Besides other things, your current design creates a new ContentVC every time you change pages. That’s a lot of unnecessary overhead. Here’s how I would implement that:

    (btw, you should think of a more descriptive name than labelContents. Right now it might be fine if there’s just one label, but what if you add more labels in the future?)

    - (ContentVC *)contentViewControllerWithLabelContents:(NSString *)labelContents
    {
        ContentVC *vc = [[ContentVC alloc] initWithNibName:@"ContentVC" bundle:nil];
        vc.labelContents = labelContents;
        return vc;
    }
    
    - (void)viewDidLoad
    {
        NSMutableArray *vcs = [NSMutableArray array];
        [vcs addObject:[self contentViewControllerWithLabelContents:@"Page One"]];
        [vcs addObject:[self contentViewControllerWithLabelContents:@"Page Two"]];
        //...
        self.modelArray = vcs;
    }
    
    
    #pragma mark - UIPageViewControllerDataSource Methods
    
    // Returns the view controller before the given view controller. (required)
    - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
          viewControllerBeforeViewController:(UIViewController *)viewController
    {
        NSUInteger currentIndex = [self.modelArray indexOfObject:viewController];
        if(currentIndex == 0)
            return nil;
    
        ContentVC *cVC = [self.modelArray objectAtIndex:currentIndex - 1];
        return cVC;
    }
    
    // Returns the view controller after the given view controller. (required)
    - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
       viewControllerAfterViewController:(UIViewController *)viewController
    {
        NSUInteger currentIndex = [self.modelArray indexOfObject:viewController];
        if(currentIndex == self.modelArray.count - 1)
            return nil;
    
        ContentVC *cVC = [self.modelArray objectAtIndex:currentIndex + 1];
        return cVC;
    }
    

    The code in your comment:

    - (IBAction)newButtonTapped:(id)sender 
    { 
        if(sender){ 
            [self.modelArray addObject:@"Page Two"]; 
            ContentVC *newVC = [[ContentVC alloc] initWithNibName:@"ContentVC" bundle:nil]; 
            NSArray *arr = [NSArray arrayWithObject:newVC]; 
            [self.pageVC setViewControllers:arr direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; 
            NSLog(@"%@", self.modelArray); 
        } 
    }
    

    doesn’t work because you didn’t set the labelContents of the ContentVC. So you basically end up calling [self.modelObject indexOfObject:nil] or [self.modelObject indexOfObject:@""] depending on your implementation of labelContents. Since neither of them is in the array, the call returns NSNotFound which on 64bit systems is translated to NSIntegerMax and that is 2147483647. Later you try to access your modelArray at index NSIntegerMax - 1 and that raises an NSRangeException.

    So can fix that by either setting the labelContents in your newButtonTapped: method or if you follow my suggestion to redesign your code:

    - (IBAction)newButtonTapped:(id)sender 
    { 
        if(sender){ 
            ContentVC *newVC = [self contentViewControllerWithLabelContents:@"Page Two"]; 
            [self.modelArray addObject:newVC];
    
            NSArray *newVCs = nil;
    
            if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation) || self.modelArray.count == 1)
                newVCs = @[newVC];
            else
            {
                NSUInteger secondLastIndex = self.modelArray.count - 2;
                id previousVC = [self.modelArray objectAtIndex:secondLastIndex];
                newVCs = @[previousVC, newVC];
            }
    
            [self.pageVC setViewControllers:newVCs direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
        } 
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm wondering how one would implement an outline view like the one Xcode 3
I'm running the latest WSO2 ESB and I was wondering how can I implement
From this context: import itertools lines = itertools.cycle(open('filename')) I'm wondering how I can implement
I was wondering how can we can use the python module networkX to implement
I was wondering how can I implement a view that allows the user to
I'm looking into Windows Azure now and wondering if one can implement a TCP/IP
I was wondering if anyone knew of some code which implements two buttons where
I m new to Camel and wondering how I can implement below mentioned use
I was wondering how a Garbage Collector can be implemented with C++ full power
I've implemented a Listenable/Listener trait that can be added to Actors. I'm wondering if

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.