改变NSButton字(title)的颜色

本文介绍了一种使用NSAttributedString为NSButton设置标题颜色的方法,并提供了解决内存泄漏问题的方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自我的简书:http://www.jianshu.com/p/a9e86b79a2d4

NSButton不能像UIButton那样简单的修改title的颜色,或者说NSButton不能像UIButton那样做很多事,使用起来真的很不方便。
经过大量研究测试,终于发现一种修改文字颜色的相对来说比较简单的方式-用NSAttributedString;不说了,代码如下:

// 创建段落样式,主要是为了设置居中
NSMutableParagraphStyle pghStyle = [[NSMutableParagraphStyle alloc] init];
pghStyle.alignment = NSTextAlignmentCenter;
// 创建Attributes,设置颜色和段落样式
NSDictionary dicAtt = @{NSForegroundColorAttributeName: [NSColor whiteColor], NSParagraphStyleAttributeName: pghStyle};
// 创建NSAttributedString赋值给NSButton的attributedTitle属性
btn.attributedTitle = [[NSAttributedString alloc] initWithString:@"解绑" attributes:dicAtt];

4行代码即可,比起一来就说什么重写drawRect的简单多了!

但是,经过实际操作发现该方法会导致内存泄漏,实在不知是什么原因导致的,私下猜测是Apple的bug吧。但是也不是没有解决方法,经过大量测试,发现以下方法可以解决内存泄漏的问题。

// 创建段落样式,主要是为了设置居中
    NSMutableParagraphStyle *pghStyle = [[NSMutableParagraphStyle alloc] init];
    pghStyle.alignment = NSTextAlignmentCenter;
    // 创建Attributes,设置颜色和段落样式
    NSDictionary *dicAtt = @{NSForegroundColorAttributeName: [NSColor whiteColor], NSParagraphStyleAttributeName: pghStyle};
    // 创建NSAttributedString赋值给NSButton的attributedTitle属性;必需从NSButton.attributedTitle创建,否则会有内存泄漏;
    // 给NSButton先赋值一个字符串,为的是后面替换,如果NSButton的title是空字符串的话,也会内存泄漏
    btn.title = @" ";  // 这里的字符串有一个空格
    // 用NSButton.attributedTitle属性创建一个NSMutableAttributedString对象
    NSMutableAttributedString *attTitle = [[NSMutableAttributedString alloc] initWithAttributedString:btn.attributedTitle];
    // 替换文字
    [attTitle replaceCharactersInRange:NSMakeRange(0, 1) withString:@"解绑"];
    // 添加属性
    [attTitle addAttributes:dicAtt range:NSMakeRange(0, 2)];
    // 赋值给NSButton.attributedTitle属性,不会再有内存泄漏
    btn.attributedTitle = attTitle;

经过大量测试,发现只有这种方法不会内存泄漏,我也是醉了。

运行为14:42: error: use of undeclared type 'SystemImage' static func loadImage(named: String) -> SystemImage? { ^~~~~~~~~~~ 28:24: error: 'URLSession' is unavailable: This type has moved to the FoundationNetworking module. Import that module to use it. private let session = URLSession.shared ^~~~~~~~~~ Foundation.URLSession:2:18: note: 'URLSession' has been explicitly marked unavailable here public typealias URLSession = AnyObject ^ 50:22: error: use of unresolved identifier 'SystemLabel' private let label = SystemLabel() ^~~~~~~~~~~ 51:26: error: use of unresolved identifier 'SystemImageView' private let imageView = SystemImageView() ^~~~~~~~~~~~~~~ 52:23: error: use of unresolved identifier 'SystemButton' private let button = SystemButton() ^~~~~~~~~~~~ 54:11: error: initializer does not override a designated initializer from its superclass override init(frame: CGRect) { ~~~~~~~~ ^ 49:21: error: use of undeclared type 'SystemView' class PlatformView: SystemView { ^~~~~~~~~~ 55:3: error: 'super' members cannot be referenced in a root class super.init(frame: frame) ^ 60:3: error: 'super' members cannot be referenced in a root class super.init(coder: coder) ^ 67:21: error: use of unresolved identifier 'SystemColor' label.textColor = SystemColor.label ^~~~~~~~~~~ 68:3: error: use of unresolved identifier 'addSubview' addSubview(label) ^~~~~~~~~~ 73:3: error: use of unresolved identifier 'addSubview' addSubview(imageView) ^~~~~~~~~~ 83:3: error: use of unresolved identifier 'addSubview' addSubview(button) ^~~~~~~~~~ 90:3: error: use of unresolved identifier 'NSLayoutConstraint' NSLayoutConstraint.activate([ ^~~~~~~~~~~~~~~~~~ 91:48: error: use of unresolved identifier 'centerXAnchor' imageView.centerXAnchor.constraint(equalTo: centerXAnchor), ^~~~~~~~~~~~~ 92:44: error: use of unresolved identifier 'topAnchor' imageView.topAnchor.constraint(equalTo: topAnchor, constant: 20), ^~~~~~~~~ 97:44: error: use of unresolved identifier 'centerXAnchor' label.centerXAnchor.constraint(equalTo: centerXAnchor), ^~~~~~~~~~~~~ 100:45: error: use of unresolved identifier 'centerXAnchor' button.centerXAnchor.constraint(equalTo: centerXAnchor), ^~~~~~~~~~~~~
最新发布
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值