I have created PageViewController and I could not able to figure out how to capture which page index is being clicked.
With this information, I could able to segue to the DetailViewController to load corresponding information.
- (void)viewDidLoad {
[super viewDidLoad];
arrPageTitles = #[#"0",#"1",#"2",#"3", #"4"];
self.newsPageImages = #[#"img1.jpg", #"img2.jpg", #"img3.png", #"img4.jpg", #"img5.jpg"];
// Create page view controller
self.PageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.PageViewController.dataSource = self;
self.PageViewController.delegate = self;
MainNewsPageContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingViewController];
[self.PageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
// Change the size of page view controller
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];
[self.view bringSubviewToFront:self.pageControl];
self.pageControl.numberOfPages = [self.arrPageTitles count];
self.pageControl.currentPage = 0;
for (UITapGestureRecognizer * gesRecog in self.PageViewController.gestureRecognizers)
{
gesRecog.delegate = self;
}
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (touch.view != self.PageViewController.view)
{
return NO;
}
return YES;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = ((MainNewsPageContentViewController*) viewController).pageIndex;
[self.pageControl setCurrentPage:index];
if ((index == 0) || (index == NSNotFound))
{
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = ((MainNewsPageContentViewController*) viewController).pageIndex;
[self.pageControl setCurrentPage:index];
if (index == NSNotFound)
{
return nil;
}
index++;
if (index == [self.arrPageTitles count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (MainNewsPageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.arrPageTitles count] == 0) || (index >= [self.arrPageTitles count])) {
return nil;
}
// Create a new view controller and pass suitable data.
MainNewsPageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MainNewsPageContentViewController"];
pageContentViewController.txtTitle = self.arrPageTitles[index];
pageContentViewController.imageFile = self.newsPageImages[index];
pageContentViewController.pageIndex = index;
return pageContentViewController;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"isMainDetailSegue"])
{
DetailViewController *dvc = [segue destinationViewController];
dvc.pageIndex = [self.pageControl currentPage];
}
}
UPDATE
I am trying to pass clicked index, but it always shows 0, no matter which pagecontentview that I click.
- (MainNewsPageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.arrPageTitles count] == 0) || (index >= [self.arrPageTitles count])) {
return nil;
}
// Create a new view controller and pass suitable data.
MainNewsPageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MainNewsPageContentViewController"];
pageContentViewController.txtTitle = self.arrPageTitles[index];
pageContentViewController.imageFile = self.newsPageImages[index];
pageContentViewController.pageIndex = index;
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
tap2.view.tag = index;
[pageContentViewController.view addGestureRecognizer:tap2];
return pageContentViewController;
}
-(void) tap2 : (UITapGestureRecognizer*)sender
{
UIView *view = sender.view; //cast pointer to the derived class if needed
NSLog(#"%ld", (long)view.tag);
}
Add a TapGestureRecognizer in your ViewControllers
- (MainNewsPageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.arrPageTitles count] == 0) || (index >= [self.arrPageTitles count])) {
return nil;
}
// Create a new view controller and pass suitable data.
MainNewsPageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MainNewsPageContentViewController"];
pageContentViewController.txtTitle = self.arrPageTitles[index];
pageContentViewController.imageFile = self.newsPageImages[index];
pageContentViewController.pageIndex = index;
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap2:)];
[pageContentViewController.view addGestureRecognizer:tap2];
tap2.view.tag = index;
return pageContentViewController;
}
-(void) tap2 : (UITapGestureRecognizer*)sender
{
UIView *view = sender.view; //cast pointer to the derived class if needed
NSLog(#"%ld", (long)view.tag);
}
You can add following code inside UIPageViewcontroller's delegate method
-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{
if (completed) {
currentPageIndex = [self indexOfController:[pageViewController.viewControllers lastObject]];
}
}
Helper method is
-(NSInteger)indexOfController:(UIViewController *)viewController{
for (int i = 0; i<[self.viewControllerArray count]; i++) {
if (viewController == [self.viewControllerArray objectAtIndex:i])
{
return i;
}
}
return NSNotFound;
}
Related
I have been unable to find a solution to this issue that resolves my case. I am looking to call the two blocks of code that swipe my page view controller programmatically.
Such as a [self viewControllerAfterViewController:self] that would call the last block of code.
In viewDidLoad
[super viewDidLoad];
indexvalue = 1;
NSLog(#"main intitated");
// Do any additional setup after loading the view, typically from a nib.
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.pageViewController.dataSource = self;
ViewController *tvc = [self.storyboard instantiateViewControllerWithIdentifier:#"Main"];
Request *pvc;
viewcontrollers =[NSArray arrayWithObjects:tvc, pvc, nil];
[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);
[self addChildViewController:pageViewController];
[self.view addSubview:pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
Code to swipe between screens called by swipe gesture
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSLog([NSString stringWithFormat:#"%i", indexvalue]);
if (indexvalue == 0 & check0 < 1) {
check0 = 1;
ViewController *tvc = [self.storyboard instantiateViewControllerWithIdentifier:#"Main"];
indexvalue = 1;
return tvc;
}
else {
return nil;
}
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSLog([NSString stringWithFormat:#"%i", indexvalue]);
if (indexvalue == 1 & check1 < 1) {
check1 = 1;
Request *pvc = [self.storyboard instantiateViewControllerWithIdentifier:#"Friends"];
indexvalue = 0 ;
return pvc;
}
else {
return nil;
}
}
viewcontrollers =[NSArray arrayWithObjects:tvc, pvc, nil];
replace with
viewControllers = #[tvc];
viewControllers= [self viewControllerAtIndex:0];
Now add this method
- (UIViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.pageTitles count] == 0) || (index >= [self.pageTitles count])) {
return nil;
}
if (index == 0) {
//first view
ViewController *pageContentViewController2 = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
return pageContentViewController2;
}
//second view
Request *pageContentViewController3 = [self.storyboard instantiateViewControllerWithIdentifier:#"Request"];
return pageContentViewController3;
}
I am using the following code for implementing UIPageViewController. How to move next and previous page using UIButton click event?
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = ((PageContentView*) viewController).pageIndex;
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = ((PageContentView *) viewController).pageIndex;
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [arrCarStatus count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
You need to call UIPageViewController methods on your UIButton tap. Here is what you need to do. Create a method for UIPageViewController
- (void)changePage:(UIPageViewControllerNavigationDirection)direction {
NSUInteger pageIndex = ((ViewControllerContainingUIImageView *) [_pageViewController.viewControllers objectAtIndex:0]).index;
if (direction == UIPageViewControllerNavigationDirectionForward)
{
pageIndex++;
}
else
{
pageIndex--;
}
initialViewController = [self viewControllerAtIndex:pageIndex];
if (initialViewController == nil) {
return;
}
[_pageViewController setViewControllers:#[initialViewController]
direction:direction
animated:YES
completion:nil];
}
Now call this method on UIButton click providing direction forward/back
-(void)backSlide
{
[self changePage:UIPageViewControllerNavigationDirectionReverse];
}
-(void)forwardSlide
{
[self changePage:UIPageViewControllerNavigationDirectionForward];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pvc.view.frame = CGRectInset(self.view.bounds, 200, 200);
[self.view addSubview:self.pvc.view];
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
-(UIViewController*)randomVC
{
UIViewController *vc = [[UIViewController alloc] init];
UIColor *color = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
vc.view.backgroundColor = color;
return vc;
}
- (IBAction)previousButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
}
- (IBAction)nextButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
Try This It May Help you. I Have Made totally New Demo.
you can just use the delegate Methods of page view controller named as a
- (void)changePage:(UIPageViewControllerNavigationDirection)direction
and just simple check the condition which i mention below.
if (direction == UIPageViewControllerNavigationDirectionForward)
{
pageIndex++;
}
else
{
pageIndex--;
}
I have a series of VCs in a PageViewController that a user navigates left to right through with their fingers. I need to add in buttons that essentially perform the same action as the finger swiping, moving left or right by one through the VCs . How can I do this? Right now I am using these two methods to dynamically setting the VCs as the user swipes:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;
Is there someway I can do the same thing if a user clicks a button?
You can programmatically set the currently displayed view controller with a transition animation using setViewControllers:direction:animated:completion: on your page view controller.
Here is an example that presents view controllers with random background colors. You can adjust this to use your specific view controllers.
- (void)viewDidLoad
{
[super viewDidLoad];
self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pvc.view.frame = CGRectInset(self.view.bounds, 200, 200);
[self.view addSubview:self.pvc.view];
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
-(UIViewController*)randomVC
{
UIViewController *vc = [[UIViewController alloc] init];
UIColor *color = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
vc.view.backgroundColor = color;
return vc;
}
- (IBAction)previousButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
}
- (IBAction)nextButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
In case Pages can be navigated by added button (Previous, Next) & also by swipe with page control ON.
Please go through below:
//Set Delegate & Data Source for PageView controller [Say in View Did Load]
self.pageViewController.dataSource = self;
self.pageViewController.delegate = self;
// PageBefore & After When User Scroll to move next or previous page
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
[_nextBtn setTitle:#"Next" forState:UIControlStateNormal];
NSUInteger index = ((PageContentViewController*) viewController).pageIndex;
if (index == NSNotFound)
{
return nil;
}
if (index > 0)
{
index--;
}
else
{
return nil;
}
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
NSUInteger index = ((PageContentViewController*) viewController).pageIndex;
if (index == NSNotFound) {
return nil;
}
if (index < 3)
{
index++;
}else
{
return nil;
}
return [self viewControllerAtIndex:index];}
//To Match Exact Index page view when scrolled & navigated using button action. Place button index when page is been translated.
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers{
buttonIndex = (int)((PageContentViewController*) pendingViewControllers.firstObject).pageIndex;}
-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{
if (buttonIndex == 0)
{
_backButton.hidden = true;
}else if (buttonIndex == [self.pageImages count] - 1)
{
_backButton.hidden = false;
[_nextBtn setTitle:#"Begin" forState:UIControlStateNormal];
}else
{
_backButton.hidden = false;
}
}
//Previous , Next Button Actions
-(void)backBtnClicked:(id)sender{
if (buttonIndex > 0)
{
buttonIndex -= 1;
}
if (buttonIndex < 1) {
_backButton.hidden = YES;
}
if (buttonIndex >=0) {
[_nextBtn setTitle:#"Next" forState:UIControlStateNormal];
PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}}
-(void)nextBtnAction:(id)sender{
if (buttonIndex < 3)
{
buttonIndex += 1;
}
if(buttonIndex == _pageImages.count){
//Navigate Outside Pageview controller
} else{
if (buttonIndex ==3) {
[_nextBtn setTitle:#"Begin" forState:UIControlStateNormal];
}
_backButton.hidden = NO;
PageContentViewController *startingViewController = [self viewControllerAtIndex:buttonIndex];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}}
//BUTTON INDEX
-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
return [self.pageImages count];}
-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
return buttonIndex;}
Pageviewcontroller is not working for first two swipe after it is work.I don't know what is the issue in my code. please refer my code below
PageViewController Coding
- (void)viewDidLoad
{
[super viewDidLoad];
self.sampleImage=#[#"sample1.jpeg",#"sample2.jpeg",#"sample3.jpeg"];
self.sampleContent=#[#"sample1",#"sample2",#"sample3"];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.dataSource = self;
MYViewCtrl *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingViewController];
self.pagecontrol= [UIPageControl appearanceWhenContainedIn:[self.pageViewController class], nil];
self.pagecontrol.currentPageIndicatorTintColor = [UIColor colorWithRed:152.0/225.0 green:10.0/225.0 blue:115.0/225.0 alpha:1.0];
self.pagecontrol.pageIndicatorTintColor = [UIColor colorWithRed:121.0/255.0 green:121.0/255.0 blue:121.0/255.0 alpha:1.0];
self.pageViewController.view.frame = CGRectMake(0, 0, self.myview.frame.size.width, self.myview.frame.size.height+35);
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:_pageViewController];
[self.myview addSubview:_pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
}
- (MYViewCtrl *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.sampleImage count] == 0) || (index >= [self.sampleImage count])) {
return nil;
}
MYViewCtrl *childViewController = [[MYViewCtrl alloc] initWithNibName:#"MYViewCtrl" bundle:nil];
childViewController.Image = self.sampleImage[index];
childViewController.Content = self.sampleContent[index];
childViewController.pageIndex=index;
return childViewController;
}-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{
NSUInteger index = ((MYViewCtrl*) viewController).pageIndex;
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
NSUInteger index = ((MYViewCtrl*) viewController).pageIndex;
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.sampleImage count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
return [self.sampleImage count];
}
-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
Can anyone help me to solve this issue.
I am trying to build a app based on information displaying via pageviewcontroller.
To prevent boredom, i would like to display the pages randomly. Everytime open up the app at different page. How can i do that, below is the code i am using. Thanks
_pageTitles = #[#"Over 200 Tips and Tricks", #"Discover Hidden Features", #"Bookmark Favorite Tip", #"Free Regular Update"];
_pageImages = #[#"page1.png", #"page2.png", #"page3.png", #"page4.png"];
// Create page view controller
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PageViewController"];
self.pageViewController.dataSource = self;
PageContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
// Change the size of page view controller
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.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;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (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];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = ((PageContentViewController*) viewController).pageIndex;
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return [self.pageTitles count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
generate your datasources, _pageTitles and _pageImages, at startup new with a random number so that the entries each run have another array index. you could do that in viewDidLoad.