Objective c 如何从其他类访问NSView

Objective c 如何从其他类访问NSView,objective-c,macos,class,nsview,nsviewcontroller,Objective C,Macos,Class,Nsview,Nsviewcontroller,在我开始之前,我是一个初学者,所以请不要压倒我。尽管我可能和你一起做了对不起:/ 所以基本上我有一个主视图NSView,我正在加载其他视图。所以我的awakeFromNib方法工作了,它将我的开始菜单视图主菜单加载到一个tic-tac-toe游戏中。菜单上有一个单人和一个双人按钮,根据我单击的按钮,我希望程序加载更多视图 所以我有一个AppController类,它控制通过setViewController方法加载哪些视图。问题是,我还没有找到一种方法将“开始”菜单视图中的按钮连接到AppCon

在我开始之前,我是一个初学者,所以请不要压倒我。尽管我可能和你一起做了对不起:/

所以基本上我有一个主视图NSView,我正在加载其他视图。所以我的awakeFromNib方法工作了,它将我的开始菜单视图主菜单加载到一个tic-tac-toe游戏中。菜单上有一个单人和一个双人按钮,根据我单击的按钮,我希望程序加载更多视图

所以我有一个AppController类,它控制通过setViewController方法加载哪些视图。问题是,我还没有找到一种方法将“开始”菜单视图中的按钮连接到AppController类。因此,我认为如果在开始菜单类中创建一个AppController类型的对象,然后在按下单人或双人播放器按钮时调用setViewController方法,它会相应地更改视图,但结果证明它没有任何作用。但是,当我在AppController类中调用setViewController方法时,它确实起作用。因此,我认为问题必须是从类外访问视图,但我可能错了。任何帮助都将不胜感激,我花了很多时间试图弄明白这一点,但我尝试过的任何事情都没有任何运气。这是我的AppController类和我的开始 屏幕类

AppController.h:

@interface AppController : NSObject

@property (weak) IBOutlet NSView *mainMenu;
@property (strong) NSViewController *mainViewController;

-(void)setViewController:(NSInteger)viewNumber;

@end
@interface StartScreenViewController : NSViewController

- (IBAction)OnePlayer:(id)sender;
- (IBAction)TwoPlayer:(id)sender;

@end
AppController.m:

@implementation AppController

@synthesize mainMenu = _mainMenu;
@synthesize mainViewController =_mainViewController;

NSString *const kStartScreen = @"StartScreenViewController";
NSString *const kOnePlayerMenu = @"OnePlayerMenuViewController";
NSString *const kTwoPlayerMenu = @"TwoPlayerMenuViewController";
int test = 0;

enum{
    kStartScreenView = 0,
    kOnePlayerView,
    kTwoPlayerView
};


-(void)awakeFromNib
{
    [self setViewController:0];
}


-(void)setViewController:(NSInteger)viewNumber
{
    [[_mainViewController view] removeFromSuperview];

    if(viewNumber==kStartScreenView)
    {
        self.mainViewController = [[StartScreenViewController alloc] initWithNibName:
                                    kStartScreen bundle:nil];

    }
    else if(viewNumber==kOnePlayerView)
    {
        self.mainViewController = [[OnePlayerMenuViewController alloc] initWithNibName:
                                    kOnePlayerMenu bundle:nil];
    }
    else if(viewNumber==kTwoPlayerView)
    {
        self.mainViewController = [[TwoPlayerMenuViewController alloc] initWithNibName:
                                   kTwoPlayerMenu bundle:nil];
    }

    [_mainMenu addSubview:[_mainViewController view]];
    [[_mainViewController view] setFrame:[_mainMenu bounds]];
}
@end
@interface StartScreenViewController ()

@end

@implementation StartScreenViewController

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

    }
    return self;
}

- (IBAction)OnePlayer:(id)sender
{
    AppController *appControllerObj = [[AppController alloc] init];
    [appControllerObj setViewController:1];
}

- (IBAction)TwoPlayer:(id)sender
{
    AppController *appControllerObj = [[AppController alloc] init];
    [appControllerObj setViewController:2];
}


@end
StartScreenViewController.h:

@interface AppController : NSObject

@property (weak) IBOutlet NSView *mainMenu;
@property (strong) NSViewController *mainViewController;

-(void)setViewController:(NSInteger)viewNumber;

@end
@interface StartScreenViewController : NSViewController

- (IBAction)OnePlayer:(id)sender;
- (IBAction)TwoPlayer:(id)sender;

@end
StartScreenViewController.m:

@implementation AppController

@synthesize mainMenu = _mainMenu;
@synthesize mainViewController =_mainViewController;

NSString *const kStartScreen = @"StartScreenViewController";
NSString *const kOnePlayerMenu = @"OnePlayerMenuViewController";
NSString *const kTwoPlayerMenu = @"TwoPlayerMenuViewController";
int test = 0;

enum{
    kStartScreenView = 0,
    kOnePlayerView,
    kTwoPlayerView
};


-(void)awakeFromNib
{
    [self setViewController:0];
}


-(void)setViewController:(NSInteger)viewNumber
{
    [[_mainViewController view] removeFromSuperview];

    if(viewNumber==kStartScreenView)
    {
        self.mainViewController = [[StartScreenViewController alloc] initWithNibName:
                                    kStartScreen bundle:nil];

    }
    else if(viewNumber==kOnePlayerView)
    {
        self.mainViewController = [[OnePlayerMenuViewController alloc] initWithNibName:
                                    kOnePlayerMenu bundle:nil];
    }
    else if(viewNumber==kTwoPlayerView)
    {
        self.mainViewController = [[TwoPlayerMenuViewController alloc] initWithNibName:
                                   kTwoPlayerMenu bundle:nil];
    }

    [_mainMenu addSubview:[_mainViewController view]];
    [[_mainViewController view] setFrame:[_mainMenu bounds]];
}
@end
@interface StartScreenViewController ()

@end

@implementation StartScreenViewController

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

    }
    return self;
}

- (IBAction)OnePlayer:(id)sender
{
    AppController *appControllerObj = [[AppController alloc] init];
    [appControllerObj setViewController:1];
}

- (IBAction)TwoPlayer:(id)sender
{
    AppController *appControllerObj = [[AppController alloc] init];
    [appControllerObj setViewController:2];
}


@end

事实上,我猜出来了,您所要做的就是在AppController中创建一个类方法,它将使用的对象self存储为类变量。然后您可以从任何地方访问该对象。这可能不是最有效的方法,我不知道,因为我只是一个初学者,但它对我有效D

以下是相关代码:

-(void)awakeFromNib
{
   [self setViewController:kStartScreenView];
   viewObject = self;
}

+(id)getViewObject
{
    return viewObject;
}

viewObject被定义为id类型的类变量。

为什么要分配多个AppController?似乎一个应用程序中应该只有一个AppController;是的,idk,但我解决了它,仍然在寻找答案按钮。。哈哈,刚刚加入这个网站,但是谢谢:我不是只有一个appcontroller吗?如果你有一个在那里,那么nib会创建一个,然后你每次在StartScreenViewController中调用alloc时都会创建一个新的。啊,好的,我不知道,谢谢!