I've asked this question before, and I haven't got any solid answers, I am determined to find the solution not take up too much time, so I added images through Google sites.
I'd like to navigate with Page Control from View 1 to view 2 which are 2 separate view controllers.
pic one xcode
Pic 2 story board
Additional code that needs fixing:
#pragma mark - Page View Controller Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = ((PageContentViewController*) viewController).pageIndex;
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
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;
}
I just need the UIPageViewController to navigate from view 1 to view 2 and back to view 1 from view 2.
Hi you have to use this method also
- (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;
}
or refer this links hope it will work for you.
http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/
Thanks
Related
I've UIPageViewController and I can go next and previous page using below delegate methods.
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[PageController class]])
return nil;
if(_counter < 1) {
return nil;
}
self.view.backgroundColor = [UIColor lightGrayColor];
return [self.storyboard instantiateViewControllerWithIdentifier:#"memoTable"];
}
Edit:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
//NSLog(#"Child controller count = %lu",(unsigned long)pageViewController.childViewControllers.count);
if ([viewController isKindOfClass:[PageController class]])
return nil;
if([viewController isKindOfClass:[TableViewController class]])
{
TableViewController *viewController1 = (TableViewController*) viewController;
if (viewController1.dataArr.count < 5) {
return nil;
}
}
return [self.storyboard instantiateViewControllerWithIdentifier:#"pageView"];
}
Now I want to go next page if some condition satisfied. Like last page viewController.isCheck == true.
How can I achieve this?
You can just add that condition to one of the existing ifs and return nil if the condition isn't verified. Something like:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[PageController class]] || ((YourViewControllerClass *)viewController).isCheck == false)
return nil;
return [self.storyboard instantiateViewControllerWithIdentifier:#"pageView"];
}
Simply check the view controller you instantiated before returning it in pageViewController:viewControllerAfterViewController method.
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[PageController class]])
return nil;
let pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"pageView"];
if (pageViewController.isCheck)
return pageViewController;
else return nil;
}
My second guess is that you should try to instantiate all the view controllers that you will need in the UIPageViewController before you navigate.
UIViewController* memoViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"memoTable"];
UIViewController* pageViewContentController = [self.storyboard instantiateViewControllerWithIdentifier:#"pageView"];
assign all the view controllers you will need in an array
NSArray* reservedViewControllers = #[memoViewController, pageViewController];
use index to track where you current page is
int currentIndex = 0;
Then you can easily iterate between your view controllers in the UIPageViewControllerDataSource functions.
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if(currentIndex == 0) return nil;
currentIndex = currentIndex - 1;
return reservedViewControllers[currentIndex];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if(currentIndex == reservedViewControllers.count) return nil;
currentIndex = currentIndex + 1;
//check for last page
if(currentIndex == reservedViewControllers.count){
UIViewController* lastViewController = reservedViewControllers[currentIndex];
if(lastViewController.isCheck == false) return nil;
}
return reservedViewControllers[currentIndex];
}
According to your question you should use the scroll view for this purpose.. set the content size of the scroll view and give the content offset to the content on your table...
for your reference:
see the link:
https://github.com/cwRichardKim/RKSwipeBetweenViewControllers
https://github.com/nicklockwood/SwipeView
I have followed this tutorial for creating PageViewController http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/
What the problem is iam getting of the page incorrectly rest of the things all are perfect
I need to do something like if the page index is the last index then i have change the buttons label.
- (PageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.pageImages count] == 0) || (index >= [self.pageImages 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;
NSLog(#"INDEX : %lu", (unsigned long)index);
return pageContentViewController;
}
- (void)pageViewController:(UIPageViewController *)pageViewCntr didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
NSInteger currentIndex = ((UIViewController *)self.pageViewController.viewControllers.firstObject).view.tag;
if (completed) pageControl.currentPage = currentIndex;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSInteger index = ((PageContentViewController *)viewController).pageIndex;
if (index == NSNotFound || !index) return nil;
NSLog(#"INDEX : %lu", (unsigned long)index);
return [self viewControllerAtIndex:index-1];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSInteger index = ((PageContentViewController *)viewController).pageIndex;
if (index == NSNotFound || index == pageCount-1) return nil;
NSLog(#"INDEX : %lu", (unsigned long)index);
return [self viewControllerAtIndex:index+1];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
return [self.pageImages count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
return 0;
}
I tried many way but couldn't resolve the problem.
Help me in finding the current index of the page.
Index of the page is not showing currently when i swipe one time it returns me 0,1 index at a time and for next swipe it shows me 2 and for next swipe it does not return me any index
I have implemented the same code and after debugging, got to know that the PageViewControllerDataSource methods are getting called twice. So you can use willTransitionToViewControllers method instead of viewControllerBeforeViewController and viewControllerAfterViewController methods to get the proper index.
Please refer following answer,
PageViewController delegate functions called twice
How we can show more then 30 pageIndicator in UIPageControl in objective C, its going out from UIPageControl view.
Is there any way to manage that in 10 - 10 blocks/segment at one time.
I am using following code :
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = [(DetailOfferViewController *)viewController index];
if (index ==0 ) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = [(DetailOfferViewController *)viewController index];
index++;
if (index == [_data count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
return [_data count];
//_data count coming with more then 30 numbers
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
return [_rowNumber intValue];
}
Per Apple's Documentation on UIPageControl:
On iPhone and iPod touch, about 20 page control dots fit on the screen before they are clipped.
My UIPageViewController's page indicator goes out of sync when swiping back and forth really fast using this UIAutomation script:
target.dragFromToForDuration({x:10, y:100}, {x:300, y:114}, 0.5);
target.dragFromToForDuration({x:300, y:100}, {x:10, y:114}, 0.5);
repeated over and over.
Or when tapping one direction on the page controller and swiping the other direction as in this question:
UIPageControl and UIPageviewController are out of sync
The solution there was to replace the page indicator with a UIPageControl. This solution was also accepted here:
Page Indicator UIPageViewController
My code for returning the UIViewControllers (the UIViewControllers contain tables with different data sources):
- (MyViewController*) viewControllerAtIndex:(NSUInteger)index
{
MyViewController *pageContentViewController = [[MyViewController alloc] initWithNibName:#"MyView" bundle:nil];
id myDataSource = [self.myDataSources objectAtIndex:index];
[pageContentViewController setMyDataSource:myDataSource];
return pageContentViewController;
}
#pragma mark - Page View Controller Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
id myDataSource = [((MyViewController*) viewController) myDataSource];
NSInteger index = [self.myDataSources indexOfObject:myDataSource];
if (index == NSNotFound || index - 1 < 0) {
return nil;
} else {
MyViewController *pageContentViewController = [self viewControllerAtIndex:index - 1];
return pageContentViewController;
}
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
MyDataSource *myDataSource = [((MyViewController*) viewController) myDataSource];
NSInteger index = [self.myDataSources indexOfObject:myDataSource];
if (index == NSNotFound || index + 1 >= [self.myDataSources count]) {
return nil;
} else {
MyViewController *pageContentViewController = [self viewControllerAtIndex:index + 1];
return pageContentViewController;
}
return nil;
}
What is causing the UIPageViewController and page indicator to become out of sync?
I want a segmented control to act like the gray dots at the bottom of the page of a pageview controller. So, when I swipe to the right, it moves to the segment on the right, and when I swipe to the left, it moves to the segment on the left. I've already got it to change the page when I click on a specific segment correctly (so if I click the first segment, it moves to the first page). However, I can't seem to make the code do exactly what I want it to do. Right now I have the following code:
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers
{
if([pendingViewControllers count]>0)
{
NSUInteger index =[(MasterTableViewController*)[pendingViewControllers objectAtIndex:0] pageIndex];
segmentedControl.selectedSegmentIndex = index;
}
}
This works fine, but the problem is that this is called when the transition is happening, not when it is finished. Therefore, when I start changing the page, but then stop, it moves the segment over. So, I tried some other code:
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
if(finished && completed && [previousViewControllers count]>0)
{
NSUInteger index =[(MasterTableViewController*)[previousViewControllers objectAtIndex:0] pageIndex];
segmentedControl.selectedSegmentIndex = index;
self.lastSelected = index;
}
}
This is called at the right time. If I put an NSLOG, it shows up ever time I finish a transition, which is exactly what I want, but for some reason, the segmentcontrol is lagged behind by 1 move. So, if I go from page 1 to page 2, segment stays at 1, and then if i go from page 2 to page 3, segment moves to 2, and then from then on it continues to lag behind by one move no matter which direction I go. I've played around with it and I can't seem to get the logic straight. Help would be greatly appreciated!!
Here are the helper functions:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = ((MasterTableViewController*) viewController).pageIndex;
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = ((MasterTableViewController*) viewController).pageIndex;
if (index == NSNotFound) {
return nil;
}
index++;
// startingViewController.pageIndex = index;
if (index == [self.pageTitles count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (MasterTableViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.pageTitles count] == 0) || (index >= [self.pageTitles count])) {
return nil;
}
MasterTableViewController *pageContentViewController;
if (index == 0)
{
pageContentViewController = [storyboard instantiateViewControllerWithIdentifier:#"OnCampusTable"];
}
else if (index == 1)
{
pageContentViewController = [storyboard instantiateViewControllerWithIdentifier:#"OffCampusTable"];
}
else if (index == 2)
{
pageContentViewController = [storyboard instantiateViewControllerWithIdentifier:#"MyEventsTable"];
}
// pageContentViewController.titleText = self.pageTitles[index];
pageContentViewController.pageIndex = index;
return pageContentViewController;
}
Any of the commented stuff was stuff I was playing with to try to get the logic straight. I just ran the program with didFinishAnimating running and willTransitionToViewControllers commented out. This gave the lagged effect where the segmented control is one behind the cells. Any help is very appreciated
this is how i solved it:
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers
{
if([pendingViewControllers count]>0)
{
NSUInteger index =[(MasterTableViewController*)[pendingViewControllers objectAtIndex:0] pageIndex];
startingViewController.pageIndex = index;
}
}
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
if(finished && completed && [previousViewControllers count]>0)
{
NSUInteger index =[(MasterTableViewController*)[previousViewControllers objectAtIndex:0] pageIndex];
segmentedControl.selectedSegmentIndex = startingViewController.pageIndex;
self.lastSelected = index;
}
}
Essentially, I used both the willTransition and the didFinishAnimation. When you call a transition, the method changes a global variable, pageIndex, to get the page index, but doesn't change the segment. When you finish the animation, the didFinish method pulls the global pageIndex, and sets the segment to be that page.
You could just use didset method:
var pageIndex:Int!{
didSet{
segmentControl.selectedSegmentIndex = pageIndex
}
}