macOS开发 NSTextField控件 macOS中并没有 UILable ,也没有 NSLabel
macOS中的 label 实际上是 NSTextField,并将editable = NO;
来实现显示效果。这是不是和 iOS 中的UITextView 很像呢?
-(void)viewDidLoad { [super viewDidLoad]; NSTextField *lbl = [[NSTextField alloc] init]; lbl.frame = CGRectMake(100, 100, 200, 44); lbl.stringValue = @"啦啦啦"; [self.view addSubview:lbl]; }
复制以上代码即可简单运行NSTextField
以下是项目运行
#import "ViewController.h" @interface ViewController () /** macos 文本 */ @property (nonatomic, weak) NSTextField *lblnew; @end @implementation ViewController #pragma mark 懒加载 macos 文本 - (NSTextField *)lblnew { if (!_lblnew) { NSTextField *lbl = [[NSTextField alloc] init]; [self.view addSubview:lbl]; _lblnew = lbl; } return _lblnew; } -(void)viewDidLoad { [super viewDidLoad]; CGFloat lblY = 100; CGFloat lblW = 80; CGFloat lblH = 440; CGFloat lblX = 100; self.lblnew.frame = CGRectMake(lblX, lblY, lblW, lblH); //macOS NSTextField的属性按需要选择使用 _lblnew.editable = NO;//设置是否可以编辑 _lblnew.bordered = NO; //不显示边框 _lblnew.backgroundColor = [NSColor greenColor]; //控件背景色 _lblnew.textColor = [NSColor magentaColor]; //文字颜色 _lblnew.alignment = NSTextAlignmentCenter; //水平显示方式 _lblnew.maximumNumberOfLines = 2; //最多显示行数 _lblnew.stringValue = @"hhh"; //现实的文字内容 _lblnew.font = [NSFont systemFontOfSize:14];//设置字号大小 [_lblnew sizeToFit];////自适应大小(改变label的宽度,使其刚刚好可以容纳字符) } @end
要注意的点:
1.可以在非编辑模式下显示富文本;
如果需要编辑富文本,建议使用 NSTextView.
2.输入为密文:NSSecureTextField
用NSSecureTextField和NSTextField重叠实现可见输入的密码
https://blog.csdn.net/abby_sheen/article/details/7386308
3.现NSTextField是继承于NSControl的,在NSControl中有一个属性为cell。
@property (nullable, strong) __kindof NSCell *cell;
也就是说在NSTextField控件上,除了有自己的边框外,还有一个继承于父类的NSCell,所以在我们设置NSTextField的边框颜色时需要同时设置NSCell的相应属性。
cell 是 cocoa 在当时硬件条件下的一种优化。cocoa 是利用显卡3d 加速能力的 GUI 框架。
4.Mac 开发中,设置一个 Label 是很常见的事情,但 Mac 中没有直接提供类似 iOS 中的 UILabel 类,只能使用 NSTextField 类;但在使用过程中发现,其中的字无法垂直居中,很是难看。网络上搜了一遍,有用的信息支离破碎,同时几年前的类方法已经被废弃了。
综合一下,参考苹果官方文档,NSTextField 内部有个 cell 对象,默认是 NSTextFieldCell,它负责绘制工作。因此自定义一个 RSVerticallyCenteredTextFieldCell 类继承自 NSTextFieldCell,绘制时设置垂直居中;再自定义一个 RSVerticallyCenteredTextField 类继承自 NSTextField,初始化时设置 cell 为自定义的 Cell 类;最后使用该自定义的 RSVerticallyCenteredTextField 类即可。
5.关于oc NSTextField文本垂直居中除了网上的做法以外,最简单的做法就是在
_lblnew.stringValue = @"\n\n\n例子";//是的在字符串添加\n
最好还可以配合行数和字号大小来控制
_lblnew.maximumNumberOfLines = 8; //最多显示行数
_lblnew.font = [NSFont systemFontOfSize:14];//设置字号大小
能垂直居中的字符串一定是可以确定字符串长度的,字符串过长(就是超过设置的宽度)可以自动回行
你以为学习就这样结束了?这仅仅是开始!
Cocoa 提供了两种文本编辑控件 [1]:NSTextView
和 NSTextField
。从表面上看,前者比后者功能丰富,前者一般用作复杂的文字编辑,后者一般接受简单的数据输入。二者处理 Enter 和 Tab 键的行为不同。NSTextView
的方式和通常的编辑器相同:给编辑内容添加换行或者 tab 字符。NSTextField
的方式则类似于其它非文本编辑的 Cocoa 控件:Enter 键触发 target action(缺省为终止编辑),Tab 键令焦点移到相邻的下一控件。
有了正确的世界观,就可以自由地对文本编辑行为作出调整。
其实在 Cocoa 中提供文本编辑功能的类只有 NSTextView
。NSTextField
不是 NSTextView
的封装,它的作用是为实际承担编辑工作的 NSTextView
提供操作「场所」。其名称中「field」的意义不是表格或文件格式意义上的 field。当一个 NSTextField
控件不拥有焦点的时候,它只显示自己存储的文本值 [2],并不和 NSTextView
有任何关系。当它获得焦点时,其所在的窗口会把一个 NSTextView
控件置于其上,并将原来的 NSTextField
对象设置为该 NSTextView
对象的 delegate,真正获取焦点并且成为 first responder 的控件是 NSTextView
对象。在同一窗口中,置于所有 NSTextField
之上的是同一个 NSTextView
对象实例。因为只有一个控件能获得焦点,所以共享单一的 NSTextView
实例没有问题。这个唯一的实例称为「field editor」,即放置在 text field 上的 editor。
所以下一篇博主就NSTextView来一篇简单的使用说明和具体应用。实践是检验真理的唯一标准!
NSTextView
和 NSTextField
对 Enter/Tab 的不同处理。严格的说是非 field editor 的 NSTextView
对象和作为 field editor 的 NSTextView
对象的不同行为。 NSTextView
的 isFieldEditor
属性表示当前对象是否为 field editor。一切行为差异的秘密就在于 insertNewLine:
和 insertTab:
会根据 isFieldEditor
的返回值来决定控件的行为。
- 始终用
NSTextView
,并且保证isFieldEditor
属性返回NO
。 - 重写窗口 delegate 的
windowWillReturnFieldEditor:toObject:
,返回 custom field editor。此方案需要创建两个新类:窗口 delegate 和NSTextView
的子类。后者的insertNewLine:
和insertTab:
需要被改写。 - 让处理 key action 的模块发送
insertNewLineIgnoringFieldEditor:
和insertTabIgnoringFieldEditor:
消息给 field editor,保证始终插入换行或 tab 字符。
- 实际上 Cocoa 中的静态 label 也是由
NSTextField
实现,只不过这时它没有获取焦点的能力,不作为NSTextView
的「field」。 - 这个「更早的模块」是 Cocoa 的 key-binding manager。可以参见《Cocoa Event Handling Guide》的 Key Bindings 章节等。
- 用 debugger 在其中设置断点查看 call-stack 可以发现更多信息,比如关于 key-binding manager 的信息。
- 更多细节可以阅读《Editing Programming Guide》的 Working With Field Editor,以及《Technical Q&A 1454》。
此处感谢:Sodaslay