08.容器控件(二) - NSPanl面板基础与自定义,以及文件、颜色、字体面板使用

本节主要讲述和容器相关的控件第二部分,主要包括panel、dialog以及文件打开和保存面板等等。

NSPanel

用来显示辅助性内容的窗口面板,包括文件打开、保存对话框、颜色、字体等都是NSPanel的子类。
在这里插入图片描述

基本设置

  • title:面板标题
  • controls:窗口三个按钮显示:最大,最小,关闭
  • behabior:用于控制启动是否显示
  • style:皮肤

显示和隐藏面板

这里需要注意只有xib-ui才有panel控件,而storyboard而没有此控件。拖动时需要拖动一个NSPanel到空白处,然后绑定到Appdelegate中。

    @IBAction func nsPanelBtnTest(_ sender: NSButton) {
        //显示弹出面板
        self.window.beginSheet(
            self.loginPanel,
            completionHandler: { //关闭后的回调函数
                [weak self] returnCode in let userName = self?.userNameField.stringValue
                
                print("user \(returnCode)")
            }
        )
    }
    
    //隐藏面板
    @IBAction func submitUserInfo(_ sender: NSButton) {
        self.window.endSheet(self.loginPanel)
    }

NSOpenPanel

文件打开面板,这个面板的打开通常直接绑定文件菜单中的打开上,比如下便中的文件fynd取。
在这里插入图片描述

基本设置

  • canChooseFiles:是否允许一次选择多个文件;
  • canChooseDirectories:是否允许选择目录;
  • allowMutipleSelection:是否允许多选;
  • allowedFileTypes:允许的文件后缀名;
  • URLs:文件路径;

打开文件

打开一个txt文件并设置内容到一个textView中(这里绑定textView时注意其绑定的是最底层视图)

    @IBOutlet var textView: NSTextView!
    
    @IBAction func openFiles(_ sender: NSMenuItem) {
        let openDlg = NSOpenPanel()
        openDlg.canChooseFiles = true
        openDlg.canChooseDirectories = false
        openDlg.allowsMultipleSelection = false
        openDlg.allowedFileTypes = ["txt"]
    
        openDlg.begin(completionHandler: { [weak self]  result in
            
            if(result.rawValue == NSFileHandlingPanelOKButton){
                let fileURLs = openDlg.urls
                for url: URL in fileURLs  {
                    guard let text = try?  NSString.init(contentsOf: url, encoding: String.Encoding.utf8.rawValue)
                        else {
                            return
                    }
                    // as 是一种强制类型转换语法
                    self?.textView.string = text as String
                }
            }
         })
    }

NSSavePanel

文件保存面板,其功能和使用场景同open差不太多。
在这里插入图片描述

基本设置

  • title:保存面板标题
  • allowedFileTypes:可以保存的文件的后缀名称
  • nameFieldStringValue:默认要保存的文件名

保存文件

