根据其原始纯文本状态创建UIButton属性标题

时间:2015-10-01 23:01:10

标签: ios objective-c uibutton interface-builder nsattributedstring

我试图创建一个UIButton的子类来强制执行文本字距调整。因此,当我在Interface Builder中构建一个按钮时,设置文本颜色(使用纯文本)我希望能够从普通{{1}中获取现有的文本,颜色,段落样式和字体。实例并将其转换为具有相同属性的属性标签。

我写了两个我认为可能有帮助的类别:

titleLabel

然后在我的UIButton子类中,我会像这样覆盖这些:

+ (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;
}

但是有些东西没有用 - 特别值得注意的是,- (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]似乎总是零。在我看来,在Interface Builder中设置属性的方式存在一些脱节,因为当文本通过OK时,所有样式都缺失了。

1 个答案:

答案 0 :(得分:1)

终于有了这个工作。事实证明,纯文本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];
}