04. Form表单相关(一) - NSLabel 标签和 NSTextField 文本输入控件

从本章开始会用3~4篇文章详细介绍下和Form表单相关的控件,本节主要介绍下NSLabel和NSTextField输入相关的几个控件。

文本输入框包含两类:NSTextField 和 NSSecureTextField,后者用于输入密码。基础控件的作用都差不太多,本节会以NSTextField为例做一个详细介绍,其它的几个控件的使用方法可参考NSTextField的描述。

NSTextField

先设计如下一个简单界面:

基础设置

在 attributes 面板中可设置很多内容,包括样式和一些其它的属性:

  • title :默认文本
  • placeholder:占位提示文本
  • text color:文本颜色
  • behavior:none-只读不支持选择, editable读写,selectable只能选择文本
  • text direction:文本输入的方向

修改事件侦听

文本框的输入事件 是通过实现 NSTextFieldDelegate 协议的代理方法回调通知实现的,如果需要侦听则需要绑定各个输入框的Outlets到AppDelegate上面(设置代理,限XIB方式)。

然后就可以实现回调方法了,需要注意不同swift版本的实现不太一样:

修改Swift Language Version 的方法是在product-> target->Build settings -> swift Language version 中设置的。

swift 复制代码
//以下代码是swift v4版本
class AppDelegate: NSObject, NSApplicationDelegate,NSTextFieldDelegate
    @IBOutlet var window: NSWindow!

    @IBOutlet weak var userName: NSTextField!
    
    @IBOutlet weak var userPwd: NSSecureTextField!

    override func controlTextDidBeginEditing(_ obj: Notification) {
        if let textField = obj.object as? NSTextField {
            //取值
            let text = textField.stringValue
            if(textField == self.userName){
                print("userName:\(text)")
            }
            if(textField == self.userPwd){
                print("password:\(text)")
            }
        }
    }
    
    override func controlTextDidChange(_ obj: Notification) {
        if let textField = obj.object as? NSTextField {
            let text = textField.stringValue
            if(textField == self.userName){
                print("userName:\(text)")
            }
            if(textField == self.userPwd){
                print("password:\(text)")
            }
        }
    }

文本内容获取

获取输入框的文本内容

swift 复制代码
textField.stringValue
richTextField.attributedStringValue

拦截特殊按键

侦听特殊按键,在后面事件一节中会有详细讲解,此处会用即可,此功能也是 NSTextFieldDelegate 协议中的一个方法:

swift 复制代码
    // AppDelegate.swift
    func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
        if (commandSelector == #selector(NSResponder.insertNewline(_:))) {
            // Press ENTER key
            print("enter")
            return true
        } else if (commandSelector == #selector(NSResponder.deleteForward(_:))) {
            // Press DELETE key
            return true
        } else if (commandSelector == #selector(NSResponder.deleteBackward(_:))) {
            // Press BACKSPACE key
            return true
        } else if (commandSelector == #selector(NSResponder.insertTab(_:))) {
            // Press TAB key
            return true
        } else if (commandSelector == #selector(NSResponder.cancelOperation(_:))) {
            // Press ESC key
            return true
        }
        return false
    }

NSTextView

多行文本输入框,这东西是一个多层结构,最外层是NSScrollView,最内层才是NSTextView,所以绑定的时候不要弄错了。

基础设置

  • Linguistics:智能化的一些设置,比如拼写检查等;

修改事件侦听

同样的,TextView的事件是通过实现 NSTextDelegate 协议的代理方法回调通知实现的,同样的要侦听的控件也需要绑定到AppDelegate对象上面(设置代理,限XIB方式)。

swift 复制代码
import Cocoa

@main
class AppDelegate: NSObject, NSApplicationDelegate, NSTextDelegate {

    @IBOutlet var window: NSWindow!

    @IBOutlet var textViewNS: NSTextView!
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

    func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
        return true
    }
    
    func textDidBeginEditing(_ notification: Notification) {
        if let textView = notification.object as? NSTextView {
            let text = textView.string
            print("textDidBeginEditing text \(text)")
            
        }
    }
    
    func textDidEndEditing(_ notification: Notification) {
        if let textView = notification.object as? NSTextView {
            let text = textView.string
            print("textDidEndEditing text \(text)")
        }
    }

    func textDidChange(_ notification: Notification) {
        if let textView = notification.object as? NSTextView {
             let text = textView.string
             print("textDidChange text \(text)")
            
        }
    }
}

文本内容获取

swift 复制代码
textView.string

NSSearchField

实时检索

搜索文本框,可实现类似实时搜索的效果,实时效果需要绑定IBAction方法:

