Mac OS X Cocoa多视图应用程序导航

时间:2013-02-14 23:24:50

标签: cocoa multiview nsviewcontroller

我已经花了整整2天试图弄清楚如何使用NSViewControllers来创建一个多视图应用程序。

这就是我的工作。

我有2个View Controllers和MainMenu.xib的Window。 我还有一个AppController,它是两个视图控制器的委托。

当我启动应用程序时,我首先会遇到MainMenu.xib的Window视图,其中包含一个按钮。单击此按钮,IBAction将发送到appController并要求SecondViewController显示它的nib。到目前为止,一切正常,nib文件显示正确。

在secondViewController上,还有另一个按钮,它将另一个IBAction发送到appController,并要求显示FirstViewController,但没有任何反应, 没有崩溃,没有警告......任何帮助将不胜感激...... 提前感谢您的耐心......

以下是AppController.h的代码:

#import <Foundation/Foundation.h>
#import "SecondViewController.h"
#import "FirstViewController.h"

@interface AppController : NSObject

@property (strong) IBOutlet NSWindow *mainWindow;

@property (strong) IBOutlet SecondViewController *secondViewController;
@property (strong) IBOutlet FirstViewController *firstViewController;


- (IBAction)secondButtonfromsecondViewControllerClicked:(id)sender;

- (IBAction)buttonClicked:(id)sender;

@end

这是AppController.m的代码:

#import "AppController.h"


@implementation AppController
@synthesize mainWindow = mainwindow;
@synthesize secondViewController;
@synthesize firstViewController;

- (IBAction)buttonClicked:(id)sender {

     NSLog(@"button from second View Controller clicked");

     self.secondViewController = [[SecondViewController  
     alloc]initWithNibName:@"SecondViewController" bundle:nil];
     self.mainWindow.contentView = self.secondViewController.view;
     [self.secondViewController.view setAutoresizingMask:NSViewWidthSizable | 
     NSViewHeightSizable];
}

 - (IBAction)secondButtonfromsecondViewControllerClicked:(id)sender {

     NSLog(@"button from first ViewController clicked");

     self.firstViewController = [[FirstViewController 
     alloc]initWithNibName:@"FirstViewController" bundle:nil];
     self.mainWindow.contentView = [self.firstViewController view];

}


@end

好吧,任何人都可以帮助我,我只需要一个视图应用程序,在第一个viewController上显示第一个带有按钮的ViewController,它带我到第二个视图控制器,第二个按钮带我回到我的第一个viewcontroller。 ..我已经花了一个多星期的时间......徒劳...... PS:我不想在mainMenu.xib窗口上显示任何按钮,也不需要标签。

3 个答案:

答案 0 :(得分:4)

这是我的问题的解决方案。

以下是AppDelegate.h的代码:

  //  AppDelegate.h


 #import <Cocoa/Cocoa.h>
 #import "FirstViewController.h"
 #import "SecondViewController.h"

 //We need to declare the AppDelegate class as being the delegate for both 
 //FirstViewController and SecondViewController

 @interface AppDelegate : NSObject <NSApplicationDelegate, 
 FirstViewControllerDelegate, SecondViewControllerDelegate>

 @property (strong, nonatomic) NSWindow *window;
 @property (strong) FirstViewController *firstViewController;
 @property (strong) SecondViewController *secondViewController;

 -(void) goToSecondView;
 -(void) goToFirstView;

 @end

现在,这是AppDelegate.m:

 //  AppDelegate.m

 #import "AppDelegate.h"


 @implementation AppDelegate

 @synthesize window = _window;
 @synthesize firstViewController;
 @synthesize secondViewController;

 -(void) awakeFromNib {

 [self goToFirstView];
 self.firstViewController.delegate = self;

 }


 -(void) goToSecondView {

        if (self.secondViewController ==nil) {
            self.secondViewController =[[SecondViewController alloc] 
            initWithNibName:@"SecondViewController" bundle:nil];
        }

        self.window.contentView = [self.secondViewController view];
  }

 -(void) goToFirstView {

 if (self.firstViewController ==nil) {
     self.firstViewController =[[FirstViewController alloc] 
     initWithNibName:@"FirstViewController" bundle:nil];
   }

    self.window.contentView = [self.firstViewController view];

 }

 @end

