我是可可的新手。我想在可可中创建一个与 iOS 中相同的消息框,没有任何按钮。 NSTimer 之后消息框自动关闭。我使用下面的代码,但它总是添加“确定”按钮。
alert = [[[NSAlert alloc] init] autorelease];
// [alert addButtonWithTitle: @"OK"];
[alert setMessageText: @"Attention!!! This a critical Alert."];
[alert setInformativeText:@"Scanning..."];
[alert setAlertStyle: NSInformationalAlertStyle];
NSTimer *myTimer = [NSTimer timerWithTimeInterval: 17.0
target:self
selector: @selector(killWindow:) userInfo:nil
repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSModalPanelRunLoopMode];
int choice = 0;
choice = [alert runModal];
if(choice != 0)
[myTimer invalidate];
KillWindow函数:
-(void) killWindow: (NSTimer *) theTimer
{
NSLog(@"killWindow");
[[alert window] close];
}
当警报关闭时,我的应用程序无法单击任何按钮或交互?
也许在2013年答案是否定的。然而,在当前的 SDK (Xcode 7.0 with OS X 10.11) 中,您可以简单地通过 addButtonWithTitle("") 添加“”,然后按钮将不会显示。
是的,你可以,你添加新按钮。之后,你得到它并隐藏它:)。我的代码
NSAlert* alert = [[NSAlert alloc] init];
[alert setMessageText:@"Loading...."];
[alert addButtonWithTitle:@"Cancel"];
NSButton *button = [[alert buttons] objectAtIndex:0];
[button setHidden:YES];
[alert setAccessoryView:[self viewLoadingReadFile]];
[alert setAlertStyle:NSWarningAlertStyle];
[alert runModal];
NSAlert 设计用于应用程序或窗口模式显示消息,并带有用于用户关闭的按钮。 它不是为显示没有按钮的窗口而设计的;你不应该这样使用它。
您应该使用自定义 NSWindow/NSPanel。 如果您希望它阻止窗口/应用程序,那么您将需要运行自己的模式会话。 除了像上面那样关闭窗口之外,还可以使用
abortModal
从计时器回调中停止模态会话。 这解释了为什么当警报关闭时您没有收到任何进一步的事件 - 模式会话仍在运行。
请参阅模态窗口如何工作了解更多信息。
MBProgressHUD
。我使用MBProgressHUD
解决这个问题。
+ (void)showMessage:(NSString *)message forDuration:(NSTimeInterval)duration withTitle:(NSString *)title
{
UIWindow *window = [UIApplication sharedApplication].keyWindow;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
hud.mode = MBProgressHUDModeText;
hud.labelText = title;
hud.detailsLabelText = message;
hud.removeFromSuperViewOnHide = YES;
[hud hide:YES afterDelay:duration];
}
经过一些用户测试,确定用户不喜欢他们无法忽略的长时间消息。
+ (void)showMessage:(NSString *)message forDuration:(NSTimeInterval)duration withTitle:(NSString *)title
{
if (duration < 3.0) {
UIWindow *window = [UIApplication sharedApplication].keyWindow;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
hud.mode = MBProgressHUDModeText;
hud.labelText = title;
hud.detailsLabelText = message;
hud.removeFromSuperViewOnHide = YES;
[hud hide:YES afterDelay:duration];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
int64_t delayInSeconds = duration;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[alertView dismissWithClickedButtonIndex:alertView.cancelButtonIndex animated:YES];
});
}
}
关闭警报窗口后,您还必须使用 [NSApp abortModal] 中止模式
现在只需隐藏该按钮即可。为此,在实例化警报后,您可以在所有alert.window.contentView.subviews中扫描标题为“OK”的 NSButton 并将其隐藏。
免责声明:这是一个快速、丑陋的黑客攻击,但它目前有效。使用需要您自担风险
在 MacOS 解决方案中添加一个 Swift,基于 @Lê Tấn Thành
的想法func showAlertOnTask(task: @escaping () -> Any, alert_msg: String, parent_window:NSWindow) {
let alert = NSAlert()
alert.alertStyle = NSAlert.Style.warning
alert.messageText = alert_msg
alert.addButton(withTitle: "OK")
let btn = alert.buttons[0]
btn.isHidden = true
DispatchQueue.main.async {
task()
alert.window.close()
}
alert.beginSheetModal(for: parent_window) // you can change to alert.runModal()
}
例如,当按下 GUI 中的按钮(让我们将其参数名称称为
btnLoad
)时,您会运行一个很长的任务。按钮操作将调用函数 long_task()
@IBAction func generate_plist(_ sender: Any) {
showAlertOnTask(task: long_task(), alert_msg: "Loading...", parent_window: self.btnLoad.window!)
}