2016-07-13 31 views
0

Ich habe NSAttributed String mit Links darin und ich möchte es in UILabel laden. Ich arbeite gut, aber alle Links sind blau.NSForegroundColorAttributeName für UILabel mit NSAttributedString

Keine Änderung der Vordergrundfarbe, Einstellung aller anderen Attribute funktioniert, wie durchgestrichen Stil. Nur Link bleibt immer blau.

NSAverteilte Zeichenfolge wird aus HTML generiert, wenn dies einen Unterschied macht.

+0

es für mich funktioniert. Ist 'linkRange' korrekt? Vielleicht kann ich es nicht bekommen, weil ich nicht aus HTML generieren – bradkratky

+0

Haben Sie versucht, die TintColor des Etiketts zu ändern: http://StackOverflow.com/A/33431102/1801544? – Larme

Antwort

0

class AttributedTextLabel:UILabel { 

var attributedString:NSAttributedString?{ 
    didSet{ 
     guard let attributedString = attributedString else { 
      return 
     } 
     let mutableAttributedString = NSMutableAttributedString(attributedString: attributedString) 

     mutableAttributedString.enumerateAttribute(NSLinkAttributeName, inRange: NSRange(location: 0, length: attributedString.length), options: NSAttributedStringEnumerationOptions.Reverse) {[weak self] (attribute, range, other) in 

      if let url = attribute as? NSURL { 
       mutableAttributedString.removeAttribute(NSLinkAttributeName, range: range) 
       self?.links.append(Link(url: url, range: range)) 
      } 
     } 
     self.attributedText = mutableAttributedString 

    } 
} 

struct Link { 
    var url:NSURL 
    var range:NSRange 
} 

var links:[Link] = [] 

var edgeInsets:UIEdgeInsets = UIEdgeInsetsZero 

private var textContentSize:CGSize { 
    let textContainerWidth = frame.width - edgeInsets.left - edgeInsets.right 
    let textContainerHeight = frame.height - edgeInsets.top - edgeInsets.bottom 

    return CGSizeMake(textContainerWidth, textContainerHeight) 
} 


func characterIndexAtPoint(point:CGPoint) -> Int? { 
    guard let attributedText = attributedText else { 
     return nil 
    } 

    let layoutManager = NSLayoutManager() 
    let textContainer = NSTextContainer(size: textContentSize) 

    textContainer.lineFragmentPadding = 0.0 
    textContainer.lineBreakMode = self.lineBreakMode 
    textContainer.maximumNumberOfLines = self.numberOfLines 
    layoutManager.addTextContainer(textContainer) 

    let storage = NSTextStorage(attributedString: attributedText) 
    storage.addLayoutManager(layoutManager) 
    let adjustedPoint = CGPointMake(point.x-edgeInsets.left, point.y-edgeInsets.top) 

    let characterIndex = layoutManager.characterIndexForPoint(point, inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil) 

    return characterIndex 
} 

override func drawTextInRect(rect: CGRect) { 
    return super.drawTextInRect(UIEdgeInsetsInsetRect(rect, edgeInsets)) 
} 

private var selectedRange:NSRange? 

private var highligtedLink:Link? { 
    didSet{ 
     let string = self.attributedText as! NSMutableAttributedString 
     if let oldValue = oldValue { 
      if let selectedLinkColor = NativeTextKit.TextAttributes.selectedLinkColor.value { 
       string.addAttributes([ 
        NSForegroundColorAttributeName:selectedLinkColor 
        ], range: oldValue.range) 
      } 
     } 

     if let highligtedLink = highligtedLink { 
      if let selectedLinkColor = NativeTextKit.TextAttributes.selectedLinkColor.value { 
       string.addAttributes([ 
        NSForegroundColorAttributeName:selectedLinkColor 
        ], range: highligtedLink.range) 
      } 
     } 

     self.attributedText = string 
    } 
} 

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    guard let touch = touches.first else { 
     return 
    } 
    let char = characterIndexAtPoint(touch.locationInView(self)) 
    let string = self.attributedText as! NSMutableAttributedString 

    highligtedLink = linkForTouch(touch) 

    string.addAttributes([ 
     NSForegroundColorAttributeName:UIColor.brownColor() 
     ], range: NSMakeRange(char!, 1)) 

    attributedText = string 
} 

func linkForTouch(touch:UITouch)->Link? { 
    guard let attributedText = attributedText else { 
     return nil 
    } 
    guard let characterIndex = characterIndexAtPoint(touch.locationInView(self)) else { 
     return nil 
    } 
    return links.filter({NSLocationInRange(characterIndex, $0.range)}).first 
} 

override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) { 
    highligtedLink = nil 
} 

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    guard let touch = touches.first else { 
     return 
    } 
    if let highligtedLink = highligtedLink, let lastTouchedLink = linkForTouch(touch) where highligtedLink.url == lastTouchedLink.url { 
     urlInteractionHandler?(textView: UITextView(), url:lastTouchedLink.url) 
    } 

} 

/// Executed on link interaction 
var urlInteractionHandler:URLInteractionHandler? 
} 

den Job Ended up Does, dauerte eine Weile, um herauszufinden. Da UILabel seine eigenen Link-Formatierung

  • Entfernen Sie alle Links von einem zurück String endete hat einmal Zeichenfolge gesetzt
  • Links hinzufügen und reicht bis zu Array
  • Nach Link ausgewählt Verwendung NSTextContainer um herauszufinden, was Index den Charakter dieser Charakter war
  • Suche Bereich gehört
  • Return Link