NSAlert不使用NSTextField

时间:2014-09-02 22:24:41

标签: objective-c xcode macos cocoa nsalert

我有一个带有NSView附件视图的NSAlert,它包含两个NSTextField。我可以将光标放在NSTextField中,但我无法输入它们。相反,它将输入我在Xcode中输入的最后一行。我正在使用Xcode 6。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    NSAlert *passRequest = [[NSAlert alloc] init];
    [passRequest setMessageText:@"Finder wants to restart. Type your       password to allow this."];
    [passRequest addButtonWithTitle:@"OK"];
    [passRequest addButtonWithTitle:@"Cancel"];
    [passRequest setAccessoryView:[InputView inputViewWithUsername:@"James Pickering"]];

    NSImage *lockImage = [[NSImage alloc] initWithContentsOfFile:@"LOCK_YOSEMITE.png"];
    [passRequest setIcon:lockImage];
    [passRequest runModal];
}

我确实实现了LSUIElement键,但在此之前它还没有正常运行。否则,它是开箱即用的可可应用程序。

这是我的InputView代码:

#import "InputView.h"

@interface InputView ()

@property (strong, nonatomic) NSString *username;

@end

@implementation InputView

+ (InputView *)inputViewWithUsername:(NSString *)username {
    InputView *view = [[self alloc] initWithFrame:NSRectFromCGRect(CGRectMake(0, 0, 321, 52))];
    [view setUsername:username];
    return view;
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    NSTextField *usernameLabel = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(0, 32, 71, 17))];

    [usernameLabel setStringValue:@"Username:"];
    [[usernameLabel cell] setBordered:NO];
    [[usernameLabel cell] setBezeled:NO];

    [usernameLabel setEditable:NO];
    [usernameLabel setSelectable:NO];
    [usernameLabel setBackgroundColor:[NSColor clearColor]];
    [usernameLabel setFont:[NSFont systemFontOfSize:13]];
    [self addSubview:usernameLabel];

    NSTextField *passwordLabel = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(2, 2, 69, 17))];

    [passwordLabel setStringValue:@"Password:"];
    [[passwordLabel cell] setBordered:NO];
    [[passwordLabel cell] setBezeled:NO];

    [passwordLabel setEditable:NO];
    [passwordLabel setSelectable:NO];
    [passwordLabel setBackgroundColor:[NSColor clearColor]];
    [passwordLabel setFont:[NSFont systemFontOfSize:13]];
    [self addSubview:passwordLabel];

    NSTextField *usernameInput = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(77, 30, 206, 22))];

    [usernameInput setStringValue:self.username];
    [usernameInput setFont:[NSFont systemFontOfSize:13]];
    [self addSubview:usernameInput];

    NSTextField *passwordInput = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(77, 0, 206, 22))];

    [passwordInput setFont:[NSFont systemFontOfSize:13]];
    [self addSubview:passwordInput];
}

@end

1 个答案:

答案 0 :(得分:0)

  

我在int main中调用此函数。

这是你的问题。警报需要设置完整的应用程序并运行其事件循环。为了输入它,它将需要是活动的应用程序。

你应该从Xcode的模板创建一个普通的应用程序。从那开始。让事情在那里工作。您可以在连接到菜单项或窗口中的按钮或其他任何内容的操作方法中显示警报。 (我想你也可以在-applicationDidFinishLaunching: app委托方法中出现。)

在你完成这项工作之后,如果有某种原因你需要在异常的环境中工作(例如命令行工具),你可以继续工作。


您正在修改-drawRect:方法内的视图层次结构。你不能这样做。

首先,-drawRect:可能会在视图的整个生命周期中多次调用,并且每次绘制 时都会添加子视图 。越来越多的子视图,一遍又一遍。

其次,即使您第一次小心添加它们,-drawRect:也是用于绘图而不是用于更改视图层次结构。 (如果您需要在绘图之前进行此类更改,则-viewWillDraw,但我认为这也不适用于此情况。)

您可以改为覆盖-initWithFrame:替换子视图。

顺便说一下,您应该使用NSMakeRect()代替NSRectFromCGRect(CGRectMake(...))