2016-07-13 3 views
0

NSAttributedの文字列にリンクがあり、UILabelの中にロードします。私はうまく動作しますが、すべてのリンクは青色です。NSAttributedStringを使用しているUILabelのNSForegroundColorAttributeName

フォアグラウンドカラーは変更されず、他のすべてのアトリビュートが取り消し線のように設定されます。ちょうどリンクは常に青色のままです。

NSAttributed文字列は、違いがあればHTMLから生成されます。

+0

属します。 'linkRange'は正しいですか?たぶん、私はHTMLから生成していないので、私はそれを得ることができません – bradkratky

+0

ラベルのtintColorを変更しようとしました:http://stackoverflow.com/a/33431102/1801544? – Larme

答えて

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? 
} 

が仕事をしてやってしまっ把握する時間がかかりました。 UILabelは、書式設定、独自のリンクは

  • を終了しているため、文字列が
  • はリンクを追加設定し、リンクがどのようなインデックスを文字を把握するために使用NSTextContainerを選択した後、アレイ
  • の範囲でされると、属性付き文字列からすべてのリンクを削除します
  • 検索範囲だったその文字は
  • リターンリンクそれは私の作品
関連する問題