同样的需要绑定save菜单

    @IBAction func saveFiles(_ sender: NSMenuItem) {
        let text = self.textView.string
        
        let saveFileDlg = NSSavePanel()
        saveFileDlg.title = "Save File"
        saveFileDlg.message = "Save My File"
        saveFileDlg.allowedFileTypes = ["txt"]
        saveFileDlg.nameFieldStringValue = "my"
        
        saveFileDlg.begin(completionHandler: { result in
        
            if result.rawValue==NSFileHandlingPanelOKButton {
                let url = saveFileDlg.url
                _ = try? text.write(to: url!, atomically: true, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
            }
        
        })
    }

测试保存文件时,在保存文件时需要打开相应的权限,如下:
在这里插入图片描述

颜色和字体设置

NSColorPanel

在这里插入图片描述

共享系统toolbar面板功能

    @IBAction func chooseColor(_ sender: NSButton) {
        let colorpanel = NSColorPanel.shared
        //事件
        colorpanel.setAction(#selector(changeTextColor(_:)))
        colorpanel.setTarget(self)
        colorpanel.orderFront(nil)
    }
    
    @objc func changeTextColor(_ sender: NSColorPanel){
       let color = sender.color;
       self.textView.textColor = color
    }

NSFontManager

共享系统toolbar面板功能

    @IBAction func chooseFont(_ sender: NSButton) {
        let fontManager = NSFontManager.shared
        fontManager.target = self
        fontManager.action = #selector(changeTextFont(_:))
        fontManager.orderFrontFontPanel(self)
    }
    
    lazy var font = NSFont()
    
    @objc func changeTextFont(_ sender: NSFontManager){
        self.font = sender.convert(self.font)
        self.textView.font = self.font
    }

NSAlert

显示提示信息,有时也可以用popup来代替,可以用于验证提示等场景。
在这里插入图片描述

基本设置

  • messageText:提示信息
  • informativeText:提示详细信息
  • icon:图标
  • alertStyle:样式,分为基本、警告和错误三类

编程示例

同样的也会存在一个名为 NSAlertDelegate的代理。

    @IBOutlet weak var userNameForAlert: NSTextField!
    
    @IBAction func userNameForAlert(_ sender: NSButton) {
        let password = self.userNameForAlert.stringValue
        if password.characters.count < 6 {
            let alert = NSAlert()
            //增加一个按钮
            alert.addButton(withTitle: "Ok")
            alert.addButton(withTitle: "Canel")
            //提示的标题
            alert.messageText = "Alert"
            //提示的详细内容
            alert.informativeText = "userName length must be more than 6 "
            //设置告警风格
            alert.alertStyle = .informational
            alert .beginSheetModal(for: self.window!, completionHandler: { returnCode in
                     //当有多个按钮是 可以通过returnCode区分判断,三个按钮分别为1000, 1001, 1002
                     print("returnCode :\(returnCode)")
                
                }
            
            )
        }
    }

使用XIB创建面板

UI 绑定

  1. 新建一个xib文件,选择Application.xib, 也可选择Empty;
  2. 新建一个新NSPanel的子类,比如Application.Swift;
  3. 在xib-window的identity面板中绑定custom类为Application.Swift;
    在这里插入图片描述
    在这里插入图片描述

功能代码

在这里插入图片描述

定义全局变量

建议定义在一个单独的文件中

import Cocoa

let kCancelCode = 0
let kOkCode = 1

自定义面板实现

import Cocoa

class Application: NSPanel {

    var datas = [NSDictionary]()
    
    @IBOutlet weak var tableView: NSTableView!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        self.updateData()
    }
    
    func updateData() {
        self.datas = [
            ["name":"john","address":"USA"],
            ["name":"mary","address":"China"],
            ["name":"park","address":"Japan"],
            ["name":"Daba","address":"Russia"],
        ]
    }
    
    @IBAction func okAction(_ sender: AnyObject?) {
        self.parent?.endSheet(self, returnCode: NSApplication.ModalResponse(rawValue: kOkCode))
    }
    
    @IBAction func cancelAction(_ sender: AnyObject?) {
        self.parent?.endSheet(self, returnCode: NSApplication.ModalResponse(rawValue: kCancelCode))
    }
}

extension Application: NSTableViewDataSource {
    func numberOfRows(in tableView: NSTableView) -> Int {
        return self.datas.count
    }
}

extension Application: NSTableViewDelegate {
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        
        let data = self.datas[row]
        //表格列的标识
        let key = (tableColumn?.identifier)!
        //单元格数据
        let value = data[key]
        
        //根据表格列的标识,创建单元视图
        let view = tableView.makeView(withIdentifier: key, owner: self)
        let subviews = view?.subviews
        if (subviews?.count)!<=0 {
            return nil
        }
        
        if key.rawValue == "name" || key.rawValue == "address" {
            let textField = subviews?[0] as! NSTextField
            if value != nil {
                textField.stringValue = value as! String
            }
        }
        
        return view
    } 
}

调用自定义面板

    var topLevelArray: NSArray?
    lazy var myPanel: Application? = {
        var panel: Application?
        // 加载xib文件
        let nib  = NSNib.init(nibNamed: NSNib.Name(rawValue: "Application"), bundle: Bundle.main)
        // 实例化xib资源文件中的类,并存放在对象数组中
        //topLevelObjects::是一个指向数组的指针,方法会将从 Nib 文件中实例化的顶级对象放入这个数组中。这些对象通常是视图控制器、视图或其他界面元素。
        if let success =  nib?.instantiate(withOwner: self, topLevelObjects: &topLevelArray) {
            if success {
                for obj in self.topLevelArray! {
                    if obj is Application {
                        //一种类型转换操作,具体来说是尝试将 obj 转换为 Application 类型的一个可选值(Application?)
                        panel = obj as? Application
                        break
                    }
                }
            }
        }
        return panel
    }()
    
    //按钮调用
    @IBAction func showWindowAction(_ sender: NSButton) {
        self.myPanel?.parent = self.window
        self.window?.beginSheet(self.myPanel!, completionHandler: {  returnCode in
            if returnCode.rawValue == kOkCode {
                print("returnCode \(returnCode)")

            }
        })
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

korgs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值