macOS警告/提示視圖 — NSAlert、自定義WindowController

系統(tǒng)的NSAlert——系統(tǒng)自帶提示視圖

在'ViewController.swift'文件中,先創(chuàng)建一個(gè)NSAlert實(shí)例來看看~

import Cocoa

class ViewController: NSViewController {

    @objc func clickItem(btn: NSButton) {
        print("clickItem:\(btn.title)")
        
    }
    @objc func showNotice() {
        let alert = NSAlert()
        //添加的前3個(gè)項(xiàng)(按鈕),會(huì)響應(yīng)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法——且枚舉中有對(duì)應(yīng)項(xiàng)進(jìn)行確認(rèn)
        alert .addButton(withTitle: "確定")
        alert .addButton(withTitle: "取消")
        let item3 = alert .addButton(withTitle: "More") //獲取對(duì)應(yīng)的按鈕
        //item3.target = self; item3.action = #selector(clickItem)//重寫方法—覆蓋‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法
        //第4項(xiàng)(按鈕)開始,會(huì)響應(yīng)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法——但枚舉中沒有對(duì)應(yīng)項(xiàng)進(jìn)行確認(rèn)
        let item4 = alert .addButton(withTitle: "第4項(xiàng)")  //獲取對(duì)應(yīng)的按鈕
        //item4.target = self; item4.action = #selector(clickItem)//重寫方法—覆蓋‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法
        let item5 = alert .addButton(withTitle: "第5項(xiàng)")  //獲取對(duì)應(yīng)的按鈕
        //item5.target = self; item5.action = #selector(clickItem)//重寫方法—覆蓋‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法
        alert.messageText = "blabla操作的警告"http://標(biāo)題
        alert.informativeText = "blabla操作會(huì)導(dǎo)致XX后果,是否繼續(xù)?"http://詳細(xì)描述
        //設(shè)置NSAlert的展示風(fēng)格
        alert.alertStyle = NSAlert.Style.critical//warning\informational\critical
        alert .beginSheetModal(for: self.view .window!) { (returnCode: NSApplication.ModalResponse) in
            //點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)
            switch returnCode {
            case .alertFirstButtonReturn:
                print("NSApplication.ModalResponse.alertFirstButtonReturn")
            case .alertSecondButtonReturn:
                print("NSApplication.ModalResponse.alertSecondButtonReturn")
            case .alertThirdButtonReturn:
                print("NSApplication.ModalResponse.alertThirdButtonReturn")
            //以下條件均不會(huì)到達(dá)
            case .stop:
                print("NSApplication.ModalResponse.stop")
            case .abort:
                print("NSApplication.ModalResponse.abort")
            case .`continue`:
                print("NSApplication.ModalResponse.`continue`")
            case .OK:
                print("NSApplication.ModalResponse.OK")
            case .cancel:
                print("NSApplication.ModalResponse.cancel")
            case .continue:
                print("NSApplication.ModalResponse.continue")
            default:
                print("Other situation——default")
                break
            }
        }
        
    }
    func addOneBtn() {//為該window,隨便添加一個(gè)按鈕
        let btn = NSButton(frame: NSMakeRect(100, 100, 100, 100))
        btn.target = self; btn.action = #selector(showNotice)
        self.view .addSubview(btn)
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self .addOneBtn()//添加按鈕
        
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }


}

效果:
1.點(diǎn)擊'Button'按鈕后彈出NSAlert視圖!彈出該NSAlert視圖(除了該NSAlert視圖 進(jìn)行選擇)其他視圖 不能進(jìn)行操作~
2.前3項(xiàng)(按鈕)——點(diǎn)擊第1項(xiàng)('確定')/第2項(xiàng)('取消')/第3項(xiàng)('More')后NSAlert視圖會(huì)消失并打印NSApplication.ModalResponse.alertFirstButtonReturn/NSApplication.ModalResponse.alertSecondButtonReturn/NSApplication.ModalResponse.alertThirdButtonReturn
3.從第4項(xiàng)(按鈕)開始,點(diǎn)擊第4項(xiàng)('第4項(xiàng)')/第5項(xiàng)('第5項(xiàng)')后NSAlert視圖會(huì)消失并都打印Other situation——default

