问题
Basically, I have a Table View Controller and a normal View Controller, I want to make it so that I can swipe between the view controllers like on the home screen of app (obvious same type of view controller).
But the thing I am finding is that the UIpageviewcontroller
is usaully used when you have multiple views of the same type of viewcontroller
for example swiping between pictures, you could just set an index in the class and an array of images relating to the index and set it up that way.
But I'm trying to get different view controllers in this set up. Right now it's two but will definitely go up to about 4.
Is UIPageViewController
the right way to set it up or something else.
EDIT: Code added below
//
// ViewController.m
// testb
//
#import "MainPostController.h"
#import "MainTableViewController.h"
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize pageViewController;
@synthesize indexValue = _indexValue;
- (void)viewDidLoad
{
[super viewDidLoad];
self.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;
MainTableViewController *tvc = [self.storyboard instantiateViewControllerWithIdentifier:@"MainTableViewController"];
MainPostController *pvc;
NSArray *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 - 30);
[self addChildViewController:pageViewController];
[self.view addSubview:pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if (self.indexValue == 1) {
MainPostController *pvc = [self.storyboard instantiateViewControllerWithIdentifier:@"MainPostController"];
self.indexValue = 0 ;
return pvc;
}
else return nil;
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if (self.indexValue == 0) {
MainTableViewController *tvc = [self.storyboard instantiateViewControllerWithIdentifier:@"MainTableViewController"];
self.indexValue = 1;
return tvc;
}
else return nil;
}
@end
I want the intial view to be the table view controller(tvc) and i want the Post view controller(pvc) to be to its left. I can load it up and swipe between the two easily but sometime i can swipe further than the boundaries so basically if i start on the tvc-->pvc-->tvc then i can go further by swiping right to the same tvc then the boundary is reached or go the other way tvc-->pvc-->tvc-->pvc-->pvc by swiping left for the last transition. The boundaries are reached in the end. Once the app intially launches at tvc i cannot go forward a page, (which is what should happen) and if i go tvc-->pvc and try to go to a page to the left it wont let me (which is what should happen)
Thanks
回答1:
Finally done it, didn't have to add any properties to the different classes. Just tested the class. Heres the code:
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[MainTableViewController class]]) {
MainPostController *pvc = [self.storyboard instantiateViewControllerWithIdentifier:@"MainPostController"];
return pvc;
}
else return nil;
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[MainPostController class]]) {
MainTableViewController *tvc = [self.storyboard instantiateViewControllerWithIdentifier:@"MainTableViewController"];
return tvc;
}
else return nil;
}
Should be easy to add more view controllers as i just need to add else if statements to test them. The main problem solver was the method isKindOfClass:
Thanks for your reply guys!
回答2:
I had the same issue, here's what i did and working perfectly.
.h
@interface ViewController : UIViewController <UIPageViewControllerDataSource>
@property (strong, nonatomic) UIPageViewController *pageViewController;
@property (nonatomic) NSArray *viewControllerIDArr;
@end
.m
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupDefaults];
}
- (void)setupDefaults
{
self.viewControllerIDArr = @[@"FirstViewController", @"SecondViewController"];
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
self.pageViewController.dataSource = self;
UIViewController *startingViewController = [self.storyboard instantiateViewControllerWithIdentifier:self.viewControllerIDArr[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 - 45);
[self addChildViewController:_pageViewController];
[self.view addSubview:_pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
}
- (UIViewController *)getViewControllerFromClass:(Class)class isNext:(BOOL)next
{
NSInteger index = [self.viewControllerIDArr indexOfObject:[NSString stringWithFormat:@"%@", class]];
if (next)
index+=1;
else
index-=1;
if (index < 0 || index >= self.viewControllerIDArr.count)
return nil;
else
return [self.storyboard instantiateViewControllerWithIdentifier:self.viewControllerIDArr[index]];
}
#pragma mark - Page View Controller Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
return [self getViewControllerFromClass:viewController.class isNext:NO];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
return [self getViewControllerFromClass:viewController.class isNext:YES];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
return 0;
}
Note:
self.viewControllerIDArr
containers Storyboard ID's of the viewControllers.
It looks like this in storyboard:
回答3:
This is an old question but since I bumped into this problem I'll post my solution.
The first time I did this I added my code
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { }
Which received problems when you continuously scroll the views using two fingers and didFinishAnimating
is not called unless scrolling stops.
So I just used this delegate method instead.
func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
let currentView = pendingViewControllers[0]
if currentView is UINavigationController && currentView.restorationIdentifier == "Settings" {
index = 0
} else if currentView is UINavigationController && currentView.restorationIdentifier == "Main" {
index = 1
} else if currentView is UINavigationController && currentView.restorationIdentifier == "Message" {
index = 2
}
}
Where currentView is the currentUIViewController
(or UINavigationController
like what I am using, using a restorationIdentifier to identify my navigation controller as well), and index is a global value to know which UIViewController
in the array to instantiate.
回答4:
You could use a UIViewPageViewController, with some custom logic.
As you say, the normal way to handle this is to have the page view controller's data source simply create the same type of view controller for each page and fill it with data from your model.
In your case, you could add a pageNumber property to all the view controllers that you're going to host in your page view controller. Then, in the data source methods, use the page number of the old view controller to figure out the new page number. Then have a switch statement based on page number. Each case in the switch statement would create a different type of view controller.
来源:https://stackoverflow.com/questions/20734673/uipageviewcontroller-with-different-viewcontrollers-right-way