5

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

这就是我所做的。

我有 2 个视图控制器和 MainMenu.xib 的窗口。我还有一个 AppController,它是两个视图控制器的代表。

当我启动应用程序时,我首先看到 MainMenu.xib 的窗口视图,其中包含一个按钮。单击此按钮时,将向 appController 发送 IBAction 并要求 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 上的按钮,将我带到第二个视图控制器,第二个按钮带我回到我的第一个视图控制器......我'已经花了一个多星期了......徒劳无功...... PS:我不想要mainMenu.xib窗口或选项卡上的任何按钮。

4

3 回答 3

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

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

于 2013-02-20T22:04:45.923 回答
1

问题: 当用户在 View2 中按下按钮时,您希望 View1 出现。它不是。

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

第 2 步:准确地考虑您希望该操作做什么。我的猜测是你想隐藏 View2 并显示 View1。也许

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

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

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

第 4 步:万一您仍然卡住,请检查 view1 和 view2 的框架。也许 view1 不是你想的那样。

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

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

于 2013-02-19T18:07:14.587 回答
0

目前这不是一个很好的答案,但是我对你的代码有些担心,我想和你一起工作。

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

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

    @synthesize mainWindow = mainwindow;
                                 ^
                                 W
    

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

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

    if (self.secondViewController == nil)
    {
        self.secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController"
                                                                           bundle:nil];
    }
    self.window.contentView = self.secondViewController.view;
    
于 2013-02-19T11:30:06.087 回答