結(jié)論:添加的前3個(gè)項(xiàng)(按鈕),會(huì)響應(yīng)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法——且枚舉中有對(duì)應(yīng)項(xiàng)進(jìn)行確認(rèn)!第4項(xiàng)(按鈕)開始,會(huì)響應(yīng)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法——但枚舉中沒有對(duì)應(yīng)項(xiàng)進(jìn)行確認(rèn)!

Tips:可通過open func addButton(withTitle title: String) -> NSButton方法,獲取該項(xiàng)對(duì)應(yīng)按鈕!對(duì)其按鈕重寫方法覆蓋‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法后,點(diǎn)擊該項(xiàng)后NSAlert視圖不會(huì)消失會(huì)系統(tǒng)默認(rèn)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)方法而是執(zhí)行@objc func clickItem(btn: NSButton)方法)!

公開注釋后的@objc func showNotice()方法:

@objc func showNotice() {
   let alert = NSAlert()
    //添加的前3個(gè)項(xiàng)(按鈕),會(huì)響應(yīng)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法——且枚舉中有對(duì)應(yīng)項(xiàng)進(jìn)行確認(rèn)
    alert .addButton(withTitle: "確定")
    alert .addButton(withTitle: "取消")
    let item3 = alert .addButton(withTitle: "More") //獲取對(duì)應(yīng)的按鈕
    item3.target = self; item3.action = #selector(clickItem)//重寫方法—覆蓋‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法
    //第4項(xiàng)(按鈕)開始,會(huì)響應(yīng)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法——但枚舉中沒有對(duì)應(yīng)項(xiàng)進(jìn)行確認(rèn)
    let item4 = alert .addButton(withTitle: "第4項(xiàng)")  //獲取對(duì)應(yīng)的按鈕
    item4.target = self; item4.action = #selector(clickItem)//重寫方法—覆蓋‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法
   let item5 = alert .addButton(withTitle: "第5項(xiàng)")  //獲取對(duì)應(yīng)的按鈕
    item5.target = self; item5.action = #selector(clickItem)//重寫方法—覆蓋‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)’方法
    alert.messageText = "blabla操作的警告"http://標(biāo)題
    alert.informativeText = "blabla操作會(huì)導(dǎo)致XX后果,是否繼續(xù)?"http://詳細(xì)描述
    //設(shè)置NSAlert的展示風(fēng)格
    alert.alertStyle = NSAlert.Style.critical//warning\informational\critical
    alert .beginSheetModal(for: self.view .window!) { (returnCode: NSApplication.ModalResponse) in
        //點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)
        switch returnCode {
        case .alertFirstButtonReturn:
            print("NSApplication.ModalResponse.alertFirstButtonReturn")
        case .alertSecondButtonReturn:
            print("NSApplication.ModalResponse.alertSecondButtonReturn")
        case .alertThirdButtonReturn:
            print("NSApplication.ModalResponse.alertThirdButtonReturn")
        //以下條件均不會(huì)到達(dá)
        case .stop:
            print("NSApplication.ModalResponse.stop")
        case .abort:
            print("NSApplication.ModalResponse.abort")
        case .`continue`:
            print("NSApplication.ModalResponse.`continue`")
        case .OK:
            print("NSApplication.ModalResponse.OK")
        case .cancel:
            print("NSApplication.ModalResponse.cancel")
        case .continue:
            print("NSApplication.ModalResponse.continue")
        default:
            print("Other situation——default")
            break
        }
    }
    
}

該項(xiàng)對(duì)應(yīng)按鈕的點(diǎn)擊回調(diào)方法:

