UILabel(QMUI)

@interface UILabel (QMUI)

- (instancetype)qmui_initWithFont:(nullable UIFont *)font textColor:(nullable UIColor *)textColor;

/**
 * @brief 在需要特殊样式时,可通过此属性直接给整个 label 添加 NSAttributeName 系列样式,然后 setText 即可,无需使用繁琐的 attributedText
 *
 * @note 即使先调用 setText/attributedText ,然后再设置此属性,此属性仍然会生效
 * @note 如果此属性包含了 NSKernAttributeName ,则最后一个字的 kern 效果会自动被移除,否则容易导致文字在视觉上不居中
 *
 * @note 当你设置了此属性后,每次你调用 setText: 时,其实都会被自动转而调用 setAttributedText:
 *
 * 现在你有三种方法控制 label 的样式:
 * 1. 本身的样式属性(如 textColor, font 等)
 * 2. qmui_textAttributes
 * 3. 构造 NSAttributedString
 * 这三种方式可以同时使用,如果样式发生冲突(比如先通过方法1将文字设成红色,又通过方法2将文字设成蓝色),则绝大部分情况下代码执行顺序靠后的会最终生效
 * 唯一例外的极端情况是:先用方法2将文字设成红色,再用方法1将文字设成蓝色,最后再 setText,这时虽然代码执行顺序靠后的是方法1,但最终生效的会是方法2,为了避免这种极端情况的困扰,建议不要同时使用方法1和方法2去设置同一种样式。
 *
 */
@property(nullable, nonatomic, copy) NSDictionary<NSAttributedStringKey, id> *qmui_textAttributes;

/** 
 *  Setter 设置当前整段文字的行高
 *  @note 如果同时通过 qmui_textAttributes 或 attributedText 给整段文字设置了行高,则此方法将不再生效。换句话说,此方法设置的行高将永远不会覆盖 qmui_textAttributes 或 attributedText 设置的行高。
 *  @note 比如对于字符串"abc",你通过 attributedText 设置 {0, 1} 这个 range 范围内的行高为 10,又通过 setQmui_lineHeight: 设置了整体行高为 20,则最终 {0, 1} 内的行高将为 10,而 {1, 2} 内的行高将为全局行高 20
 *  @note 比如对于字符串"abc",你先通过 setQmui_lineHeight: 设置整体行高为 10,又通过 attributedText/qmui_textAttributes 设置整体行高为 20,无论这两个设置的代码的先后顺序如何,最终行高都将为 20
 *  @note 你可以通过设置 'QMUILineHeightIdentity' 来恢复 UILabel 默认的行高
 *  @note 当你设置了此属性后,每次你调用 setText: 时,其实都会被自动转而调用 setAttributedText:
 *
 *  -----------------------------------
 *
 *  Getter 获取整段文字的行高
 *  @note 如果通过 setQmui_lineHeight 设置行高,会优先返回该值。
 *  @note 如果通过 NSParagraphStyleAttributeName 设置了行高,同时 range 是整段文字,则会返回 paraStyle.maximumLineHeight。
 *  @note 如果通过 setText 设置文本,会返回 font.lineHeight。
 *  @warning 除上述情况外,计算的数值都可能不准确,会返回 0。
 *
 */

@property(nonatomic, assign) CGFloat qmui_lineHeight;

/**
 * 将目标UILabel的样式属性设置到当前UILabel上
 *
 * 将会复制的样式属性包括:font、textColor、backgroundColor
 * @param label 要从哪个目标UILabel上复制样式
 */
- (void)qmui_setTheSameAppearanceAsLabel:(UILabel *)label;

/**
 * 在UILabel的样式(如字体)设置完后,将label的text设置为一个测试字符,再调用sizeToFit,从而令label的高度适应字体
 * @warning 会setText:,因此确保在配置完样式后、设置text之前调用
 */
- (void)qmui_calculateHeightAfterSetAppearance;

/**
 * UILabel在显示中文字符时,会比显示纯英文字符额外多了一个sublayers,并且这个layer超出了label.bounds的范围,这会导致label必定需要做像素合成,所以通过一些方式来避免合成操作
 * @see http://stackoverflow.com/questions/34895641/uilabel-is-marked-as-red-when-color-blended-layers-is-selected
 */
- (void)qmui_avoidBlendedLayersIfShowingChineseWithBackgroundColor:(UIColor *)color;

@end

