LoginSignup
0
0

NSAlertの使い方

Last updated at Posted at 2023-05-22

概要

  • SwiftUIでアラートといえばalert(_:isPresented:actions:message:)を使用しますが、細かい調整のためNSAlertを使いたい場面があり、そのときの忘備録です。

OK

Button {
    let alert = NSAlert()
    alert.messageText = "Title"
    alert.informativeText = "message"
    alert.addButton(withTitle: "OK")
    _ = alert.runModal()
} label: {
    Text("OK")
}

OK / Cancel

Button {
    let alert = NSAlert()
    alert.messageText = "Title"
    alert.informativeText = "message"
    alert.addButton(withTitle: "OK")
    alert.buttons[0].tag = NSApplication.ModalResponse.OK.rawValue
    alert.addButton(withTitle: "Cancel")
    alert.buttons[1].tag = NSApplication.ModalResponse.cancel.rawValue
    let result = alert.runModal()
    if result == .OK {
        print("tapped: OK")
    } else if result == .cancel {
        print("tapped: Cancel")
    } else {
        print("tapped: Unknown")
    }
} label: {
    Text("Cancel / OK")
}

Delete / Cancel

Button {
    let alert = NSAlert()
    alert.messageText = "Title"
    alert.informativeText = "message"
                    
    alert.addButton(withTitle: "Cancel")
    alert.buttons[0].tag = NSApplication.ModalResponse.cancel.rawValue
    
    alert.addButton(withTitle: "Delete")
    alert.buttons[1].hasDestructiveAction = true
    
    let result = alert.runModal()
    if result == .cancel {
        print("tapped: Cancel")
    } else if result == .alertSecondButtonReturn {
        print("tapped: Delete")
    } else {
        print("tapped: Unknown")
    }
} label: {
    Text("Cancel / Delete")
}

3つ以上のボタン

Button {
    let alert = NSAlert()
    alert.messageText = "Title"
    alert.informativeText = "message"
    alert.addButton(withTitle: "First")
    alert.addButton(withTitle: "Second")
    alert.addButton(withTitle: "Third")
    let result = alert.runModal()
    
    switch result {
    case .alertFirstButtonReturn:
        print("tapped: First")
    case .alertSecondButtonReturn:
        print("tapped: Second")
    case .alertThirdButtonReturn:
        print("tapped: Third")
    default:
        print("tapped: Unknown")
    }
} label: {
    Text("First / Second / Third")
}
  • またボタンが4つ以上ある場合は下記の見た目になる(macOS 13)

ボタンのキー設定

  • ボタンが2つあるとき、デフォルトでは左のボタンにEsc、右のボタンにEnterが割り当てられているよう。
  • またキーは以下のように設定できる。
alert.buttons[0].keyEquivalent = "\r"  // Enter
alert.buttons[0].keyEquivalent = "\u{1b}"  // Esc

ボタン押下時にアラートを表示したままにする

  • NSAlertダイアログのボタンを押下すると、ダイアログは終了してしまう。
  • そこでtargetを設定すると表示したままにできる。
  • またSwiftUIのViewはtargetに指定できないため、NSObjectを継承させたAlertManagerを定義してそこで処理を行っている。

May-22-2023 12-36-58

struct ContentView: View {
    
    let alertManager = AlertManager()
    
    var body: some View {
        VStack {
            Button {
                alertManager.handleAlertButtonTapped()
            } label: {
                Text("First / Second / OK")
            }
        }
        .padding()
    }
}
class AlertManager: NSObject {
    
    func handleAlertButtonTapped() {
        let alert = NSAlert()
        alert.messageText = "Title"
        alert.informativeText = "message"
        alert.addButton(withTitle: "First")
        alert.buttons[0].target = self
        alert.buttons[0].action = #selector(self.handleFirstButtonTapped)
        alert.buttons[0].keyEquivalent = ""
        
        alert.addButton(withTitle: "Second")
        alert.buttons[1].target = self
        alert.buttons[1].action = #selector(self.handleSecondButtonTapped)
        
        alert.addButton(withTitle: "OK")
        alert.buttons[2].keyEquivalent = "\r"
        let result = alert.runModal()
        
        switch result {
        case .alertThirdButtonReturn:
            print("tapped: OK")
        default:
            print("tapped: Unknown")
        }
    }
    
    @objc func handleFirstButtonTapped() {
        print("handleFirstButtonTapped")
    }
    
    @objc func handleSecondButtonTapped() {
        print("handleSecondButtonTapped")
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0