Как настроить кернинг текста с помощью Interface Builder в Xcode 7?

Есть множество настроек для NSAttributedParagraphStyle, которые я вижу в Interface Builder:

Но ни один из них не предназначен для кернинга текста. Есть ли способ настроить кернинг текста в Xcode 7 Interface Builder для атрибутированного текста?

(Пожалуйста, не отвечайте, как это сделать в коде — я уже знаю, как это сделать!)


person brandonscript    schedule 28.09.2015    source источник
comment
Вы когда-нибудь находили способ? Это кажется заметным в его отсутствии.   -  person Dov    schedule 07.10.2015
comment
@Dov нет ... действительно!   -  person brandonscript    schedule 07.10.2015


Ответы (5)


На самом деле вы можете сделать это без использования подкласса через расширение.

import UIKit

@IBDesignable
extension UILabel {
    @IBInspectable
    public var kerning:CGFloat {
        set{
            if let currentAttibutedText = self.attributedText {
                let attribString = NSMutableAttributedString(attributedString: currentAttibutedText)
                attribString.addAttributes([NSKernAttributeName:newValue], range:NSMakeRange(0, currentAttibutedText.length))
                self.attributedText = attribString
            }
        } get {
            var kerning:CGFloat = 0
            if let attributedText = self.attributedText {
                attributedText.enumerateAttribute(NSKernAttributeName,
                                                  in: NSMakeRange(0, attributedText.length),
                                                  options: .init(rawValue: 0)) { (value, range, stop) in
                                                    kerning = value as? CGFloat ?? 0
                }
            }
            return kerning
        }
    }
}

введите описание изображения здесь

Хотя на самом деле это не будет отображаться в конструкторе интерфейсов, оно будет отображаться и работать, когда вы запускаете свое приложение.

person robertwalsh    schedule 16.02.2017

Создайте подкласс UILabel, назовите его KerningLabel, чтобы он состоял из следующего кода:

import UIKit

@IBDesignable
class KerningLabel: UILabel {

    @IBInspectable var kerning: CGFloat = 0.0 {
        didSet {
            if attributedText?.length == nil { return }

            let attrStr = NSMutableAttributedString(attributedString: attributedText!)
            let range = NSMakeRange(0, attributedText!.length)
            attrStr.addAttributes([NSAttributedStringKey.kern: kerning], range: range)
            attributedText = attrStr
        }
    }
}

Перетащите этикетку. Измените его на свой подкласс UILabel. Отрегулируйте кернинг по желанию. введите здесь описание изображения

В объект-с:

.h

IB_DESIGNABLE
@interface KerningLabel : UILabel

@property (nonatomic) IBInspectable CGFloat kerning;

@end

.m

@implementation KerningLabel

- (void)setKerning:(CGFloat)kerning
{
    _kerning = kerning;
    if(self.attributedText)
    {
        NSMutableAttributedString *attribString = [[NSMutableAttributedString alloc]initWithAttributedString:self.attributedText];
        [attribString addAttribute:NSKernAttributeName value:@(kerning) range:NSMakeRange(0, self.attributedText.length)];
        self.attributedText = attribString;
    }
}

@конец

person beyowulf    schedule 13.12.2015
comment
Очевидно, что это не нативный вариант, но довольно приятное решение! Хороший. - person brandonscript; 13.12.2015
comment
Я ищу версию того же кода на Objective-C! Я не знаю, как преобразовать это в ObjC - person Randika Vishman; 15.06.2016
comment
@KasunRandika См. здесь - person beyowulf; 15.06.2016
comment
О Отлично, спасибо! Я уже что-то пробовал, и у меня не получилось, так что поместите это [на SO здесь.] [1] Если вы можете, пожалуйста, ответьте и на это. Но, кажется, теперь я уже знаю ответ на свой вопрос! [1]: stackoverflow.com/questions/ 37826749/ - person Randika Vishman; 15.06.2016

Свифт 4 код:

@IBDesignable
extension UILabel {
@IBInspectable
public var kerning:CGFloat {
    set{
        if let currentAttibutedText = self.attributedText {
            let attribString = NSMutableAttributedString(attributedString: currentAttibutedText)
            attribString.addAttributes([NSAttributedStringKey.kern:newValue], range:NSMakeRange(0, currentAttibutedText.length))
            self.attributedText = attribString
        }
    } get {
        var kerning:CGFloat = 0
        if let attributedText = self.attributedText {
            attributedText.enumerateAttribute(NSAttributedStringKey.kern,
                                              in: NSMakeRange(0, attributedText.length),
                                              options: .init(rawValue: 0)) { (value, range, stop) in
                                                kerning = value as? CGFloat ?? 0
            }
        }
        return kerning
    }
}
}
person George    schedule 29.06.2018

Сокращенная попытка:

@IBDesignable class KerningLabel: UILabel {


  @IBInspectable var kerning: CGFloat = 0.0 {
    didSet {
      let attrStr = NSMutableAttributedString(string: "Foobar")
      attrStr.addAttributes([NSKernAttributeName: kerning],
                            range: NSMakeRange(0, attrStr.string.characters.count))
      attributedText = attrStr
    }
  }
}
person aBikis    schedule 15.05.2017

Свифт 5

Расширение UILabel:

@IBDesignable
extension UILabel {
    @IBInspectable
      var letterSpace: CGFloat {
          set {
              let attributedString: NSMutableAttributedString!
              if let currentAttrString = attributedTitle(for: .normal) {
                  attributedString = NSMutableAttributedString(attributedString: currentAttrString)
              }
              else {
                  attributedString = NSMutableAttributedString(string: self.titleLabel?.text ?? "")
                  setTitle(.none, for: .normal)
              }

              attributedString.addAttribute(NSKernAttributeName,
                                             value: newValue,
                                             range: NSRange(location: 0, length: attributedString.length))

              setAttributedTitle(attributedString, for: .normal)
          }

          get {
              if let currentLetterSpace = attributedTitle(for: .normal)?.attribute(NSKernAttributeName, at: 0, effectiveRange: .none) as? CGFloat {
                  return currentLetterSpace
              }
              else {
                  return 0
              }
          }
      }
}

Расширение UIButton

    extension UIButton{
          @IBInspectable
          var letterSpace: CGFloat {
              set {
                  let attributedString: NSMutableAttributedString!
                  if let currentAttrString = attributedTitle(for: .normal) {
                      attributedString = NSMutableAttributedString(attributedString: currentAttrString)
                  }
                  else {
                      attributedString = NSMutableAttributedString(string: self.titleLabel?.text ?? "")
                      setTitle(.none, for: .normal)
                  }
    
                attributedString.addAttribute(NSAttributedString.Key.kern,
                                                 value: newValue,
                                                 range: NSRange(location: 0, length: attributedString.length))
    
                  setAttributedTitle(attributedString, for: .normal)
              }
    
              get {
                if let currentLetterSpace = attributedTitle(for: .normal)?.attribute(NSAttributedString.Key.kern, at: 0, effectiveRange: .none) as? CGFloat {
                      return currentLetterSpace
                  }
                  else {
                      return 0
                  }
              }
          }
}
person Sourabh Sharma    schedule 08.07.2020