Undocumented

  • Undocumented

    Declaration

    Objective-C

    - (instancetype)qmui_initWithFont:(nullable UIFont *)font textColor:(nullable UIColor *)textColor;

    Swift

    func qmui_init(with font: UIFont?, textColor: UIColor?) -> Self
  • @brief 在需要特殊样式时,可通过此属性直接给整个 label 添加 NSAttributeName 系列样式,然后 setText 即可,无需使用繁琐的 attributedText

    Note

    即使先调用 setText/attributedText ,然后再设置此属性,此属性仍然会生效

    Note

    如果此属性包含了 NSKernAttributeName ,则最后一个字的 kern 效果会自动被移除,否则容易导致文字在视觉上不居中

    Note

    当你设置了此属性后,每次你调用 setText: 时,其实都会被自动转而调用 setAttributedText:

    现在你有三种方法控制 label 的样式:

    1. 本身的样式属性(如 textColor, font 等)
    2. qmui_textAttributes
    3. 构造 NSAttributedString 这三种方式可以同时使用,如果样式发生冲突(比如先通过方法1将文字设成红色,又通过方法2将文字设成蓝色),则绝大部分情况下代码执行顺序靠后的会最终生效 唯一例外的极端情况是:先用方法2将文字设成红色,再用方法1将文字设成蓝色,最后再 setText,这时虽然代码执行顺序靠后的是方法1,但最终生效的会是方法2,为了避免这种极端情况的困扰,建议不要同时使用方法1和方法2去设置同一种样式。

    Declaration

    Objective-C

    @property (nonatomic, copy, nullable) NSDictionary<NSAttributedStringKey, id> *qmui_textAttributes;

    Swift

    var qmui_textAttributes: [NSAttributedString.Key : Any]? { get set }
  • Setter 设置当前整段文字的行高

    Note

    如果同时通过 qmui_textAttributes 或 attributedText 给整段文字设置了行高,则此方法将不再生效。换句话说,此方法设置的行高将永远不会覆盖 qmui_textAttributes 或 attributedText 设置的行高。

    Note

    比如对于字符串"abc",你通过 attributedText 设置 {0, 1} 这个 range 范围内的行高为 10,又通过 setQmui_lineHeight: 设置了整体行高为 20,则最终 {0, 1} 内的行高将为 10,而 {1, 2} 内的行高将为全局行高 20

    Note

    比如对于字符串"abc",你先通过 setQmui_lineHeight: 设置整体行高为 10,又通过 attributedText/qmui_textAttributes 设置整体行高为 20,无论这两个设置的代码的先后顺序如何,最终行高都将为 20

    Note

    你可以通过设置 ‘QMUILineHeightIdentity’ 来恢复 UILabel 默认的行高

    Note

    当你设置了此属性后,每次你调用 setText: 时,其实都会被自动转而调用 setAttributedText:

    Getter 获取整段文字的行高

    Note

    如果通过 setQmui_lineHeight 设置行高,会优先返回该值。

    Note

    如果通过 NSParagraphStyleAttributeName 设置了行高,同时 range 是整段文字,则会返回 paraStyle.maximumLineHeight。

    Note

    如果通过 setText 设置文本,会返回 font.lineHeight。

    Warning

    除上述情况外,计算的数值都可能不准确,会返回 0。

    Declaration

    Objective-C

    @property (nonatomic) CGFloat qmui_lineHeight;

    Swift

    var qmui_lineHeight: CGFloat { get set }
  • 将目标UILabel的样式属性设置到当前UILabel上

    将会复制的样式属性包括:font、textColor、backgroundColor

    Declaration

    Objective-C

    - (void)qmui_setTheSameAppearanceAsLabel:(nonnull UILabel *)label;

    Swift

    func qmui_setTheSameAppearance(as label: UILabel)

    Parameters

    label

    要从哪个目标UILabel上复制样式

  • 在UILabel的样式(如字体)设置完后,将label的text设置为一个测试字符,再调用sizeToFit,从而令label的高度适应字体

    Warning

    会setText:,因此确保在配置完样式后、设置text之前调用

    Declaration

    Objective-C

    - (void)qmui_calculateHeightAfterSetAppearance;

    Swift

    func qmui_calculateHeightAfterSetAppearance()
  • UILabel在显示中文字符时,会比显示纯英文字符额外多了一个sublayers,并且这个layer超出了label.bounds的范围,这会导致label必定需要做像素合成,所以通过一些方式来避免合成操作

    Declaration

    Objective-C

    - (void)qmui_avoidBlendedLayersIfShowingChineseWithBackgroundColor:
        (nonnull UIColor *)color;

    Swift

    func qmui_avoidBlendedLayersIfShowingChinese(withBackgroundColor color: UIColor)