页面视图控制器 - 从图像到另一个视图控制器

问题描述:

我对我想要完成的事情感到有点困惑。我有一个页面视图控制器有一个数据源包含图像数组列表。它实际上是一个用户可以翻阅的教程。我想要做的是让最后一页登录屏幕,以便用户可以输入信息并点击登录按钮。我认为这将是添加一个登录视图控制器的阵列一样简单,但哦我是多么错误d:当我想,我得到这个错误:页面视图控制器 - 从图像到另一个视图控制器

*终止应用程序由于未捕获的异常“NSInvalidArgumentException”,原因:' - [UIViewController _isResizable]:发送到实例0xa160660'

无法识别的选择器我为做这样的noob而道歉我只是试图让我的头在附近。这里是我的代码(通过使用这个网站实际完成):

我的数据源(ModelController.h)

#import <Foundation/Foundation.h> 
@class DataViewController; 
@interface ModelController : NSObject <UIPageViewControllerDataSource> 
- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard; 
- (NSUInteger)indexOfViewController:(DataViewController *)viewController;` 
@end 

ModelController.m

#import "ModelController.h" 
#import "DataViewController.h" 
#import "LoginViewController.h" 

@interface ModelController() 
@property (readonly, strong, nonatomic) NSArray *pageData; 
@end 


@implementation ModelController 

- (id)init 
{ 
self = [super init]; 
if (self) 
{ 

    // Create the data model 
    _pageData = [[NSArray alloc] initWithObjects: 

        [UIImage imageNamed:@"tutorial1.png"], 
        [UIImage imageNamed:@"tutorial2.png"], 
        [UIImage imageNamed:@"lastWishes.png"], 
        [UIImage imageNamed:@"todo.png"], 
        [UIImage imageNamed:@"web.png"], 
       (LoginViewController*)[[UIViewController alloc] init], 

        nil]; 
} 
return self; 
} 

- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard 
{ 
// Return the data view controller for the given index. 
if (([self.pageData count] == 0) || (index >= [self.pageData count])) 
{ 
    return nil; 
} 

// Create a new view controller and pass suitable data. 
DataViewController *dataViewController = [storyboard  instantiateViewControllerWithIdentifier:@"DataViewController"]; 
dataViewController.dataObject = self.pageData[index]; 
return dataViewController; 
} 

- (NSUInteger)indexOfViewController:(DataViewController *)viewController 
{ 
// Return the index of the given data view controller. 
// For simplicity, this implementation uses a static array of model objects and the view  controller stores the model object; you can therefore use the model object to identify the index. 
return [self.pageData indexOfObject:viewController.dataObject]; 
} 

#pragma mark - Page View Controller Data Source 

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController  viewControllerBeforeViewController:(UIViewController *)viewController 
{ 
NSUInteger index = [self indexOfViewController:(DataViewController *)viewController]; 
if ((index == 0) || (index == NSNotFound)) { 
    return nil; 
} 

index--; 
return [self viewControllerAtIndex:index storyboard:viewController.storyboard]; 
} 

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController  viewControllerAfterViewController:(UIViewController *)viewController 
{ 
NSUInteger index = [self indexOfViewController:(DataViewController *)viewController]; 
if (index == NSNotFound) { 
    return nil; 
} 

index++; 
if (index == [self.pageData count]) { 
    return nil; 
} 
return [self viewControllerAtIndex:index storyboard:viewController.storyboard]; 
} 


@end 

家长(RootViewController.h)

#import <UIKit/UIKit.h> 

@interface RootViewController : UIViewController <UIPageViewControllerDelegate> 

@property (strong, nonatomic) UIPageViewController *pageViewController; 

@end 

RootViewController.m

#import "RootViewController.h" 

#import "ModelController.h" 

#import "DataViewController.h" 

@interface RootViewController() 
@property (readonly, strong, nonatomic) ModelController *modelController; 
@end 

@implementation RootViewController 

@synthesize modelController = _modelController; 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 
// Do any additional setup after loading the view, typically from a nib. 
// Configure the page view controller and add it as a child view controller. 
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:nil]; 
self.pageViewController.delegate = self; 

DataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard]; 
NSArray *viewControllers = @[startingViewController]; 
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL]; 

self.pageViewController.dataSource = self.modelController; 

[self addChildViewController:self.pageViewController]; 
[self.view addSubview:self.pageViewController.view]; 

// Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages. 
CGRect pageViewRect = self.view.bounds; 
self.pageViewController.view.frame = pageViewRect; 

[self.pageViewController didMoveToParentViewController:self]; 

// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily. 
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers; 
} 

- (void)didReceiveMemoryWarning 
{ 
[super didReceiveMemoryWarning]; 
// Dispose of any resources that can be recreated. 
} 

- (ModelController *)modelController 
{ 
// Return the model controller object, creating it if necessary. 
// In more complex implementations, the model controller may be passed to the view controller. 
if (!_modelController) { 
    _modelController = [[ModelController alloc] init]; 
} 
return _modelController; 
} 

#pragma mark - UIPageViewController delegate methods 

/* 
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating: (BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted: (BOOL)completed 
{ 

} 
*/ 

- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation 
{ 
// Set the spine position to "min" and the page view controller's view controllers array to contain just one view controller. Setting the spine position to 'UIPageViewControllerSpineLocationMid' in landscape orientation sets the doubleSided property to YES, so set it to NO here. 
UIViewController *currentViewController = self.pageViewController.viewControllers[0]; 
NSArray *viewControllers = @[currentViewController]; 
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL]; 

self.pageViewController.doubleSided = NO; 
return UIPageViewControllerSpineLocationMin; 
} 


@end 

的儿童(DataViewController.h)

#import <UIKit/UIKit.h> 

@interface DataViewController : UIViewController 
@property (strong, nonatomic) id dataObject; 
@property (weak, nonatomic) IBOutlet UIImageView *imageView; 

@end 

DataViewController.m

#import "DataViewController.h" 

@interface DataViewController() 

@end 

@implementation DataViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
if (self) { 
    // Custom initialization 
} 
return self; 
} 

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 
// Do any additional setup after loading the view. 
} 

- (void)didReceiveMemoryWarning 
{ 
[super didReceiveMemoryWarning]; 
// Dispose of any resources that can be recreated. 
} 

- (void) viewWillAppear:(BOOL)animated 
{ 
[super viewWillAppear:animated]; 
self.imageView.image = _dataObject; 
} 

@end 

再次,有问题的代码是在这里,我正在尝试一个视图控制器添加到数据源作为最后一页:

_pageData = [[NSArray alloc] initWithObjects: 

       [UIImage imageNamed:@"tutorial1.png"], 
       [UIImage imageNamed:@"tutorial2.png"], 
       [UIImage imageNamed:@"lastWishes.png"], 
       [UIImage imageNamed:@"todo.png"], 
       [UIImage imageNamed:@"web.png"], 
      (LoginViewController*)[[UIViewController alloc] init], 

       nil]; 

并且出现无法识别的选择器错误运行时间。我也试过这个:

- (id)init 
{ 
self = [super init]; 
if (self) 
{ 
    LoginViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"]; 
    // Create the data model 
    _pageData = [[NSArray alloc] initWithObjects: 

        [UIImage imageNamed:@"tutorial1.png"], 
        [UIImage imageNamed:@"tutorial2.png"], 
        [UIImage imageNamed:@"lastWishes.png"], 
        [UIImage imageNamed:@"todo.png"], 
        [UIImage imageNamed:@"web.png"], 
        viewController, 

        nil]; 
} 
return self; 
} 

任何建议将是伟大的。谢谢!!

你的想法是100%正确的,你的实现不是。

这条线:

dataViewController.dataObject = self.pageData[index];

是非常可疑的,因为这会在你的登录屏幕的情况下返回一个UIViewController。我建议你type-check你的页面数据,如果它已经是一个UIViewController子类,只要返回它,如果它是(在你的情况下)一个UIImage添加它作为数据对象。

+0

嘿保罗。非常感谢你回复我的帖子。关于你的建议,你能用一些示例代码进行更新吗?我只是想知道类型检查是否应该在您所指的方法内发生,或者应该在我创建页面数据之前发生。请原谅我的无知大声笑 – mafiOSo