按钮在OS X中是最常使用的控件之一,本节所描述的控件本质上都是NSButton的实现,官方根据不同的用途进行了特殊的设置进而可以显示为不同的样式。
在OS X中可以把一个事件绑定到多个控件上面,比如自定义菜单和界面中的按钮公用一个响应事件;
NSButton
动作按钮,根据type属性值的不同大概有以下这些样式:

基本设置
- style:按钮的样式
- bordered:是否带边框
- title:显示文字
- Alignment:文字对齐
- image:按钮图像,可以删除掉title文字实现纯图像按钮
- tool tip:设置按钮提示事件
点击响应事件
连接Action事件即可:
@IBAction func pushAction(_ sender: NSButton) {
NSLog("button click!")
}
编程实现
用代码创建按钮,同时绑定事件
@IBAction func pushAction(_ sender: NSButton) {
NSLog("button click!")
}
func createButton(){
let frame = CGRect(x: 300, y: 0, width: 100, height: 28)
let btn = NSButton(frame: frame)
btn.bezelStyle = .rounded
btn.title = "CodeButton"
btn.target = self
btn.action = #selector(pushAction(_:))
self.window.contentView?.addSubview(btn)
}
CheckButton
本质上就是NSButton,只不过设置了不同的样式而已;

基本设置
- state :on(1), off(0), mixed;
func initCheckBtn(){
self.checkBtn1.state = .on
self.checkBtn2.state = .off
self.checkBtn3.state = .mixed
}
点击响应事件
在OS X中可以把一个事件绑定到多个控件上面,比如下面例子就是把checkbtn1和2同时绑定到了同一个事件上面。
@IBAction func checkBtnAction(_ sender: NSButton) {
let state = sender.state // 0||1
if state == .on {
print("check selected ")
}
else {
print("check un selected ")
}
print("state :\(state)")
}
Radio
本质上就是NSButton,只不过设置了不同的样式而已;
基本设置
- state:是否选中,on(1), off(0);
- tag:可为每个radio设置一个唯一的tag值,用于逻辑判断使用;
点击响应事件
Radio一般是需要分组的,只要把一组按钮绑定到同一个事件上即可实现类似分组的功能,如下例子,这三个radio只能有一个被选中了。

@IBAction func radioBtn(_ sender: NSButton) {
let tag = sender.tag
print("tag:\(tag) , text:\(sender.title), state:\(sender.state)")
}
NSSegmentedControl
一种多选一的分段按钮视图,有很多种样式,默认的按钮宽度由其内容大小决定,但可以通过设置其width来调整大小。

基本设置
- segments:分段数;
- segment:段列表;
- state:选中状态;
点击响应事件
没啥特殊的,正常绑定即可
@IBAction func segmentBtn(_ sender: NSSegmentedControl) {
var btn: NSSegmentedControl = sender
let index = btn.selectedSegment
print(index) //index从0开始
}
NSComboBox
下拉列表,其功能比较多:

基本设置
- items:选项列表;
- visible items:下拉列表弹出后,其默认显示多少条;
- useDataSource:通过代码来设置其值
点击响应事件
没啥特殊的,直接绑定即可:
@IBAction func listSelected(_ sender: NSComboBox) {
let selectedIndex = sender.indexOfSelectedItem
let selectedContent = sender.stringValue
print("selectedIndex:\(selectedIndex) selectedContent:\(selectedContent)")
}
动态改变列表内容
原始控件的所有设置不要变,直接新加以下代码在程序中控制:
func dynamicComboBoxConfig(){
let items = ["1","2","3"]
//删除默认的初始数据
self.dynamicList.removeAllItems()
//增加数据items
self.dynamicList.addItems(withObjectValues: items)
//设置第一行数据为当前选中的数据
self.dynamicList.selectItem(at: 0)
}
使用外部数据源配置
这种方式比较灵活,比如数据可由外部来定义,使用数据源配置时需要实现NSComboBoxDataSource 和 NSComboBoxDelegate 协议,下面例子是一个简单实现,正常来讲需要创建一个子类,然后
//开启配置,自定义方法
func dataSourceComboBoxConfig(){
self.dataSourceList.usesDataSource = true
self.dataSourceList.dataSource = self
self.dataSourceList.delegate = self
}
var datas : [String] = ["Class1","Class2","Class3"]
// MARK: NSComboBoxDataSource,返回item个数
func numberOfItems(in comboBox: NSComboBox) -> Int {
return self.datas.count
}
// MARK: NSComboBoxDataSource,返回每个index对应的item
func comboBox(_ comboBox: NSComboBox, objectValueForItemAt index: Int) -> Any? {
return self.datas[index]
}
// MARK: NSComboBoxDelegate, 侦听事件
func comboBoxSelectionDidChange(_ notification: Notification) {
let comboBox = notification.object as! NSComboBox
let selectedIndex = comboBox.indexOfSelectedItem
let selectedContent = comboBox.stringValue
print("selectedIndex = \(selectedIndex) selectedContent =\(selectedContent)")
}
NSPopUpButton
弹出式列表控件,其作用同NSComboBox差不太多,按道理这个控件用处不大,有点怪。

