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

时间:2012-10-29 00:17:22

标签: xcode storyboard uipageviewcontroller

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

* 由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:' - [UIViewController _isResizable]:无法识别的选择器发送到实例0xa160660'

我为这样一个菜鸟而道歉我对这一切都很陌生,只是试图了解它。这是我的代码(实际使用此网站完成):

我的数据源(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

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

任何建议都会很棒。谢谢!

1 个答案:

答案 0 :(得分:2)

您的想法是100%正确的,您的实施不是。

这一行:

  

dataViewController.dataObject = self.pageData [index];

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