I am loading multiple UIViewControllers in UIPageViewController with each UIViewController having their own navigation bar. I have implemented all the required data source and delegate methods for UIPageViewController and it showing up correctly.
But when I scroll my view controller horizontally, more often, I see a white blank screen instead of my view controller. Below is my code.
Any clue what could be wrong here.
PS: I tried by removing the IF condition in my viewControllerForRequestID method and returning a new controller every time. This works but then I end up with one view controller showing up twice in pagination.
- (UIViewController *)pageViewController:(UIPageViewController *)iPageViewController viewControllerBeforeViewController:(UIViewController *)iViewController {
[self.pageControl setCurrentPage:self.selectedRequestIndex];
if (self.selectedRequestIndex == 0) {
return nil;
}
NSUInteger aNewSelectedRequestIndex = self.selectedRequestIndex - 1;
NSString *aPreviousRequestID = [self.paginationRequestIDList[aNewSelectedRequestIndex] stringValue];
self.selectedRequestIndex = aNewSelectedRequestIndex;
self.selectedRequestID = aPreviousRequestID;
return [self viewControllerForRequestID:self.selectedRequestID];
}
- (UIViewController *)pageViewController:(UIPageViewController *)iPageViewController viewControllerAfterViewController:(UIViewController *)iViewController {
[self.pageControl setCurrentPage:self.selectedRequestIndex];
if (self.selectedRequestIndex == NSNotFound || self.selectedRequestIndex >= self.paginationRequestIDList.count - 1) {
return nil;
}
NSUInteger aNewSelectedRequestIndex = self.selectedRequestIndex + 1;
NSString *aNextRequestID = self.paginationRequestIDList[aNewSelectedRequestIndex];
self.selectedRequestIndex = aNewSelectedRequestIndex;
self.selectedRequestID = aNextRequestID;
return [self viewControllerForRequestID:self.selectedRequestID];
}
- (MyNavigationViewController *)viewControllerForRequestID:(id)iRequestID {
NSString *aRequestID = iRequestID;
// Safe check to avoid numbers in request ID
if (![iRequestID isKindOfClass:[NSString class]]) {
aRequestID = [iRequestID stringValue];
}
#synchronized (self) {
if ([self.viewControllers containsObjectForKey:iRequestID]) {
MyNavigationViewController *aNavigationController = self.viewControllers[iRequestID];
return aNavigationController;
}
MyDataModel *aRequestData = self.savedRequestData[iRequestID];
MyDataModelController *aRequestInfoController = [[MyDataModelController alloc] initWithRequestData:aRequestData];
aRequestInfoController.delegate = self;
MyNavigationViewController *aNavigationController = [[MyNavigationViewController alloc] initWithRootViewController:aRequestInfoController];
[self.viewControllers setObject:aNavigationController forKey:iRequestID];
return aNavigationController;
}
}
Related
I have a UIPageViewController that I've set up with an array as the datasource. I see the first page fine and the presentation count dots show up correctly, but when I try to drag the to the next page nothing happens. So I set up some breakpoints in the viewControllerAfterViewController as well as Before methods and they never get called on. The other dataSource methods for presentationCountForPageViewController get called on fine.
Any idea what I am missing? I've been going line by line with examples I've found on the web but can't find anything.
- (void)viewDidLoad
{
[super viewDidLoad];
UIPageViewController *pageController = self.pageController;
pageController.dataSource = self;
UIChildViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[initialViewController];
[pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
[self addChildViewController:pageController];
[self.view addSubview:pageController.view];
[pageController didMoveToParentViewController:self];
}
- (UIPageViewController *)pageController
{
return !_pageController ? _pageController =
({
UIPageViewController *value = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
value.view.frame = self.view.bounds;
value;
}) : _pageController;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pa geViewController viewControllerBeforeViewController:(UIChildViewController *)viewController
{
NSUInteger index = viewController.index;
return (index == 0 ) ? nil : [self viewControllerAtIndex:--index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIChildViewController *)viewController
{
NSUInteger index = viewController.index;
index++;
return (index == self.myDataSourceArray.count) ? nil : [self viewControllerAtIndex:index];
}
- (UIChildViewController *)viewControllerAtIndex:(NSUInteger)index
{
UIChildViewController *childViewController = [UIChildViewController new];
childViewController.view.frame = self.pageController.view.bounds;
childViewController.index = index;
...
return childViewController;
}
- (NSInteger)presentationCountForPageViewController: (UIPageViewController *)pageViewController
{
// The number of items reflected in the page indicator.
return self.myDataSourceArray.count;
}
- (NSInteger)presentationIndexForPageViewController:(UI PageViewController *)pageViewController
{
// The selected item reflected in the page indicator.
return 0;
}
The problem was that in including my UIViewController subclass which encapsulated the UIPageViewController, I forgot in the parent view controller's viewDidLoad to include addChildViewController and didMoveToParentViewController
[self addChildViewController:myViewController];
[self.view addSubview:myViewController.view];
[myViewControllerController didMoveToParentViewController:self];
Fixed the problem.
I am doing a tutorial in my iOS app. But I have a bug in my PageViewController.
My tutorial has 5 pages. But the second movement that I do to change page always appears the previous page repeatedly.
For example, appears page0, move to page1, and then when i want to appear page2, appears page1 again.
This occurs to both sides.
This is my code:
- (void)viewDidLoad {
[super viewDidLoad];
self.pageTexts = #[#"",intro1, intro2, intro3, intro4];
self.index = 0;
self.viewControllerPageContentOne = [[ViewControllerPageContentOne alloc] init];
self.viewControllerPageContentTwo = [[ViewControllerPageContentTwo alloc] init];
self.viewControllerPageContentThree = [[ViewControllerPageContentThree alloc] init];
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.pageViewController.dataSource = self;
UIViewController* first = [self viewControllerUsed];
NSArray *viewControllers = [NSArray arrayWithObject:first];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (UIViewController *)viewControllerUsed{
if (self.index == 0) {
self.viewControllerPageContentOne=[self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentOne"];
return self.viewControllerPageContentOne;
}
else if (self.index == 1)
{
self.viewControllerPageContentTwo=[self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentTwo"];
self.viewControllerPageContentTwo.titleText = self.pageTexts[self.index];
return self.viewControllerPageContentTwo;
}
else if (self.index == 2)
{
self.viewControllerPageContentTwo=[self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentTwo"];
self.viewControllerPageContentTwo.titleText = self.pageTexts[self.index];
return self.viewControllerPageContentTwo;
}
else if (self.index == 3)
{
self.viewControllerPageContentTwo=[self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentTwo"];
self.viewControllerPageContentTwo.titleText = self.pageTexts[self.index];
return self.viewControllerPageContentTwo;
}
else if (self.index == 4)
{
self.viewControllerPageContentThree=[self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentThree"];
self.viewControllerPageContentThree.titleText = self.pageTexts[self.index];
return self.viewControllerPageContentThree;
}
else{
return nil;
}
}
#pragma mark - Page View Controller Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
self.index--;
if (self.index < 0) {
self.index = [self.pageTexts count]-1;
}
return [self viewControllerUsed];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
self.index++;
if (self.index > [self.pageTexts count]-1) {
self.index = 0;
}
return [self viewControllerUsed];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return [self.pageTexts count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
I suppose that there is an error in index pages but I don’t know it.
Thanks
I think your problem is that you are creating class level properties for view controllers. And that too you are initialising them in viewDidLoad
self.viewControllerPageContentOne = [[ViewControllerPageContentOne alloc] init];
self.viewControllerPageContentTwo = [[ViewControllerPageContentTwo alloc] init];
self.viewControllerPageContentThree = [[ViewControllerPageContentThree alloc] init];
My advise is to create view controllers and save them in an array like this:
UIViewController *page0 = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentOne"];
UIViewController *page1 = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentTwo"]
page3.titleText = self.pageTexts[1];
UIViewController *page2 = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentTwo"]
page3.titleText = self.pageTexts[2];
UIViewController *page3 = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentTwo"]
page3.titleText = self.pageTexts[3];
UIViewController *page4 = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerPageContentThree"];
[self.viewControllers addObject:page0];
[self.viewControllers addObject:page1];
[self.viewControllers addObject:page2];
[self.viewControllers addObject:page3];
[self.viewControllers addObject:page4];
And then in your viewControllerUsed simply return viewControllers from self.viewControllers like self.viewControllers[self.index].
I'm loading views into a UIPageViewController and scrolling through them horizontally.
My issue is that when a view enters screen, it has a bigger size, and when the scroll finishes, it snaps to the size it should have.
Been trying to figure this out for a couple of hours now.
Anyone has had the same problem? how did you solve it?
I've checked these 2 links:
UIPageViewController changes size?
UIPageViewController has strange size
That made sense, but on my case, by doing that, I made the views too big on smaller devices, feels like the constraints aren't working, so I'm getting the bigger size here
I am not sure but try this:
// Disalbe translatesAutoresizingMaskIntoConstraints
self.pageViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
// Set up page view controller view constraints by using PureLayout
[self.pageViewController.view autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero]
please confine is it help ful or not ..
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
ImageViewController *contentVc = (ImageViewController *)viewController;
NSUInteger currentIndex = [_modelArray indexOfObject:[contentVc model]];
_vcIndex = currentIndex;
[_rateStepper setValue:[[contentVc model] rating]];
ImageModel *model = [_modelArray objectAtIndex:_vcIndex];
[_imageLabel setText:[NSString stringWithFormat:#"%# - Rating: %d", model.imageName, model.rating]];
if (currentIndex == 0)
{
return nil;
}
ImageViewController *imageViewController = [[ImageViewController alloc] init];
imageViewController.model = [_modelArray objectAtIndex:currentIndex - 1];
return imageViewController;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
ImageViewController *contentVc = (ImageViewController *)viewController;
NSUInteger currentIndex = [_modelArray indexOfObject:[contentVc model]];
_vcIndex = currentIndex;
[_rateStepper setValue:[[contentVc model] rating]];
ImageModel *model = [_modelArray objectAtIndex:_vcIndex];
[_imageLabel setText:[NSString stringWithFormat:#"%# - Rating: %d", model.imageName, model.rating]];
if (currentIndex == _modelArray.count - 1)
{
return nil;
}
ImageViewController *imageViewController = [[ImageViewController alloc] init];
imageViewController.model = [_modelArray objectAtIndex:currentIndex + 1];
return imageViewController;
}
If you build and run now, the pages will scroll, however we are still missing the page indicator view. We only need to implement the following dataSource methods as below:
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return _modelArray.count;
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
I bought this project (http://codecanyon.net/item/turnthepdf/2417301/support) to use in my application but it is not detecting links inside PDF file. For example, page index works in webview but not working in this library.
I tried to search in internet about configuring UIPageViewController but no result.
#pragma mark Debug / Utility
- (int) currentPage
{
int pageCheck = ((UIViewController *)[self.viewControllers objectAtIndex:0]).view.tag;
return pageCheck;
}
#pragma mark Page Handling
// Update if you'd rather use some other decision style
- (BOOL) useSideBySide: (UIInterfaceOrientation) orientation
{
BOOL isLandscape = UIInterfaceOrientationIsLandscape(orientation);
return isLandscape;
}
// Store the new page and update the delgate
- (void) updatePageTo: (uint) newPageNumber
{
pageNumber = newPageNumber;
[[NSUserDefaults standardUserDefaults] setInteger:pageNumber forKey:DEFAULTS_BOOKPAGE];
[[NSUserDefaults standardUserDefaults] synchronize];
SAFE_PERFORM_WITH_ARG(bookDelegate, #selector(bookControllerDidTurnToPage:), [NSNumber numberWithInt:pageNumber]);
}
// Request controller from delegate
- (UIViewController *) controllerAtPage: (int) aPageNumber
{
if (bookDelegate &&
[bookDelegate respondsToSelector:#selector(viewControllerForPage:)])
{
UIViewController *controller = [bookDelegate viewControllerForPage:aPageNumber];
controller.view.tag = aPageNumber;
return controller;
}
return nil;
}
// Update interface to the given page
- (void) fetchControllersForPage: (uint) requestedPage orientation: (UIInterfaceOrientation) orientation
{
BOOL sideBySide = [self useSideBySide:orientation];
int numberOfPagesNeeded = sideBySide ? 2 : 1;
int currentCount = self.viewControllers.count;
uint leftPage = requestedPage;
if (sideBySide && (leftPage % 2)) leftPage--;
// Only check against current page when count is appropriate
if (currentCount && (currentCount == numberOfPagesNeeded))
{
if (pageNumber == requestedPage) return;
if (pageNumber == leftPage) return;
}
// Decide the prevailing direction by checking the new page against the old
UIPageViewControllerNavigationDirection direction = (requestedPage > pageNumber) ? UIPageViewControllerNavigationDirectionForward : UIPageViewControllerNavigationDirectionReverse;
[self updatePageTo:requestedPage];
// Update the controllers
NSMutableArray *pageControllers = [NSMutableArray array];
SAFE_ADD(pageControllers, [self controllerAtPage:leftPage]);
if (sideBySide)
SAFE_ADD(pageControllers, [self controllerAtPage:leftPage + 1]);
[self setViewControllers:pageControllers direction: direction animated:YES completion:nil];
}
- (void)viewDidLoad {
}
// Entry point for external move request
- (void) moveToPage: (uint) requestedPage
{
[self fetchControllersForPage:requestedPage orientation:(UIInterfaceOrientation)[UIDevice currentDevice].orientation];
}
#pragma mark Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
[self updatePageTo:pageNumber - 1];
return [self controllerAtPage:(viewController.view.tag - 1)];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
[self updatePageTo:pageNumber + 1];
return [self controllerAtPage:(viewController.view.tag + 1)];
}
/*
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
[self updatePageTo:pageNumber + 1];
return [self controllerAtPage:(viewController.view.tag + 1)];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
[self updatePageTo:pageNumber - 1];
return [self controllerAtPage:(viewController.view.tag - 1)];
}
*/
#pragma mark Delegate
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
NSUInteger indexOfCurrentViewController = 0;
if (self.viewControllers.count)
indexOfCurrentViewController = ((UIViewController *)[self.viewControllers objectAtIndex:0]).view.tag;
[self fetchControllersForPage:indexOfCurrentViewController orientation:orientation];
BOOL sideBySide = [self useSideBySide:orientation];
self.doubleSided = sideBySide;
UIPageViewControllerSpineLocation spineLocation = sideBySide ? UIPageViewControllerSpineLocationMid : UIPageViewControllerSpineLocationMin;
return spineLocation;
}
#pragma mark Class utility routines
// Return a UIViewController that knows how to rotate
+ (id) rotatableViewController
{
UIViewController *vc = [[RotatableVC alloc] init];
return vc;
}
// Return a new book
+ (id) bookWithDelegate: (id) theDelegate
{
BookController *bc = [[BookController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
bc.dataSource = bc;
bc.delegate = bc;
bc.bookDelegate = theDelegate;
return bc;
}
Annotations inside a pdf is not able to render in iOS devices to render forms or annotations you can go for a good library.
Pdf Tron Library
You can also see the below link it might help.
Get pdf hyperlinks on ios
I have a slight problem with my code. I keep getting the following message appear when I try to I have two page view controllers in my application. Both are being used for different things. I copied and pasted my coding for the first page controller I implemented and then I changed around the names to prevent conflicts. I recently started to recieve this error message and now my program can no longer work. Can anyone please tell me why this happens?
I also get an error which says method 'pageViewController:viewControllerBeforeViewController:' in protocol not implemented. Im not too sure if this is a linked problem, but does anyone know why I get this?
#import "StorageViewController.h"
#import "InstructionContentViewController.h"
#interface StorageViewController ()
#end
#implementation StorageViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Create the data model
_pageInstructTitles = #[#"Over 200 Tips and Tricks", #"Discover Hidden Features", #"Bookmark Favorite Tip", #"Free Regular Update"];
_pageInstructImages = #[#"instructions1.png", #"instructions2.png", #"instructions3.png", #"instructions4.png"];
// Create page view controller
self.instructViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"InstructionViewController"];
self.instructViewController.dataSource = self;
InstructionContentViewController *startingInstructViewController = [self viewControllerAtIndex:0];
NSArray *viewInstructControllers = #[startingInstructViewController];
[self.instructViewController setViewControllers:viewInstructControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
// Change the size of page view controller
self.instructViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 30);
[self addChildViewController:_instructViewController];
[self.view addSubview:_instructViewController.view];
[self.instructViewController didMoveToParentViewController:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)startInstructWalkthrough:(id)sender {
InstructionContentViewController *startingInstructViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingInstructViewController];
[self.instructViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
}
#pragma mark - Page View Controller Data Source Methods:
- (UIViewController *)instructViewController:(UIPageViewController *)instructViewController viewControllerBeforeViewController:(UIViewController *)viewInstructController
{
NSUInteger index = ((InstructionContentViewController*) viewInstructController).instructPageIndex;
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)instructViewController:(UIPageViewController *)instructViewController viewControllerAfterViewController:(UIViewController *)viewInstructController
{
NSUInteger index = ((InstructionContentViewController*) viewInstructController).instructPageIndex;
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.pageInstructTitles count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (InstructionContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.pageInstructTitles count] == 0) || (index >= [self.pageInstructTitles count])) {
return nil;
}
// Create a new view controller and pass suitable data.
InstructionContentViewController *instructionContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"InstructionContentViewController"];
instructionContentViewController.instructImageFile = self.pageInstructImages[index];
instructionContentViewController.instructTitleText = self.pageInstructTitles[index];
instructionContentViewController.instructPageIndex = index;
return instructionContentViewController;
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)instructViewController
{
return [self.pageInstructTitles count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)instructViewController
{
return 0;
}
#end