Issue with iOS7 and UIPageViewController - ios

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;

Related

UIPage Control Buttons

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

Why ContentVC's viewWill/DidAppear is called before its parent(PageVC)?

In my case, I use ViewController as parent of PageViewController. And it also be the dataSource of PageViewController by providing ContentViewController.
It's strange that ContentViewController's -viewWill/DidAppear: is called before it's parent, here is what I got from console:
[ContentViewController viewWillAppear:]
[ContentViewController viewDidAppear:]
[ViewController viewWillAppear:]
[PageViewController viewWillAppear:]
[ViewController viewDidAppear:]
[PageViewController viewDidAppear:]
Here are some code from ViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
PageViewController *pageVC = [[PageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];;
pageVC.dataSource = self;
[pageVC setViewControllers:#[[self contentViewControllerWithIndex:0]]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO completion:nil];
pageVC.view.backgroundColor = [UIColor whiteColor];
pageVC.view.frame = self.view.bounds;
[self addChildViewController:pageVC];
[self.view addSubview:pageVC.view];
[pageVC didMoveToParentViewController:self];
}
-(ContentViewController *)contentViewControllerWithIndex:(NSInteger )index {
ContentViewController *vc = [[ContentViewController alloc] init];
vc.index = index;
return vc;
}
Thanks.
If you go through line by line of your code
This line just alloc your PageViewController. It has actually not added it on top of your ViewController. So ViewWillAppear for PageViewController will not get called here.
Code:
PageViewController *pageVC = [[PageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
Below line is calling [self contentViewControllerWithIndex:0] which will be allocating the ContentViewController also adding it on PageVC so ViewWillAppear for ContentViewController is called
Code:
[pageVC setViewControllers:#[[self contentViewControllerWithIndex:0]]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO completion:nil];
Below line is adding PageVC as childViewControllerof ViewController. So once the ViewWillAppear of ViewController will be called then only it can call ViewWillAppear of PageVC and add it as its childView.
Code:
[self addChildViewController:pageVC];
[self.view addSubview:pageVC.view];
[pageVC didMoveToParentViewController:self];

UIPageViewController, instantiating ViewControllers with Storyboard ID, Objective-C

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.

Delegate between UIViewControllers

I have following structure of ViewControllers:
PageViewController contains PhotoViewController and VideoViewController, that changing programmatically, so there no any segues.
I want allow VideoControlViewController to use methods from CameraViewController. I tried to use following code:
self.videoControlViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"videoControlViewController"];
self.videoControlViewController.delegate = self;
It don't works because method "instantiateViewControllerWithIdentifier" creates new instance of VideoViewController. Here is topic with the same problem that I found:
http://iphonedevsdk.com/forum/iphone-sdk-development/109543-string-becomes-nil-after-viewdidload-with-protocol-and-delegate.html
How can I point self.VideoControlViewController to its instance from storyboard if there no any segues or transitions?
- (void)viewDidLoad {
[super viewDidLoad];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.viewControllers = #[#"photoControlViewController", #"videoControlViewController"];
self.pageViewController.dataSource = self;
[[self.pageViewController view] setFrame:[[self view] bounds]];
[self.pageViewController setViewControllers:[NSArray arrayWithObject:[self viewControllerAtIndex:[self.viewControllers indexOfObject:#"photoControlViewController"]]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageViewController];
[[self view] addSubview:[self.pageViewController view]];
[self.pageViewController didMoveToParentViewController:self];
}

Using UIPageViewController with Multiple Views

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.

Resources