@objc func clickItem(btn: NSButton) {
    print("clickItem:\(btn.title)")
    
}

效果:
1.點(diǎn)擊'Button'按鈕后彈出NSAlert視圖!彈出該NSAlert視圖(除了該NSAlert視圖 進(jìn)行選擇)其他視圖 不能進(jìn)行操作~
2.前2項(xiàng)(按鈕)——點(diǎn)擊第1項(xiàng)('確定')/第2項(xiàng)('取消')/后NSAlert視圖會(huì)消失并打印NSApplication.ModalResponse.alertFirstButtonReturn/NSApplication.ModalResponse.alertSecondButtonReturn/NSApplication.ModalResponse.alertThirdButtonReturn
3.從第3項(xiàng)(按鈕)開始—對(duì)應(yīng)按鈕添加了action響應(yīng),點(diǎn)擊第3項(xiàng)('More')/第4項(xiàng)('第4項(xiàng)')/第5項(xiàng)('第5項(xiàng)')后NSAlert視圖均不會(huì)消失會(huì)系統(tǒng)默認(rèn)‘點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)方法)并執(zhí)行@objc func clickItem(btn: NSButton)方法后分別打印clickItem:More/clickItem:第4項(xiàng)/clickItem:第5項(xiàng)


NSAlertalertStyle屬性對(duì)應(yīng)的效果——NSAlert.Style.warningNSAlert.Style.informationalNSAlert.Style.critical

NSAlert.Style.warning
NSAlert.Style.informational
NSAlert.Style.critical

由上面代碼可以發(fā)現(xiàn)NSAlert實(shí)例對(duì)象是基于NSWindow對(duì)象創(chuàng)建的!
所以代碼如下:為NSWindow類添加擴(kuò)展(extension)~

 extension NSWindow {
    //創(chuàng)建macOS警告/提示視圖——返回NSApplication.ModalResponse
    public func showAlertNotice(firstItemStr: String, secondItemStr: String, title: String, information: String, alertStyle: NSAlert.Style, completionHalder handler: @escaping ((NSApplication.ModalResponse) -> Void)) {//@escaping——去除“scaping closure captures non-escaping parameter 'handler'”警告
        let alert = NSAlert()
        alert .addButton(withTitle: firstItemStr)
        alert .addButton(withTitle: secondItemStr)
        alert.messageText = title//標(biāo)題
        alert.informativeText = information//詳細(xì)描述
        //設(shè)置NSAlert的展示風(fēng)格
        alert.alertStyle = alertStyle//warning\informational\critical
        alert .beginSheetModal(for: self) { (returnCode: NSApplication.ModalResponse) in
            //點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)
            handler(returnCode)
        }
    }
    //創(chuàng)建macOS警告/提示視圖——返回bool值
    public func showAlertNoticeWithBool(firstItemStr: String, secondItemStr: String, title: String, information: String, alertStyle: NSAlert.Style, completionHalder handler: @escaping ((Bool) -> Void)) {//@escaping——去除“scaping closure captures non-escaping parameter 'handler'”警告
        let alert = NSAlert()
        alert .addButton(withTitle: firstItemStr)
        alert .addButton(withTitle: secondItemStr)
        alert.messageText = title//標(biāo)題
        alert.informativeText = information//詳細(xì)描述
        //設(shè)置NSAlert的展示風(fēng)格
        alert.alertStyle = alertStyle//warning\informational\critical
        alert .beginSheetModal(for: self) { (returnCode: NSApplication.ModalResponse) in
            //點(diǎn)擊選項(xiàng)時(shí)系統(tǒng)的回調(diào)
            if returnCode == .alertFirstButtonReturn {//點(diǎn)擊"確定"
                handler(true)
            } else if returnCode == .alertSecondButtonReturn {//點(diǎn)擊"取消"
                handler(false)
            }
        }
        
    }
}

方法的調(diào)用:在'ViewController.swift'文件中

