根据其原始纯文本状态创建 UIButton 属性标题
Creating UIButton attributed title based on its original plain text state
我正在尝试创建一个 UIButton 的子类来强制执行文本字距调整。因此,当我在 Interface Builder 中构建按钮时,设置文本颜色(使用纯文本)我希望能够从普通 titleLabel
实例中获取现有文本、颜色、段落样式和字体并将其转换为具有相同属性的属性标签。
我写了两个我认为可能有帮助的类别:
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title fromExistingAttributedString:(NSAttributedString*)attributedString
{
NSDictionary *attributes = [attributedString attributesAtIndex:0 effectiveRange:NULL];
return [[NSMutableAttributedString alloc] initWithString:title attributes:attributes];
}
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title fromPlainTextLabel:(UILabel*)label
{
NSMutableAttributedString* mutableTitle = [[NSMutableAttributedString alloc] initWithString:title];
[mutableTitle addAttribute:NSFontAttributeName value:label.font range:[mutableTitle fullRange]];
[mutableTitle addAttribute:NSForegroundColorAttributeName value:label.textColor range:[mutableTitle fullRange]];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.alignment = label.textAlignment;
[mutableTitle addAttribute:NSParagraphStyleAttributeName value:style range:[mutableTitle fullRange]];
return mutableTitle;
}
然后在我的 UIButton 子类中,我像这样覆盖它们:
- (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle = [title mutableCopy];
[mutableTitle addAttributes:@{NSKernAttributeName: @(kDefaultKerning)} range:[mutableTitle fullRange]];
[super setAttributedTitle:mutableTitle forState:state];
[self setNeedsDisplay];
}
- (void)setTitle:(NSString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle;
if ([self attributedTitleForState:state]) {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title fromExistingAttributedString:[self attributedTitleForState:state]];
} else {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title fromPlainTextLabel:self.titleLabel];
}
[self setAttributedTitle:mutableTitle forState:state];
}
但有些东西不起作用 - 特别值得注意的是,[self attributedTitleForState:state]
和 [self titleForState:state]
似乎总是为零。在我看来,在 Interface Builder 中设置属性的方式有些不连贯,因为当文本通过 OK 时,它缺少所有样式。
终于成功了。事实证明,纯文本 UIButton 的多个属性位于多个位置。有些有直接从 UIButton 检索的辅助方法,有些没有。
- 字体:
self.titleLabel.font
(无辅助方法)
- 颜色:
[self titleColorForState:state]
- 正文:
[self titleForState:state]
- 属性文本:
[self attributedTitleForState]
并且纯文本 UIButton 默认情况下没有任何文本对齐方式,因为那是 controlled by content horizontal alignment。
因此,我更改了我的辅助方法(第一个是相同的,但我不得不更改第二个):
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title fromExistingAttributedString:(NSAttributedString*)attributedString
{
NSDictionary *attributes = [attributedString attributesAtIndex:0 effectiveRange:NULL];
return [[NSMutableAttributedString alloc] initWithString:title attributes:attributes];
}
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title font:(UIFont*)font color:(UIColor*)color
{
NSMutableAttributedString* mutableTitle = [[NSMutableAttributedString alloc] initWithString:title];
[mutableTitle addAttribute:NSFontAttributeName value:font range:[mutableTitle fullRange]];
[mutableTitle addAttribute:NSForegroundColorAttributeName value:color range:[mutableTitle fullRange]];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[mutableTitle addAttribute:NSParagraphStyleAttributeName value:style range:[mutableTitle fullRange]];
return mutableTitle;
}
我是这样实现的:
- (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle = [title mutableCopy];
[mutableTitle addAttributes:@{NSKernAttributeName: @(kDefaultKerning)} range:[mutableTitle fullRange]];
[super setAttributedTitle:mutableTitle forState:state];
[self setNeedsDisplay];
}
- (void)setTitle:(NSString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle;
if ([self attributedTitleForState:state]) {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title fromExistingAttributedString:[self attributedTitleForState:state]];
} else {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title font:self.titleLabel.font color:[self titleColorForState:state]];
}
[self setAttributedTitle:mutableTitle forState:state];
}
我正在尝试创建一个 UIButton 的子类来强制执行文本字距调整。因此,当我在 Interface Builder 中构建按钮时,设置文本颜色(使用纯文本)我希望能够从普通 titleLabel
实例中获取现有文本、颜色、段落样式和字体并将其转换为具有相同属性的属性标签。
我写了两个我认为可能有帮助的类别:
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title fromExistingAttributedString:(NSAttributedString*)attributedString
{
NSDictionary *attributes = [attributedString attributesAtIndex:0 effectiveRange:NULL];
return [[NSMutableAttributedString alloc] initWithString:title attributes:attributes];
}
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title fromPlainTextLabel:(UILabel*)label
{
NSMutableAttributedString* mutableTitle = [[NSMutableAttributedString alloc] initWithString:title];
[mutableTitle addAttribute:NSFontAttributeName value:label.font range:[mutableTitle fullRange]];
[mutableTitle addAttribute:NSForegroundColorAttributeName value:label.textColor range:[mutableTitle fullRange]];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.alignment = label.textAlignment;
[mutableTitle addAttribute:NSParagraphStyleAttributeName value:style range:[mutableTitle fullRange]];
return mutableTitle;
}
然后在我的 UIButton 子类中,我像这样覆盖它们:
- (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle = [title mutableCopy];
[mutableTitle addAttributes:@{NSKernAttributeName: @(kDefaultKerning)} range:[mutableTitle fullRange]];
[super setAttributedTitle:mutableTitle forState:state];
[self setNeedsDisplay];
}
- (void)setTitle:(NSString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle;
if ([self attributedTitleForState:state]) {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title fromExistingAttributedString:[self attributedTitleForState:state]];
} else {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title fromPlainTextLabel:self.titleLabel];
}
[self setAttributedTitle:mutableTitle forState:state];
}
但有些东西不起作用 - 特别值得注意的是,[self attributedTitleForState:state]
和 [self titleForState:state]
似乎总是为零。在我看来,在 Interface Builder 中设置属性的方式有些不连贯,因为当文本通过 OK 时,它缺少所有样式。
终于成功了。事实证明,纯文本 UIButton 的多个属性位于多个位置。有些有直接从 UIButton 检索的辅助方法,有些没有。
- 字体:
self.titleLabel.font
(无辅助方法) - 颜色:
[self titleColorForState:state]
- 正文:
[self titleForState:state]
- 属性文本:
[self attributedTitleForState]
并且纯文本 UIButton 默认情况下没有任何文本对齐方式,因为那是 controlled by content horizontal alignment。
因此,我更改了我的辅助方法(第一个是相同的,但我不得不更改第二个):
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title fromExistingAttributedString:(NSAttributedString*)attributedString
{
NSDictionary *attributes = [attributedString attributesAtIndex:0 effectiveRange:NULL];
return [[NSMutableAttributedString alloc] initWithString:title attributes:attributes];
}
+ (NSMutableAttributedString*)attributedStringWithTitle:(NSString*)title font:(UIFont*)font color:(UIColor*)color
{
NSMutableAttributedString* mutableTitle = [[NSMutableAttributedString alloc] initWithString:title];
[mutableTitle addAttribute:NSFontAttributeName value:font range:[mutableTitle fullRange]];
[mutableTitle addAttribute:NSForegroundColorAttributeName value:color range:[mutableTitle fullRange]];
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[mutableTitle addAttribute:NSParagraphStyleAttributeName value:style range:[mutableTitle fullRange]];
return mutableTitle;
}
我是这样实现的:
- (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle = [title mutableCopy];
[mutableTitle addAttributes:@{NSKernAttributeName: @(kDefaultKerning)} range:[mutableTitle fullRange]];
[super setAttributedTitle:mutableTitle forState:state];
[self setNeedsDisplay];
}
- (void)setTitle:(NSString *)title forState:(UIControlState)state
{
NSMutableAttributedString* mutableTitle;
if ([self attributedTitleForState:state]) {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title fromExistingAttributedString:[self attributedTitleForState:state]];
} else {
mutableTitle = [NSMutableAttributedString attributedStringWithTitle:title font:self.titleLabel.font color:[self titleColorForState:state]];
}
[self setAttributedTitle:mutableTitle forState:state];
}