基本设置
- type:样式设置,主要是用于显示一些箭头样式啥的;
- arrow:箭头方向和位置;
- menu edge:菜单位置
动态改变列表内容
@IBOutlet weak var popUpBtn: NSPopUpButton!
func dynamicDataConfig(){
let items = ["1","2","3"]
//删除默认的初始数据
self.popUpBtn.removeAllItems()
//增加数据items
self.popUpBtn.addItems(withTitles: items)
//设置第一行数据为当前选中的数据
self.popUpBtn.selectItem(at: 0)
}
点击响应事件
没啥特殊的,直接绑定即可:
@IBAction func popUpBtnAction(_ sender: NSPopUpButton){
let items = sender.itemTitles
//当前选择的index
let index = sender.indexOfSelectedItem
//选择的文本内容
let title = items[index]
print("select title \(title)")
}
NSSlider
滑杆控件,一般用于数值选择,可以为整数或浮点数

基本设置
- style:可设置为linear线或Circular圆形
- tick markers:分段标记,默认是0,表示无标记
- value:可设置minimum, maximum, current,可以为整数或浮点数
- state:表示是否可以拖动
滑动响应事件
没啥特殊的,只简单绑定即可
@IBAction func sliderBtnAction(_ sender: NSSlider) {
let intValue = sender.intValue
print("intValue :\(intValue)")
}
NSDatePicker
日期选择控件。

基本设置
- style:样式设置,可选的有:textual文本、textual with stepper文本递增、graphical图形
- selections:鼠标点击选择模式
- elements:(date)年月日, (time)时分秒显示控制
- date:初始值
- display:背景和边框
- textcolor:文字颜色
- background:背景颜色
点击响应事件
没舍特殊的,直接绑定即可
@IBOutlet weak var datePicker: NSDatePicker!
@IBAction func dataPickupAction(_ sender: NSDatePicker) {
let date = sender.dateValue
print("date:\(date)")
}
修改侦听响应
一般用于数字验证等操作,需实现NSDatePickerCellDelegate协议。
// MARK: NSDatePickerCellDelegate,日期变化侦听,可做一些范围判断等
func datePickerCell(_ datePickerCell: NSDatePickerCell, validateProposedDateValue proposedDateValue: AutoreleasingUnsafeMutablePointer<NSDate>, timeInterval proposedTimeInterval: UnsafeMutablePointer<TimeInterval>?) {
let timeInterval = proposedTimeInterval?.pointee
self.datePicker.timeInterval = timeInterval!
}
NSStepper
步进器,一般用于做数据的递增和递减操作使用。这东西本身只是一个上下箭头,然后加了一个文本框组合成了一个复合控件。

基本设置
- value:用于设置最大、最小、步进、初始化值使用
点击响应事件
因为是两个控件组成,所以需要一个联动效果,从stepper注册一个动作类,把文本框的代理设置为AppDelegate,然后复写AppDelegate协议方法。
- 同步设置

override func controlTextDidChange(_ obj: Notification) {
let textField = obj.object as! NSTextField
self.stepperButton.intValue = stepTextfield.intValue
}
- 箭头事件响应
@IBAction func stepperBtn(_ sender: NSStepper) {
let theValue = sender.intValue
self.stepTextfield.intValue = theValue
}
本节内容完整UI示例如下图所示:

2481

被折叠的 条评论
为什么被折叠?