接下来,我们需要在FirstViewController和SecondViewController

中设置委托
//  FirstViewController.h

#import <Cocoa/Cocoa.h>
#import "SecondViewController.h"

//We declare the delegation protocole:

@protocol FirstViewControllerDelegate <NSObject>

-(void)goToSecondView;

@end

@interface FirstViewController : NSViewController

- (IBAction)firstViewControllerButtonClicked:(id)sender;

@property (nonatomic, strong) id <FirstViewControllerDelegate> delegate;

@end

这是FirstViewController.m:

 //  FirstViewController.m

 #import "FirstViewController.h"

 @implementation FirstViewController
 @synthesize delegate;

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

    self.delegate = [NSApp delegate];

    }

   return self;
 }

 - (IBAction)firstViewControllerButtonClicked:(id)sender {

   NSLog(@"button from first View Controller clicked");

   if ([self.delegate respondsToSelector:@selector(goToSecondView)]) {
    [self.delegate goToSecondView];
   }
 }

 @end

现在,SecondViewController也是如此:

 //  SecondViewController.h

 #import <Cocoa/Cocoa.h>

 @protocol SecondViewControllerDelegate <NSObject>

 -(void)goToFirstView;

 @end

 @interface SecondViewController : NSViewController

 @property (nonatomic, strong) id <SecondViewControllerDelegate> delegate;

 - (IBAction)goToFirstViewControllerButtonClicked:(id)sender;

 @end

这是SecondViewController.m:

  //  SecondViewController.m

  #import "SecondViewController.h"

  @interface SecondViewController ()

  @end

  @implementation SecondViewController

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

      self.delegate = [NSApp delegate];
   }

    return self;
  }

  - (IBAction)goToFirstViewControllerButtonClicked:(id)sender {

    NSLog(@"button from Second View Controller clicked");

    if ([self.delegate respondsToSelector:@selector(goToFirstView)]) {
    [self.delegate goToFirstView];
  }

 }
 @end

嗯,我想这段代码可能会有所改进,如果您有任何建议,请随时告诉我。希望它能帮助别人。

答案 1 :(得分:1)

问题:当用户按下View2中的按钮时,您希望显示View1。不是。

步骤1:您说按钮在AppController上调用操作。在该操作中设置断点(或添加诊断日志),只是为了验证它实际上是否被调用。

第2步:准确地思考你想要采取什么行动。我的猜测是你要隐藏View2并显示View1。也许

 [view2 setHidden: YES];
 [view1 setHidden: NO];

(当然,我不是在这里使用你的名字。)或者你可以为过渡设置动画,交叉淡化视图或移动它们。

第3步:我的猜测是第2步将解决您的问题。如果没有,请再次使用调试器来验证view1和view2不为null。 (如果它们是空的,你可能有弱变量,你需要它们变强。)

步骤4:万一你仍然卡住,检查view1和view2的帧。也许view1不在你想象的地方。

步骤5:如果您仍然卡住,请检查view1的alphaValue。也许你将它设置为透明,并且它在正确的位置透明地绘制。

第6步:我打赌没有第6步!

答案 2 :(得分:0)

目前这不是一个很好的答案,但是我对你想要与你合作的代码有些担忧。

  • 您确定已在Interface Builder中连接了出口和操作。请验证这一点。

  • 您不需要mainWindow,因为已经有window属性指向主窗口(在Interface Builder中验证)。这看起来也错了:

    @synthesize mainWindow = mainwindow;
                                 ^
                                 W
    

    所以转储它并使用Xcode提供的现有window插座。

  • 如果视图控制器已经存在,请不要重新创建它们:

    if (self.secondViewController == nil)
    {
        self.secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController"
                                                                           bundle:nil];
    }
    self.window.contentView = self.secondViewController.view;