objective-c:单击按钮时向窗口添加视图

时间:2010-12-11 13:11:08

标签: objective-c xcode view

我是Objective-c的新手,所以请耐心等待。这看起来很简单,但我一定做错了。在IB中我创建了一个对象,称为AppController,然后添加了一个名为makeView和两个IBOutlets的动作,btnMakeView和mainWin,然后正确连接所有内容并从中编写类文件。

在AppController.h中我有这段代码:

#import <Cocoa/Cocoa.h>
@interface AppController : NSObject {
    IBOutlet NSWindow * mainWin;
    IBOutlet id btnMakeView;
}
- (IBAction)makeView:(id)sender;
@end

在AppController.m中这段代码:

#import "AppController.h"
#import "ViewController.h"
@implementation AppController
- (IBAction)makeView:(id)sender {

    //declare a new instance of viewcontroller, which inherits fromNSView, were going to allocate it with 
    //a frame and set the bounds of that frame using NSMakeRect and the floats we plug in.
    ViewController* testbox = [[ViewController alloc]initWithFrame:NSMakeRect(10.0, 10.0, 100.0, 20.0)];

    //this tells the window to add our subview testbox to it's contentview
    [[mainWin contentView]addSubview:testbox];
}
-(BOOL)isFlipped {
    return YES;
}
@end
ViewController.h中的

我有这段代码:

#import <Cocoa/Cocoa.h>
@interface ViewController : NSView {
}
@end

最后在ViewController.m中我有这段代码:

#import "ViewController.h"

@implementation ViewController    
- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
    }
    return self;
}

- (void)drawRect:(NSRect)rect {
    // Drawing code here.

    //sets the background color of the view object
    [[NSColor redColor]set];

    //fills the bounds of the view object with the background color
    NSRectFill([self bounds]);
}

@end

编译很好,没有错误,但没有得到一个对象,我假设它将是一个矩形,从x,y 10/10开始,为100x20。我做错了什么?

1 个答案:

答案 0 :(得分:5)

mainWin是否引用了有效窗口?除此之外,您的代码可以正常运行,但它可以使用一些改进。例如,

  • ViewController是一个视图,而不是控制器,所以它不应该被命名为控制器。
  • 你有内存泄漏。您永远不会释放您创建的ViewControllermemory management rules are very simple;阅读它们。

尝试以下更改。首先,将ViewController重命名为RedView(或SolidColorView或某些人)。您可以通过refactoringright-click @interface@implementation声明中的类名简单地执行此操作,然后选择“重构...”。

在RedView.m中:

- (id)initWithFrame:(NSRect)frame {
    // the idiom is to call super's init method and test self all in the
    // same line. Note the extra parentheses around the expression. This is a 
    // hint that we really want the assignment and not an equality comparison.
    if ((self = [super initWithFrame:frame])) {
        // Initialization code here.
    }
    return self;
}

在AppController.m中:

- (IBAction)makeView:(id)sender {
    //declare a new instance of viewcontroller, which inherits fromNSView, were going to allocate it with 
    //a frame and set the bounds of that frame using NSMakeRect and the floats we plug in.
    RedView* testbox = [[RedView alloc] initWithFrame:NSMakeRect(10.0, 10.0, 100.0, 20.0)];

    //this tells the window to add our subview testbox to it's contentview
    // You don't need to keep a reference to the main window. The application already
    // does this. You might forget to hook up mainWin, but the following won't fail
    // as long as the app has a main window.
    [[[[NSApplication sharedApplication] mainWindow] contentView] addSubview:testbox];
    // We're done with testbox, so release it.
    [testbox release];
}