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------------