//返回NSApplication.ModalResponse
self.view.window! .showAlertNotice(firstItemStr: "OK", secondItemStr: "取消", title: "標(biāo)題", information: "警告的提示內(nèi)容和信息", alertStyle: .critical) { (returnCode : NSApplication.ModalResponse) in
    if returnCode == .alertFirstButtonReturn {//點(diǎn)擊"確定"
        print("returnCode == .alertFirstButtonReturn")
        //"確定"相應(yīng)的操作
    } else if returnCode == .alertSecondButtonReturn {//點(diǎn)擊"取消"
        print("returnCode == .alertSecondButtonReturn")
        //"取消"相應(yīng)的操作
    }
}

//返回bool值
self.view.window! .showAlertNoticeWithBool(firstItemStr: "OK", secondItemStr: "取消", title: "標(biāo)題", information: "警告的提示內(nèi)容和信息", alertStyle: .critical) { (isOK: Bool) in
    if isOK == true {//點(diǎn)擊"確定"
        print("isOK == true")
        //"確定"相應(yīng)的操作
    } else {//點(diǎn)擊"取消"
        print("isOK == false")
        //"取消"相應(yīng)的操作
    }
}



自定義WindowController

新建一個(gè)自定義的GYHNoticeAlertWindowController類(需勾選'Also create XIB file for user interface'

勾選'Also create XIB file for user interface'

添加的圖片素材:

圖片素材

在'GYHNoticeAlertWindowController.swift'文件中,進(jìn)行控件UI布局

import Cocoa

class GYHNoticeAlertWindowController: NSWindowController {
    var sureBtn: NSButton!
    var cancelBtn: NSButton!
    
    var _title: String?     //標(biāo)題
    var _message: String?   //提示信息
    var _okStr: String?     //“確定”文字
    var _cancelStr: String? //“取消”文字
    var _backColor: NSColor?//背景色
    convenience init(title: String?, message: String?, backColor: NSColor?, okStr: String?, cancelStr: String?) {
        self.init(windowNibName: "GYHNoticeAlertWindowController")
        
        _title = title != nil ? title : "警告"
        _message = message != nil ? message : "提示信息的內(nèi)容:blabla~"
        _okStr = okStr != nil ? okStr : "確定"
        _cancelStr = cancelStr != nil ? cancelStr : "取消"
        _backColor = backColor != nil ? backColor : NSColor(red: 190/255.0, green: 150/255.0, blue: 125/255.0, alpha: 1.0)
    }
    override func windowDidLoad() {
        super.windowDidLoad()
        
        // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
        //對(duì)窗口(self.window)進(jìn)行配置
        self.window?.isRestorable = false//窗口不可拉伸
        self.window?.titlebarAppearsTransparent = true
        self.window?.title = _title!//標(biāo)題
        self.window?.titleVisibility = NSWindow.TitleVisibility.hidden//隱藏窗口標(biāo)題
        self.window?.styleMask = NSWindow.StyleMask.fullSizeContentView//窗口風(fēng)格:頂部視圖+窗口(融合)
        self.window?.isMovableByWindowBackground = true//點(diǎn)擊背景,可移動(dòng)
        //設(shè)置背景色
        self.window?.contentView?.wantsLayer = true
        self.window?.contentView?.layer?.backgroundColor = _backColor?.cgColor
        //self.window?.contentView?.layer?.cornerRadius = 5.0//無效:切圓角—邊框未隱藏
        
        self .setUpAllViews()
        self .setUpTitleBarV()
        
    }
    func setUpAllViews() {  //視圖布局——"確定"按鈕、"取消"按鈕、提示信息Label
        var window_W = self.window?.frame.size.width;
        window_W = window_W != nil ? window_W : 0.0;
        
        let margin_Of_TwoBtns = (200.0/3600.0)*window_W!;
        //"確定"按鈕
        let sureBtn_W = (1400.0/3600.0)*window_W!;   let sureBtn_X = window_W!/2.0 - margin_Of_TwoBtns/2.0 - sureBtn_W;
        let sureBtn_H = (360.0/3600.0)*window_W!;    let sureBtn_Y = (150.0/3600.0)*window_W!;
        sureBtn = NSButton(frame: NSMakeRect(sureBtn_X, sureBtn_Y, sureBtn_W, sureBtn_H))
        self.window?.contentView?.addSubview(sureBtn)
        sureBtn.title = _okStr!
        sureBtn.alignment = NSTextAlignment.center
        sureBtn.bezelStyle = .circular
        sureBtn.setButtonType(NSButton.ButtonType.switch)//按鈕類型(可多選)
        sureBtn.imagePosition = .imageOverlaps//圖片放在最下面
        sureBtn.imageScaling = .scaleAxesIndependently//圖片自動(dòng)調(diào)整尺寸
        sureBtn.image = NSImage(named: "Item_Button_nor")//圖片——普通狀態(tài)
        sureBtn.alternateImage = NSImage(named: "Item_Button_sel")//圖片——高亮狀態(tài)
        //"取消"按鈕
        let cancelBtn_W = (1400.0/3600.0)*window_W!;   let cancelBtn_X = window_W!/2.0 + margin_Of_TwoBtns/2.0;
        let cancelBtn_H = (360.0/3600.0)*window_W!;    let cancelBtn_Y = (150.0/3600.0)*window_W!;
        cancelBtn = NSButton(frame: NSMakeRect(cancelBtn_X, cancelBtn_Y, cancelBtn_W, cancelBtn_H))
        self.window?.contentView?.addSubview(cancelBtn)
        cancelBtn.title = _cancelStr!
        cancelBtn.alignment = NSTextAlignment.center
        cancelBtn.bezelStyle = .circular
        cancelBtn.setButtonType(NSButton.ButtonType.switch)//按鈕類型(可多選)
        cancelBtn.imagePosition = .imageOverlaps//圖片放在最下面
        cancelBtn.imageScaling = .scaleAxesIndependently//圖片自動(dòng)調(diào)整尺寸
        cancelBtn.image = NSImage(named: "Item_Button_nor")//圖片——普通狀態(tài)
        cancelBtn.alternateImage = NSImage(named: "Item_Button_sel")//圖片——高亮狀態(tài)
        
        //提示信息Label
        let tipLabel_X = 0.0;       let tipLabel_Y = self.sureBtn.frame.maxY + (110.0/2800.0)*window_W!
        let tipLabel_W = window_W!;  let tipLabel_H = (300.0/2800.0)*window_W!
        let tipContentLabel = NSTextField(frame: NSMakeRect(CGFloat(tipLabel_X), tipLabel_Y, tipLabel_W, tipLabel_H))
        self.window?.contentView?.addSubview(tipContentLabel)
        tipContentLabel.isEditable = false//不可編輯
        tipContentLabel.isBordered = false//不顯示邊框
        tipContentLabel.backgroundColor = .clear
        tipContentLabel.alignment = .center
        tipContentLabel.font = NSFont .boldSystemFont(ofSize: 15.0)
        tipContentLabel.textColor = .lightGray
        tipContentLabel.stringValue = _message!
    }
    func setUpTitleBarV() { //設(shè)置窗口的標(biāo)題欄
        let titleBar_Height: CGFloat = 27.0
        let titleBarImgV = NSImageView()
        self.window?.contentView?.addSubview(titleBarImgV)
        //添加約束
        titleBarImgV.translatesAutoresizingMaskIntoConstraints = false;
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: titleBarImgV, attribute: NSLayoutConstraint.Attribute.top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.window?.contentView, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1.0, constant: 0.0))
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: titleBarImgV, attribute: NSLayoutConstraint.Attribute.bottom, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.window?.contentView, attribute: NSLayoutConstraint.Attribute.top, multiplier: 1.0, constant: titleBar_Height))
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: titleBarImgV, attribute: NSLayoutConstraint.Attribute.left, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.window?.contentView, attribute: NSLayoutConstraint.Attribute.left, multiplier: 1.0, constant: 0.0))
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: titleBarImgV, attribute: NSLayoutConstraint.Attribute.right, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.window?.contentView, attribute: NSLayoutConstraint.Attribute.right, multiplier: 1.0, constant: 0.0))
        titleBarImgV.image = NSImage(named: "titleBar_Img")
        titleBarImgV.imageScaling = NSImageScaling.scaleAxesIndependently//圖片自動(dòng)調(diào)整尺寸
        
        let nameLB_leftMargin: CGFloat = 3.0
        let nameLB_Height: CGFloat = 20.0
        let nameLabel = NSTextField()
        self.window?.contentView?.addSubview(nameLabel)
        //添加約束-簡(jiǎn)寫
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: nameLabel, attribute: .top, relatedBy: .equal, toItem: self.window?.contentView, attribute: .top, multiplier: 1.0, constant: (titleBar_Height - nameLB_Height)))
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: nameLabel, attribute: .bottom, relatedBy: .equal, toItem: self.window?.contentView, attribute: .top, multiplier: 1.0, constant: titleBar_Height))
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: nameLabel, attribute: .left, relatedBy: .equal, toItem: self.window?.contentView, attribute: .left, multiplier: 1.0, constant: nameLB_leftMargin))
        self.window?.contentView?.addConstraint(NSLayoutConstraint(item: nameLabel, attribute: .right, relatedBy: .equal, toItem: self.window?.contentView, attribute: .right, multiplier: 1.0, constant: 0.0))
        nameLabel.isBordered = false
        nameLabel.isEditable = false
        nameLabel.backgroundColor = NSColor.clear
        nameLabel.textColor = NSColor.gridColor
        nameLabel.font = NSFont .boldSystemFont(ofSize: 13.0)
        nameLabel.stringValue = _title!//標(biāo)題
    }
    
}

