0

我有一个带有 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
4

1 回答 1

0

我在 int main 中调用这个函数。

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

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

在你完成这项工作之后,如果出于某种原因你需要它在不寻常的环境中工作(例如命令行工具),你可以处理它。


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

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

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

您可以在替代中添加子视图-initWithFrame:

顺便说一句,您可能应该使用NSMakeRect()而不是NSRectFromCGRect(CGRectMake(...)).

于 2014-09-03T04:19:51.900 回答