【问题标题】:UIPageViewController with different ViewControllers, right way?UIPageViewController 与不同的 ViewController,对吗?
【发布时间】:2016-05-18 15:05:48
【问题描述】:

基本上,我有一个 Table View Controller 和一个普通的 View Controller,我想制作它以便我可以在应用程序主屏幕上的视图控制器之间滑动(显然是相同类型的视图控制器)。

但我发现UIpageviewcontroller 通常在您有多个相同类型的viewcontroller 视图时使用,例如在图片之间滑动,您可以只在类中设置一个索引和一个数组与索引相关的图像并以这种方式进行设置。

但我试图在这个设置中获得不同的视图控制器。现在是两个,但肯定会上升到大约 4 个。

UIPageViewController 是正确的设置方式还是其他方式。

编辑:下面添加的代码

    //
//  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

我希望初始视图是表视图控制器 (tvc),我希望后视图控制器 (pvc) 位于其左侧。我可以加载它并轻松地在两者之间滑动,但有时我可以滑动比边界更远,所以基本上如果我从 tvc-->pvc-->tvc 开始,那么我可以通过向右滑动到同一个 tvc 然后走得更远到达边界或通过向左滑动以进行最后一次转换,以其他方式 tvc-->pvc-->tvc-->pvc-->pvc。边界最终到达。一旦应用程序最初在 tvc 启动,我就无法前进页面,(这是应该发生的),如果我去 tvc--> pvc 并尝试转到左侧的页面,它不会让我(这是应该发生的) )

谢谢

【问题讨论】:

  • 有什么问题? UIPageViewController 旨在加载多个视图控制器。不要求它们是相同类型的视图控制器。使用标签控制器可能是另一种选择。
  • 它们没有正确更改,我在 viewcontroller 中设置了一个显示 pageviewcontroller 的索引,当达到索引的边界时我返回 nil,它仍然将页面更改为再次出现的相同页面

标签: ios objective-c uipageviewcontroller


【解决方案1】:

终于完成了,不必为不同的类添加任何属性。刚刚测试了类。代码如下:

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

应该很容易添加更多视图控制器,因为我只需要添加 else if 语句来测试它们。主要的问题解决者是方法 isKindOfClass:

谢谢大家的回复!

【讨论】:

  • 非常感谢!这个答案太神奇了!我在 PageViewControllers 上工作了几天,现在终于可以工作了!这太棒了。
【解决方案2】:

我遇到了同样的问题,这就是我所做的并且工作得很好。

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

注意:

self.viewControllerIDArr 容器 Storyboard ID 的 viewControllers。

在故事板中看起来像这样:

【讨论】:

    【解决方案3】:

    这是一个老问题,但由于我遇到了这个问题,所以我会发布我的解决方案。

    我第一次这样做时添加了我的代码

    func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { }
    

    当您使用两根手指连续滚动视图时遇到问题,除非滚动停止,否则不会调用 didFinishAnimating

    所以我只使用了这个委托方法。

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

    currentView 是 currentUIViewController(或 UINavigationController,就像我正在使用的那样,也使用 restoreIdentifier 来标识我的导航控制器),并且 index 是一个全局值,用于知道数组中的哪个 UIViewController实例化。

    【讨论】:

      【解决方案4】:

      您可以使用带有一些自定义逻辑的 UIViewPageViewController。

      正如你所说,处理这个问题的正常方法是让页面视图控制器的数据源简单地为每个页面创建相同类型的视图控制器,并用你的模型中的数据填充它。

      在您的情况下,您可以将 pageNumber 属性添加到您将在页面视图控制器中托管的所有视图控制器。然后,在数据源方法中,使用旧视图控制器的页码来计算新的页码。然后有一个基于页码的 switch 语句。 switch 语句中的每种情况都会创建不同类型的视图控制器。

      【讨论】:

      • 我试图通过向每个视图控制器添加一个称为页面索引的属性来做到这一点。但是当试图在两个 uipageviewcontroller 方法(之前和之后)中读取它时。我输入 if(viewcontroller.page index == 0) 它说视图控制器中不存在名为 index 的属性,因为它认为它是通过方法传递的普通 uiviewcontroller
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多