在'ViewController.swift'文件中,進(jìn)行使用:

import Cocoa

class ViewController: NSViewController, NSWindowDelegate {
    
    var noticeWC: GYHNoticeAlertWindowController?//自定義‘提示’窗口
    //事件的響應(yīng)——自定義‘提示’窗口
    @objc func clickWindowButton(btn: NSButton) {
        btn.state = NSControl.StateValue.off//改為‘關(guān)閉’狀態(tài)——非選中
        
        if btn == noticeWC?.sureBtn {//點(diǎn)擊"確定"
            print("btn == noticeWC?.sureBtn")
            //"確定"相應(yīng)的操作
            
            //關(guān)閉模態(tài)、關(guān)閉窗口
            NSApplication .shared .stopModal()
            self .dismissNotice()
        } else if btn == noticeWC?.cancelBtn {//點(diǎn)擊"取消"
            print("btn == noticeWC?.cancelBtn")
            //"取消"相應(yīng)的操作
            
            //關(guān)閉模態(tài)、關(guān)閉窗口
            NSApplication .shared .stopModal()
            self .dismissNotice()
        }
    }
    //創(chuàng)建并展示‘提示’窗口
    public func createShowNotice(with delegate: NSWindowDelegate?) {
        //判空,避免重復(fù)創(chuàng)建
        noticeWC = noticeWC != nil ? noticeWC : GYHNoticeAlertWindowController(title: nil, message: nil, backColor:nil, okStr: nil, cancelStr: nil)//自定義初始化方法
        noticeWC? .showWindow(nil)
        //if delegate != nil {
        //    noticeWC?.window?.delegate = delegate;
        //} //無需delegate
        noticeWC?.sureBtn?.target = self;   noticeWC?.sureBtn?.action = #selector(clickWindowButton)
        noticeWC?.cancelBtn?.target = self; noticeWC?.cancelBtn?.action = #selector(clickWindowButton)
        
        //開啟模態(tài)
        NSApplication .shared .runModal(for: (noticeWC?.window)!)
    }
    //隱藏‘提示’窗口
    public func dismissNotice() {
        noticeWC? .close()//關(guān)閉窗口
        //noticeWC?.window?.delegate = nil  //無需delegate
        noticeWC = nil//置為nil
    }
    
