I am new to iOS and I am using UIPageViewController. Here is my code:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
firstVC *first1 = [[firstVC alloc] initWithNibName:#"firstVC" bundle:nil]; return first1;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
secondVC *second1 = [[secondVC alloc] initWithNibName:#"secondVC" bundle:nil]; return second1;
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { NSArray *viewControllers = nil; viewControllers = [NSArray arrayWithObjects:first,second, nil]; [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerSpineLocationMid animated:NO completion:NULL];
}
-(UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation {
NSArray *viewControllers = nil; viewControllers = [NSArray arrayWithObjects:second, first, nil]; [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerSpineLocationMid animated:YES completion:NULL]; return UIPageViewControllerSpineLocationMid;
}
- (void)viewDidLoad { [super viewDidLoad]; [self.navigationController setNavigationBarHidden:NO]; self.navigationController.navigationBar.tintColor = [UIColor blackColor]; self.title = #"DEMO"; NSDictionary *options = [NSDictionary dictionaryWithObject: [NSNumber numberWithInteger:UIPageViewControllerSpineLocationMin] forKey: UIPageViewControllerOptionSpineLocationKey]; self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerSpineLocationMid options:options]; self.pageViewController.delegate = self; self.pageViewController.dataSource = self; first = [[firstVC alloc] initWithNibName:#"firstVC" bundle:nil]; second = [[secondVC alloc] initWithNibName:#"secondVC" bundle:nil]; NSArray *viewControllers = [NSArray arrayWithObjects:first,second,nil]; [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerSpineLocationMid animated:NO completion:nil]; [self addChildViewController:self.pageViewController]; [self.view addSubview:self.pageViewController.view]; self.modalPresentationStyle=UIModalPresentationCurrentContext; [self.pageViewController didMoveToParentViewController:self]; CGRect pageViewRect = self.view.bounds; pageViewRect = CGRectInset(pageViewRect, 20.0, 20.0); self.pageViewController.view.frame = pageViewRect; self.view.gestureRecognizers = self.pageViewController.gestureRecognizers; self.pageViewController.doubleSided=YES; }
It is loading double sided pages in both orientations but a problem arises when I swipe the page and only one view is shown. I want a page-like animation. Please help. Thanks in advance for help and support.
where do you initialize your UIPageViewController?
at the point of initializing you MUST define the transition style as it's a readonly property.
The code should look like this;
self.pageViewController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
Related
Right now I'm using page control to display 5 images. However the circle indicators showing which page you are on are appearing at the bottom of the view instead of right underneath the image like I want. I attempted to change the location using "pageControl.frame = CGRectMake(110,5,100,100);" but it does nothing.. Any reason why this is not working?
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a
nib.
_pageData = #[#"slide0.png", #"slide1.png", #"slide2.png",
#"slide3.png", #"slide4.png", #"slide5.png"];
_pageViewController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:
UIPageViewControllerNavigationOrientationHorizontal
options:nil];
_pageViewController.delegate = self;
_pageViewController.dataSource = self;
DataViewController *startingViewController = [self viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = #[startingViewController];
[_pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:_pageViewController];
[self.view addSubview:_pageViewController.view];
// Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
CGRect pageViewRect = self.view.bounds;
_pageViewController.view.frame = pageViewRect;
[_pageViewController didMoveToParentViewController:self];
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.frame = CGRectMake(110,5,100,100);
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor whiteColor];
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed {
pageControl.currentPage = pageViewController.currentPageNumber;
}
I am trying to implement UIPageViewController and I believe that I am in the last stage. At first the UIPageViewController only used one VC to scroll to a "different" page. Now i want it to scroll between different ViewControllers.
This is the code i am using:
- (void)viewDidLoad {
[super viewDidLoad];
self.vcIdentifiers = #[#"PageContentViewController", #"PageContentViewController1"];
// Create page view controller
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.pageViewController.dataSource = self;
UIViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 30);
[self addChildViewController:_pageViewController];
[self.view addSubview:_pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
}
- (PageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.vcIdentifiers count] == 0) || (index >= self.vcIdentifiers.count)) {
return nil;
}
// Create a new view controller and pass suitable data.
PageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageContentViewController"];
pageContentViewController.titleText = self.pageTitles[index];
pageContentViewController.pageIndex = index;
return pageContentViewController;
}
I belive it is in the viewControllerAtIndex i need to make some changes. I thought of doing this:
PageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:self.vcIdentifiers[index]];
But then it still would initialise the PageContentViewController. So my problem is i don't know how to initialise the different ViewControllers.
I followed http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/ for creating a PageViewController.
This tutorial contains :
(code for Restart button)
- (IBAction)restartButton:(id)sender {
PageContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
}
When i tried for Next button like this:
- (IBAction)nextPageButton:(id)sender {
PageContentViewController *startingViewController = [self viewControllerAtIndex:+1];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
}
but it fails, how to perform next page action with the UIButton that responds with the PageControl till last page.
That wont work because you are using +1, instead, try this:
//get current index of current page
DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
NSUInteger retreivedIndex = [self.modelController indexOfViewController:theCurrentViewController];
//check that current page isn't first page
if (retreivedIndex < 5){
//get the page to go to
DataViewController *targetPageViewController = [self.modelController viewControllerAtIndex:(retreivedIndex + 1) storyboard:self.storyboard];
//put it(or them if in landscape view) in an array
NSArray *theViewControllers = nil;
theViewControllers = [NSArray arrayWithObjects:targetPageViewController, nil];
//add page view
[self.pageViewController setViewControllers:theViewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
}
PageNumberToJump=2
-(void)buyAction
{
isFromBuy = YES;
APPChildViewController *initialViewController = [self viewControllerAtIndex:PageNumberToJump];
viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}
-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
if (isFromBuy)
{
isFromBuy = NO;
return PageNumberToJump;
}
return 0;
}
I have a UIPageViewController that is added as subview on UIView. The UIView sits on the top of UIViewController's view, at start it puts the UIPageViewController lower than it should sit, but right after I click on the next button to push the next UIPageViewController's view, it send it back to the correct position.
What is he doing that? I tried everything but still can figure out the problem.
This is how it looks:
What seems to be the problem? Thanks in advance!
EDIT: This is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
DataChildViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
self.pageController.dataSource = self;
self.pageController.delegate = self;
self.pageController.view.userInteractionEnabled = NO;
self.pageController.view.frame = self.view.bounds;
[self.pageControllerParent addSubview:self.pageController.view];
[self addChildViewController:self.pageController];
self.currentPageControllerIndex = 1;
}
- (IBAction)buttonNextDidClicked
{
self.buttonNext.enabled = NO;
__weak typeof(self) __self = self;
[self.pageController setViewControllers:#[[self viewControllerAtIndex:self.currentPageControllerIndex]]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:^(BOOL finished) {
__self.currentPageControllerIndex++;
__self.buttonNext.enabled = YES;
}];
}
#pragma mark - UIPageViewControllerDelegate & DataSource
- (DataChildViewController *)viewControllerAtIndex:(NSUInteger)index
{
DataChildViewController *childViewController = [[DataChildViewController alloc] initWithNibName:#"DataChildViewController" bundle:nil];
childViewController.index = index;
return childViewController;
}
So, I've figured out the problem.
On viewDidLoad I had this line:
self.pageController.view.frame = self.view.bounds;
When it actually should be:
self.pageController.view.frame = self.pageControllerParent.bounds;
I have the following code to create a UIPageViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
self.index = 0;
self.pageContainer = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageContainer.dataSource = self;
[[self.pageContainer view] setFrame:[[self view] bounds]];
DMSignUp1ViewController *first = [[DMSignUp1ViewController alloc] init];
DMSignUp2ViewController *second = [[DMSignUp2ViewController alloc] init];
self.viewControllers = [[NSArray alloc] initWithObjects:first, second, nil];
[self.pageContainer setViewControllers:self.viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageContainer];
[[self view] addSubview:[self.pageContainer view]];
[self.pageContainer didMoveToParentViewController:self];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if(self.index == 0) {
return nil;
}
self.index--;
return [self.viewControllers objectAtIndex:self.index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if(self.index == 1) {
return nil;
}
self.index++;
return [self.viewControllers objectAtIndex:self.index];
}
I have two UIViewControllers: DMSignUp1 and 2 which I create and then place in the viewControllers array.
When I go to run it, I get the following error: 'The number of view controllers provided (2) doesn't match the number required (1) for the requested transition'
Which I understand is because I am passing the array to use as the view controller. So how do I set that I want to use the first view controller in the array?
Add the following method at the end of the ViewController.m file
- (DMSignUp1ViewController *)viewControllerAtIndex:(NSUInteger)index {
DMSignUp1ViewController *first= [[DMSignUp1ViewController alloc] initWithNibName:#"APPChildViewController" bundle:nil];
first.index = index;
return childViewController;
}
And, replace the following code
DMSignUp1ViewController *first = [[DMSignUp1ViewController alloc] init];
DMSignUp2ViewController *second = [[DMSignUp2ViewController alloc] init];
self.viewControllers = [[NSArray alloc] initWithObjects:first, second, nil];
With
APPChildViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
Hope this might help you...
If you have the UIPageViewController spineLocation set to anything other than UIPageViewControllerSpineLocationMid when you're using [self.pageContainer setViewControllers: you can only pass an array with one view controller. The API isn't very clear really with it saying Controllers. You then provide the additional viewControllers when the UIPageViewController requests them through the dataSource.
Link to the spine reference.