UILabel、UITextView中的attributedText

問題描述

給UILabel設置了highlightedTextColor屬性,在執行label.highlighted = YES后,label并不顯示highlightedTextColor對應的顏色。

發現問題

翻閱代碼,發現此label并非用text來賦值顯示的文本,而是使用attributedText。經過嘗試,發現導致問題的原因是初始化attributedTextNSForegroundColorAttributeName對應的UIColor跟此label的textColor不一致,當兩者一樣的時,highlightedTextColor才有作用。

挖掘問題

查找文檔,UILabelattributedText屬性,有如下解釋

Discussion

This property is nil by default.

Assigning a new value to this property also replaces the value of the text property with the same string data, although without any formatting information. In addition, assigning a new a value updates the values in the font, textColor, and other style-related properties so that they reflect the style information starting at location 0 in the attributed string.

當給attributedText屬性賦值的時候,會影響到textfonttextColor等屬性,本文主要對textColor做一些深入的了解。

寫些代碼來驗證一下

代碼如下:

- (void)attributedStringOfInputUI {
    UILabel *label = [UILabel new];
    label.textColor = [UIColor blueColor];
    label.highlightedTextColor = [UIColor redColor];
    label.attributedText = ({
        NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
                                                       initWithString:@"Hello,World!"
                                                       attributes:@{
                                                                    NSForegroundColorAttributeName : [UIColor grayColor]
                                                                    }];
        [attributedString appendAttributedString:[[NSAttributedString alloc]
                                                  initWithString:@"Again!"
                                                  attributes:@{
                                                               NSForegroundColorAttributeName : [UIColor blueColor]
                                                               }]];
        [attributedString appendAttributedString:[[NSAttributedString alloc]
                                                  initWithString:@"Again!"
                                                  attributes:@{
                                                               NSForegroundColorAttributeName : [UIColor blueColor]
                                                               }]];
        attributedString;
    });
    label.highlighted = YES;
    [self.view addSubview:label];
    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self.view);
    }];
    
    self.label = label;

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    [button setTitle:@"添加文本" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(appendString) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    [button mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view);
        make.bottom.equalTo(self.view).offset(-90);
    }];
    
    UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
    [button2 setTitle:@"改變highlightedTextColor" forState:UIControlStateNormal];
    [button2 addTarget:self action:@selector(changeHighlightedTextColor) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button2];
    [button2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view);
        make.bottom.equalTo(self.view).offset(-60);
    }];
    
    UIButton *button3 = [UIButton buttonWithType:UIButtonTypeSystem];
    [button3 setTitle:@"改變TextColor" forState:UIControlStateNormal];
    [button3 addTarget:self action:@selector(changeTextColor) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button3];
    [button3 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.view);
        make.bottom.equalTo(self.view).offset(-30);
    }];
}
- (void)appendString {
    NSMutableAttributedString *attributedString = self.label.attributedText.mutableCopy;

    [attributedString appendAttributedString:[[NSAttributedString alloc]
                                              initWithString:@"Again!"
                                              attributes:@{
                                                           NSForegroundColorAttributeName : self.label.textColor
                                                           }]];
    [attributedString appendAttributedString:[[NSAttributedString alloc]
                                              initWithString:@"Again!"
                                              attributes:@{
                                                           NSForegroundColorAttributeName : [UIColor blueColor]
                                                           }]];
    self.label.attributedText = attributedString;
}

- (void)changeHighlightedTextColor {
    self.label.highlightedTextColor = [UIColor greenColor];
}
- (void)changeTextColor {
    self.label.textColor = [UIColor grayColor];
    self.label.highlighted = !self.label.highlighted;
}
  • 初始化UILabel,設置textColor[UIColor blueColor],設置highlightedTextColor[UIColor redColor],然后給attributedText賦值,并設置highlightedYES,運行之后,結果界面如下:


    可以看到,attributedText中顏色值為[UIColor blueColor]的字段,顏色變成了highlightedTextColor的顏色,即顏色跟textColor一樣的字段會響應highlighted屬性的變化。
    attributedText被賦了新值,此時,label的textColor會收到影響,值會跟attributedText開頭字段(此處為Hello,Wolrd!)的樣式統一,即[UIColor grayColor]

  • 那此時,再給attributedText賦值時,是否是顏色值為[UIColor grayColor]的字段會響應highlighted屬性,點擊按鈕,執行appendString來驗證一下,結果界面如下:


    跟設想的不一樣,依然是顏色為[UIColor blueColor]的字段響應了highlighted屬性,不過驗證了textColor確實變成了[UIColor grayColor]
    此處猜想,在設置textColor時,UILabel內部有個私有屬性保存了這個值,當設置attributedText時,只會改變textColor,不會改變這個私有屬性,這個私有屬性來判斷attributedText中哪些字段需要響應highlighted

  • 改變highlightedTextColor,又會有什么影響,點擊按鈕,運行changeHighlightedTextColor,效果界面如下:


    由此可見,只是改變了highlightedTextColor,沒有其他事先沒有預想到的問題。

  • 改變textColor,從文檔可以看出,將會改變attributedText中所有字段的顏色顯示,也可以預料,改變之后,attributedText中的所有字段都會響應highlighted

If you are using styled text, assigning a new value to this property causes the color to be applied to the entirety of the string in the attributedText property. If you want to apply the color to only a portion of the text, create a new attributed string with the desired style information and associate it with the label. If you are not using styled text, this property applies to the entire text string in the text property.

點擊按鈕,第一次運行changeTextColor,效果界面如下:

點擊按鈕,第二次運行changeTextColor,效果界面如下:

運行結果跟設想的一樣。

總結

到此,本次對attributedText的探索就結束了,fonttextColorattributedText都會互相影響,當只是給文本添加段落格式,或者實現統一字體顏色的文本和圖片的混合顯示,這種情況下,不建議通過NSFontAttributeNameNSForegroundColorAttributeName來定義字體大小和顏色顯示,應該直接設置fonttextColor,個人見解,歡迎討論。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容