    @objc func showNotice() {
        self .createShowNotice(with: nil)
    }

    func addOneBtn() {//為該window,隨便添加一個(gè)按鈕
        let btn = NSButton(frame: NSMakeRect(100, 100, 100, 100))
        btn.target = self; btn.action = #selector(showNotice)
        self.view .addSubview(btn)
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self .addOneBtn()//添加按鈕
        
    }
        
    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }


}

效果:
1.點(diǎn)擊'Button'按鈕后彈出自定義‘提示’窗口GYHNoticeAlertWindowController窗口)!彈出GYHNoticeAlertWindowController窗口(除了該GYHNoticeAlertWindowController窗口 進(jìn)行選擇)其他視圖 不能進(jìn)行操作~
2.點(diǎn)擊'確定'/'取消'后該GYHNoticeAlertWindowController窗口會(huì)消失并進(jìn)行其相應(yīng)的打印!之后其他視圖 可以進(jìn)行操作~

在"Debug View hierarchy"中查看視圖層次:

1.系統(tǒng)默認(rèn)自帶的窗口('NSWindowController'):

NSWindowController


2.自定義‘提示’窗口('GYHNoticeAlertWindowController'):

GYHNoticeAlertWindowController


思路如此,封裝看個(gè)人~(不想去封裝了??)


