Est-il possible de changer l'espacement des caractères (piste) sur le texte UILabel à l'aide d'Interface Builder? Sinon, y a-t-il un moyen de le faire par programme sur un UILabel existant déjà créé avec du texte attribué?
Nous avons fini par utiliser ceci pour le moment pour obtenir le texte attribué existant et modifier pour ajouter un espacement des caractères:
let attributedString = discoveryTitle.attributedText as NSMutableAttributedString
attributedString.addAttribute(NSKernAttributeName, value: 1.0, range: NSMakeRange(0, attributedString.length))
discoveryTitle.attributedText = attributedString
Swift 3:
let attributedString = NSMutableAttributedString(string: discoveryTitle.text)
attributedString.addAttribute(NSKernAttributeName, value: CGFloat(1.0), range: NSRange(location: 0, length: attributedString.length))
discoveryTitle.attributedText = attributedString
Utiliser NSRange au lieu de NSMakeRange fonctionne dans Swift 3.
Je sais que ce n'est pas une solution d'Interface Builder, mais vous pouvez créer une extension UILabel
, puis ajouter un espacement à n'importe quel UILabel
de votre choix:
extension UILabel {
func addCharacterSpacing(kernValue: Double = 1.15) {
if let labelText = text, labelText.count > 0 {
let attributedString = NSMutableAttributedString(string: labelText)
attributedString.addAttribute(NSAttributedStringKey.kern, value: kernValue, range: NSRange(location: 0, length: attributedString.length - 1))
attributedText = attributedString
}
}
}
Envisagez de modifier la valeur par défaut kernValue
de 1.15
à quelque chose qui fonctionne mieux avec votre conception.
Lors de la mise en œuvre toujours, ajoutez un espacement des caractères après avoir défini la valeur du texte:
myLabel.text = "We used to be so close"
myLabel.addCharacterSpacing()
Si vous envisagez d'avoir un espacement différent à différents endroits de l'application, vous pouvez remplacer la valeur de kern par défaut:
myLabelWithSpecialNeeds.addCharacterSpacing(kernValue: 1.3)
Pour un texte complètement statique , comme l’en-tête d’une vue ou plus particulièrement le launchScreen , vous pouvez insérer des lettres d’une largeur minime (par exemple, le caractère 'l') avec 0 opacity
. Vous pouvez également définir la même couleur que l'arrière-plan.
Je suis conscient du fait que ce n'est pas la solution la plus jolie, mais c'est la seule solution qui fonctionne sans écrire de code et qui fait le travail - jusqu'à ce que vous puissiez le faire en spécifiant les attributs dans Xcode.
Éditer/Idée supplémentaire: Pour que votre espacement soit encore plus variable, vous pouvez modifier la taille de la police des caractères de remplissage entre les deux. (Merci à @ mohamede1945 pour cette idée)
Swift 3.2 et constructeur d'interface
extension UILabel {
@IBInspectable
var letterSpace: CGFloat {
set {
let attributedString: NSMutableAttributedString!
if let currentAttrString = attributedText {
attributedString = NSMutableAttributedString(attributedString: currentAttrString)
}
else {
attributedString = NSMutableAttributedString(string: text ?? "")
text = nil
}
attributedString.addAttribute(NSKernAttributeName,
value: newValue,
range: NSRange(location: 0, length: attributedString.length))
attributedText = attributedString
}
get {
if let currentLetterSpace = attributedText?.attribute(NSKernAttributeName, at: 0, effectiveRange: .none) as? CGFloat {
return currentLetterSpace
}
else {
return 0
}
}
}
}
essaye ça!!
créer une classe CustomLabel
@interface CustomLabel : UILabel
@property (assign, nonatomic) CGFloat myLineSpacing;
@end
@implementation CustomLabel
- (void)setMyLineSpacing:(CGFloat)myLineSpacing {
_myLineSpacing = myLineSpacing;
self.text = self.text;
}
- (void)setText:(NSString *)text {
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = _myLineSpacing;
paragraphStyle.alignment = self.textAlignment;
NSDictionary *attributes = @{NSParagraphStyleAttributeName: paragraphStyle};
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text
attributes:attributes];
self.attributedText = attributedText;
}
et définir l'attribut d'exécution
Note c'est en fait interligne (aussi appelé interligne .. dans les temps très anciens (pré-numérique), vous Je mettrais du plomb (le métal) entre les lignes pour augmenter l’écart entre les lignes. Pour l'espacement entre les lettres, cela s'appelle kerning .. voici comment faire le crénage https://stackoverflow.com/a/21141156/ 294884
Pourquoi vous définissez tous NSMUTABLEAttributedString. Vous n'êtes pas obligé de définir explicitement la plage. Les emojis ont parfois l’air bizarre. Ceci est ma solution, testé dans Swift 4. ????
extension UILabel {
func addCharactersSpacing(_ value: CGFloat = 1.15) {
if let textString = text {
let attrs: [NSAttributedStringKey : Any] = [.kern: value]
attributedText = NSAttributedString(string: textString, attributes: attrs)
}
}
}
Inspiré par la réponse de budidinho, il s'agit d'une solution plus flexible lorsque vous souhaitez modifier l'espacement des étiquettes avec des interlignes différents. Au lieu d'aller à l'intérieur de la fonction et de changer la valeur, vous pouvez simplement la passer en tant que paramètre.
extension UILabel {
func setTextSpacingBy(value: Double) {
if let textString = self.text {
let attributedString = NSMutableAttributedString(string: textString)
attributedString.addAttribute(NSKernAttributeName, value: value, range: NSRange(location: 0, length: attributedString.length - 1))
attributedText = attributedString
}
}
}
Swift 4 Extension UILabel:
import UIKit
extension UILabel {
@IBInspectable
var letterSpace: CGFloat {
set {
let attributedString: NSMutableAttributedString!
if let currentAttrString = attributedText {
attributedString = NSMutableAttributedString(attributedString: currentAttrString)
} else {
attributedString = NSMutableAttributedString(string: text ?? "")
text = nil
}
attributedString.addAttribute(NSAttributedString.Key.kern,
value: newValue,
range: NSRange(location: 0, length: attributedString.length))
attributedText = attributedString
}
get {
if let currentLetterSpace = attributedText?.attribute(NSAttributedString.Key.kern, at: 0, effectiveRange: .none) as? CGFloat {
return currentLetterSpace
} else {
return 0
}
}
}
}
Voici une solution pour Swift 4 qui ne remplacera pas les attributs de texte existants:
extension UILabel {
/**
Add kerning to a UILabel's existing `attributedText`
- note: If `UILabel.attributedText` has not been set, the `UILabel.text`
value will be returned from `attributedText` by default
- note: This method must be called each time `UILabel.text` or
`UILabel.attributedText` has been set
- parameter kernValue: The value of the kerning to add
*/
func addKern(_ kernValue: CGFloat) {
guard let attributedText = attributedText,
attributedText.string.count > 0,
let fullRange = attributedText.string.range(of: attributedText.string) else {
return
}
let updatedText = NSMutableAttributedString(attributedString: attributedText)
updatedText.addAttributes([
.kern: kernValue
], range: NSRange(fullRange, in: attributedText.string))
self.attributedText = updatedText
}
}
Essaye ça. Il ajoutera l’espacement des caractères que vous affectez, que vous définissiez un texte simple ou un texte attribué.
open class UHBCustomLabel : UILabel {
@IBInspectable open var characterSpacing:CGFloat = 1 {
didSet {
updateWithSpacing()
}
}
open override var text: String? {
set {
super.text = newValue
updateWithSpacing()
}
get {
return super.text
}
}
open override var attributedText: NSAttributedString? {
set {
super.attributedText = newValue
updateWithSpacing()
}
get {
return super.attributedText
}
}
func updateWithSpacing() {
let attributedString = self.attributedText == nil ? NSMutableAttributedString(string: self.text ?? "") : NSMutableAttributedString(attributedString: attributedText!)
attributedString.addAttribute(NSKernAttributeName, value: self.characterSpacing, range: NSRange(location: 0, length: attributedString.length))
super.attributedText = attributedString
}
}
Approche de programmation. (Essayez ceci, cela devrait fonctionner pour vous)
Note: J'ai testé dans Swift 4
let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))
label.attributedText = attrString
Vous pouvez utiliser l’extension Swift 4 UILabel suivante qui prend en compte le texte attribué existant et le texte brut afin de ne pas remplacer les paramètres existants:
import UIKit
extension UILabel {
func addCharacterSpacing(_ kernValue: Double = 1.30) {
guard let attributedString: NSMutableAttributedString = {
if let text = self.text, !text.isEmpty {
return NSMutableAttributedString(string: text)
} else if let attributedText = self.attributedText {
return NSMutableAttributedString(attributedString: attributedText)
}
return nil
}() else { return}
attributedString.addAttribute(
NSAttributedString.Key.kern,
value: kernValue,
range: NSRange(location: 0, length: attributedString.length)
)
self.attributedText = attributedString
}
}