swift 复制代码
    @IBAction func searchTextFieldAction(_ sender: NSSearchField) {
        let text = sender.stringValue
        print("searchAction:\(text)")
    }

修改事件侦听

除了上面的事件,输入文字后左右会分别显示放大镜和一个清除按钮,这两个按钮也可以添加事件侦听,放大镜相当于点击enter时调用的事件,上述功能没有现成的Delegate,需要手工编码实现,实现代码如下:

注册事件侦听

swift 复制代码
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        self.registerSearchButtonAction()
    }

实 现侦听事件

swift 复制代码
    //自行添加事件
    func registerSearchButtonAction(){
        //搜索按钮
        let searchButtonCell  = self.searchField.cell as! NSSearchFieldCell
        let searchButtonActionCell = searchButtonCell.searchButtonCell!
        
        searchButtonActionCell.target = self
        searchButtonActionCell.action = #selector(searchButtonAction(_:))
        
        //取消按钮
        let cancelButtonCell  = self.searchField.cell as! NSSearchFieldCell
        let cancelButtonActionCell = cancelButtonCell.cancelButtonCell!
        
        cancelButtonActionCell.target = self
        cancelButtonActionCell.action = #selector(cancelButtonAction(_:))
    }
    
    @IBAction func searchButtonAction(_ sender: NSSearchField) {
        print("点击了搜索按钮")
        self.searchTextFieldAction(sender)
    }
    
    @IBAction func cancelButtonAction(_ sender: NSSearchField) {
        print("文本内容已清除")
        sender.stringValue = ""
    }

NSLabel

本质上是NSTextField,只是官方事先进行了一些特殊的属性设置,目的是为了方便使用。

基础设置

  • Layout:scrolls 单行显示, wraps多行显示
  • Line Break:控制文本超出时的显示模式

编码实现简单标签

以下是完成时的样子

swift 复制代码
    func addLabel(){
        let frame = CGRect(x: 20, y: 123, width: 222, height: 24)
        let label = NSTextField(frame: frame)
        label.isEditable = false
        label.isBezeled = false
        label.drawsBackground = false
        label.stringValue = "我是代码添加的Label"
        
        self.window.contentView?.addSubview(label)
    }

编码实现超链接标签

URI点击跳转。

swift 复制代码
    func addRichableLabel(){
        
        let text = NSString(string: "http://www.korg8.com/")
        let attributedString = NSMutableAttributedString(string:text as String)
        let linkURLText = "http://www.korg8.com/"
        let linkURL = NSURL(string:linkURLText)
        
        let selectedRange = text.range(of: linkURLText)
    
        attributedString.beginEditing()
        attributedString.addAttribute(NSAttributedStringKey.link, value:linkURL!, range: selectedRange)
        
        attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value:NSColor.blue, range: selectedRange)
        
        attributedString.addAttribute(NSAttributedStringKey.underlineStyle, value:NSUnderlineStyle.styleSingle.rawValue, range: selectedRange)
        attributedString.endEditing()
        
        let frame = CGRect(x: 20, y: 93, width: 222, height: 24)
        let richTextLabel = NSTextField(frame: frame)
        richTextLabel.isEditable = false
        richTextLabel.isBezeled = false
        richTextLabel.drawsBackground = false
        richTextLabel.attributedStringValue = attributedString
        
        self.window.contentView?.addSubview(richTextLabel)
        
    }
相关推荐
hanruanjian2 小时前
CDR2024官方学习版安装包+升级补丁包+注册机
android·windows·学习·microsoft·macos·idm
yanling20234 小时前
Parallels Desktop 20 for Mac 2024年最新激活码秘钥
科技·macos·pd
2401_852403555 小时前
iPhone相册怎么删除相同照片
ios·智能手机·iphone
狼刀流9 小时前
(10) GTest c++单元测试(mac版)
c++·macos·单元测试
欣慰的三叶草(● ̄(エ) ̄●)9 小时前
【Mac苹果电脑安装】DBeaverEE for Mac 数据库管理工具软件教程【保姆级教程】
数据库·macos·数据库管理·dbeaver·dbeaveree·db数据库管理工具
墨渊君9259 小时前
仿 Mac 个人网站开发 |项目复盘
前端·javascript·macos·reactjs·web
穆栩萌霖9 小时前
解决mac更新后无法连接git问题
git·macos
Xminyang10 小时前
[Mac + Icarus Verilog + gtkwave] Mac运行Verilog及查看波形图
macos·verilog
KeithTsui10 小时前
集合论(ZFC)之良创关系(Well-Founded Relation)
开发语言·其他·算法·binder·swift