Tip1:關(guān)于按鈕字體居中顏色大小,可參考NSButton的使用(Mac端 按鈕)》中“設(shè)置按鈕的標(biāo)題顏色及字體”部分:
其中“-(void)setTitleColorToColor:(NSColor *)color andFontNum:(CGFloat)FontNum isBold:(BOOL)isBold;”方法通過了設(shè)置按鈕的attributedTitle屬性(富文本)中使用[paraStyle setAlignment:NSTextAlignmentCenter];實(shí)現(xiàn)了字體居中~


Tip2:關(guān)于提示信息Label的文字可能超出控件范圍的問題:

  • 1.可以設(shè)置其toolTip屬性—鼠標(biāo)放置上去就會(huì)展示出來!(效果如下)



不想再寫份Swift的代碼~??

Tip3:解決“頂部標(biāo)題欄鼠標(biāo)不能拖動(dòng)邊框不圓滑”的問題

self.window?.styleMask = NSWindow.StyleMask.fullSizeContentView//窗口風(fēng)格:頂部視圖+窗口(融合)

替換為如下代碼:

self.window?.styleMask = [self.window!.styleMask, >NSWindow.StyleMask.fullSizeContentView]//窗口風(fēng)格:圓滑邊框、頂部視圖+窗口(融合)
//獲取 (系統(tǒng))左側(cè)的‘關(guān)閉’、‘最小化’、‘最大化’按鈕
let closeBtn = self.window?.standardWindowButton(NSWindow.ButtonType.closeButton)
let zoomBtn = self.window?.standardWindowButton(NSWindow.ButtonType.zoomButton)
let miniaturizeBtn = self.window?.standardWindowButton(NSWindow.ButtonType.miniaturizeButton)
closeBtn?.isHidden = true       //隱藏 ‘關(guān)閉’按鈕     //初始位置 X:7.0   Y:3.0
zoomBtn?.isHidden = true        //隱藏 ‘最大化’按鈕     //初始位置 X:47.0   Y:3.0
miniaturizeBtn?.isHidden = true //隱藏 ‘最小化’按鈕   //初始位置 X:27.0   Y:3.0

優(yōu)化后效果:頂部標(biāo)題欄鼠標(biāo)可以拖動(dòng)邊框圓滑










goyohol's essay

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。