macOS UI 发讯息至通知中心显示

发讯息至通知中心显示

OSX 10.9 系统内建

早期要让应用程式在完成某些事项时自动跳出一个提示讯息告知使用者应用程式的状态都是自行设计,但讯息可能会干扰使用者操作,后来有Growl这个Framework来完成提示讯息显示,这讯息会在萤幕右上角浮动的方式显示,不过OSX 10.8后就系统就新增这功能,所以在使用上面就有两种选择,此篇是以内建的通知中心来说明如何使用。

通知类型

通知显示的方式总共有三种,不管程式最后怎么显示,最后互动的通知显示会依据下图您选择的方式产生显示的结果:

实际说明三种显示差异:

通知的资讯不会使用跳出视窗显示,所有的讯息都会显示在通知中心的列表中

横幅

会使用跳出视窗方式显示,但不与使用者产生互动的操作

提示

使用跳出视窗方式显示,并且依照程式设定会有输入、按键方式立即在跳出视窗中操作

后面会利用程式将最简单的直接将讯息显示至通知中心的方式说明之外,还会提供如何产生有回复功能直接在显示讯息中输入讯息。

通知中心物件

通知中心使用NSUserNotificationCenter物件来管理,然而每一个讯息为NSUserNotification物件组成,当你用滑鼠点击讯息或是按键时,它另外有NSUserNotificationCenterDelegate的Delegate来回应,共有三个Deletgate:

  • (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification 讯息已发送时会引发此Delegate

  • (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification 讯息已经显示后,使用者用滑鼠点击显示讯息时引发此Delegate,另外也使用此Delegate来判断使用者按下的按键类型

  • (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification 根据返回值YESNO来决定是否要强制讯息用显示视窗方式显示,一般有用到横幅提示必需要返回YES

发送简单讯息

不管将前面说提到的通知类型设定是如何,使用下面的程式依然能将讯息显示在通知中心的列表中

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

发送跳出视窗显示讯息

跳出视窗显示讯息必需要将通知类型设定为横幅后就能将前面程式的讯息内容多增加一个跳出视窗显示的功能,通知中心列表中一样还是会显示出讯息

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

发送具有按键功能的讯息

要呈现此功能必需要将通知类型设定为提示后就能将程式显示的讯息内容多增加一个跳出视窗显示及按键的功能,当然通知中心列表中一样还是会显示出讯息

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

自订按键名称

这类具有按键功能可以自定确定的名称,在程式中将这确定功能叫做ActionButton,当你有设定它的名称时,那原本显示的按键就会被取代成你设定的名称:

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    notification.actionButtonTitle = @"OK";
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

除了能改变此按键外,你也可以改变原本的关闭的按键名称,此按键最主要是将显示视窗关闭:

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    notification.otherButtonTitle = @"Other Button";
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

当然一次改变两个也是可以:

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    notification.actionButtonTitle = @"OK";
    notification.otherButtonTitle = @"Other Button";
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

看完以上程式后是否会了解到显示视窗方式总共会有两个按键功能,上方按键功能为关闭功能,按下不做其他动作,下方按键功能为确定,具有能捕抓到使用者是否按键确定键的功能

取得按键

取得按键是依照显示视窗的类型来决定按下按键时回传按键类型为何,前面所提到的则是按下确定键,程式中称为ActionButton,当你按下显示视窗的显示或是前面自订的OK就会回传NSUserNotificationActivationTypeActionButtonClicked下面程式根据按键类型捕抓并印出来:

//-----------start-----------
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
    NSLog(@"使用者点击了通知!");

    switch (notification.activationType) {
        case NSUserNotificationActivationTypeNone:
            NSLog(@"NSUserNotificationActivationTypeNone");
            break;
        case NSUserNotificationActivationTypeContentsClicked:
            NSLog(@"NSUserNotificationActivationTypeContentsClicked");
            break;
        case NSUserNotificationActivationTypeActionButtonClicked:
            NSLog(@"NSUserNotificationActivationTypeActionButtonClicked");
            break;
        case NSUserNotificationActivationTypeReplied:
            NSLog(@"NSUserNotificationActivationTypeReplied");
            break;
        default:
            break;
    }

}
//------------end------------

程式中有几种类型,但这几种类型为特定情况下才发生的,下面以图示直接说明:

发送具有回复按键功能的讯息

要跳出视窗显示讯息及按键功能必需要将通知类型设定为提示后就能将程式显示的讯息内容多增加一个跳出视窗显示及按键的功能,除此之外要将按键功能具有回复按键要利用程式将功能开启,当然通知中心列表中一样还是会显示出讯息

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    notification.hasReplyButton = YES;//开启 回复 功能
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

取得回复内容

当按下回复功能时会有输入框让您输入文字,按下Enter后会引发Delegate,再照前面提到的方式来取得按下的类型是否为NSUserNotificationActivationTypeReplied并将内容印出,修改一下之前取得按键的方式:

//-----------start-----------
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
    NSLog(@"使用者点击了通知!");

    switch (notification.activationType) {
        case NSUserNotificationActivationTypeNone:
            NSLog(@"NSUserNotificationActivationTypeNone");
            break;
        case NSUserNotificationActivationTypeContentsClicked:
            NSLog(@"NSUserNotificationActivationTypeContentsClicked");
            break;
        case NSUserNotificationActivationTypeActionButtonClicked:
            NSLog(@"NSUserNotificationActivationTypeActionButtonClicked");
            break;
        case NSUserNotificationActivationTypeReplied:
            NSLog(@"NSUserNotificationActivationTypeReplied");
            NSLog(@"%@",notification.response.string);//印出输入内容
            break;
        default:
            break;
    }

}
//------------end------------

输出结果:

输入内容提示

某此情况下可能会在输入框中显示提示讯息,

程式中利用NSUserNotification物件的responsePlaceholder method:

//-----------start-----------
    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    notification.hasReplyButton = YES;
    notification.responsePlaceholder = @"123456";//输入内容提示
    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
//------------end------------

以上内容一路看下来应该了解在通知中心传送讯息的方法,下面贴出带有回复功能的提示视窗的程式:

//-----------start-----------
- (IBAction)postAMessageButton:(id)sender {

    NSUserNotification *notification = [[NSUserNotification alloc] init];
    notification.title = @"标题";
    notification.subtitle = @"小标题";
    notification.informativeText = @"详细内容说明";
    notification.hasReplyButton = YES;


    [[NSUserNotificationCenter defaultUserNotificationCenter]  deliverNotification:notification];
    [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];

}

- (void)userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
    NSLog(@"通知已经发送!");
    //NSLog(@"%ld",notification.activationType);
}

- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
    NSLog(@"使用者点击了通知!");

    switch (notification.activationType) {
        case NSUserNotificationActivationTypeNone:
            NSLog(@"NSUserNotificationActivationTypeNone");
            break;
        case NSUserNotificationActivationTypeContentsClicked:
            NSLog(@"NSUserNotificationActivationTypeContentsClicked");
            break;
        case NSUserNotificationActivationTypeActionButtonClicked:
            NSLog(@"NSUserNotificationActivationTypeActionButtonClicked");
            break;
        case NSUserNotificationActivationTypeReplied:
            NSLog(@"NSUserNotificationActivationTypeReplied");
            NSLog(@"%@",notification.response.string);
            break;
        default:
            break;
    }

}

- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification
{
    return YES;
}
//------------end------------