Border around every word of UILabel

后端 未结 4 705
天命终不由人
天命终不由人 2021-01-07 09:06

Is there a way i can draw border around every word of UILabel. Suppose UILabel contains the string \" This is the Line 1\".

I want 5 differ

4条回答
  •  一个人的身影
    2021-01-07 09:48

    I am not aware of an easy to use code for UILabel, but for UITextView:

    Swift playground

    setup:

    import UIKit
    
    let string = "Lorem ipsum dolor sit amet"
    
    let textView = UITextView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    textView.text = string
    

    use regular expressions get a match for every word:

    let pattern = "[a-zA-Z0-9]+"
    let regex = try! NSRegularExpression(pattern: pattern, options: [])
    let matches = regex.matchesInString(string, options: [], range: NSMakeRange(0, string.characters.count))
    

    function to get a rect for each match (ported from this answer):

    func frameOfTextInRange(range:NSRange, inTextView textView:UITextView) -> CGRect {
        let beginning = textView.beginningOfDocument
        let start = textView.positionFromPosition(beginning, offset: range.location)!
        let end = textView.positionFromPosition(start, offset: range.length)!
        let textRange = textView.textRangeFromPosition(start, toPosition: end)!
        let rect = textView.firstRectForRange(textRange)
        return textView.convertRect(rect, fromView: textView)
    }
    

    iterate over each match, get its frame, use it to create a view for the background, add it to the text view:

    for m in matches {
        let range = m.range
        let frame = frameOfTextInRange(range, inTextView: textView)
        let v = UIView(frame: frame)
        v.layer.borderWidth = 1
        v.layer.borderColor = UIColor.blueColor().CGColor
        textView.addSubview(v)
    
    }
    


    But possibly this doesn't give the result you were expecting. To get a better controls, you could use attributed strings.

    Here the same code with using attributed strings

    import UIKit
    
    let string = "Lorem ipsum dolor sit amet"
    
    let textView = UITextView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    
    let attributedString = NSMutableAttributedString(string: string)
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineHeightMultiple = 1.25
    attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, string.characters.count))
    
    textView.attributedText = attributedString
    
    let pattern = "[a-zA-Z0-9]+"
    let regex = try! NSRegularExpression(pattern: pattern, options: [])
    let matches = regex.matchesInString(string, options: [], range: NSMakeRange(0, string.characters.count))
    
    func frameOfTextInRange(range:NSRange, inTextView textView:UITextView) -> CGRect {
        let beginning = textView.beginningOfDocument
        let start = textView.positionFromPosition(beginning, offset: range.location)!
        let end = textView.positionFromPosition(start, offset: range.length)!
        let textRange = textView.textRangeFromPosition(start, toPosition: end)!
        let rect = textView.firstRectForRange(textRange)
        return textView.convertRect(rect, fromView: textView)
    }
    
    for m in matches {
        let range = m.range
        var frame = frameOfTextInRange(range, inTextView: textView)
        frame = CGRectInset(frame, CGFloat(-1.2), CGFloat(2))
        frame = CGRectOffset(frame, CGFloat(0), CGFloat(2))
        let v = UIView(frame: frame)
        v.layer.borderWidth = 1
        v.layer.borderColor = UIColor.blueColor().CGColor
        textView.addSubview(v)
    
    }
    


    Also helpful to create beautiful styles would be to add the views to a background view and add that textview on top

    import UIKit
    
    let string = "Lorem ipsum dolor sit amet"
    
    let textView = UITextView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    let textViewBG = UIView(frame: textView.bounds)
    textViewBG.backgroundColor = UIColor.whiteColor()
    let attributedString = NSMutableAttributedString(string: string)
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineHeightMultiple = 1.25
    attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, string.characters.count))
    attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.whiteColor(), range: NSMakeRange(0, string.characters.count))
    textView.attributedText = attributedString
    textView.backgroundColor = UIColor.clearColor()
    
    let pattern = "[a-zA-Z0-9]+"
    let regex = try! NSRegularExpression(pattern: pattern, options: [])
    let matches = regex.matchesInString(string, options: [], range: NSMakeRange(0, string.characters.count))
    
    func frameOfTextInRange(range:NSRange, inTextView textView:UITextView) -> CGRect {
        let beginning = textView.beginningOfDocument
        let start = textView.positionFromPosition(beginning, offset: range.location)!
        let end = textView.positionFromPosition(start, offset: range.length)!
        let textRange = textView.textRangeFromPosition(start, toPosition: end)!
        let rect = textView.firstRectForRange(textRange)
        return textView.convertRect(rect, fromView: textView)
    }
    
    for m in matches {
        let range = m.range
        var frame = frameOfTextInRange(range, inTextView: textView)
        frame = CGRectInset(frame, CGFloat(-1.2), CGFloat(2))
        frame = CGRectOffset(frame, CGFloat(0), CGFloat(2))
        let v = UIView(frame: frame)
        v.layer.cornerRadius = 2
        v.backgroundColor = UIColor(hue: 0.66, saturation: 0.6, brightness: 1, alpha: 1)
        textViewBG.addSubview(v)
    
    }
    textViewBG.addSubview(textView)
    


    to increase the space between the words we can alter the kerning of the whitespace

    import UIKit
    
    func frameOfTextInRange(range:NSRange, inTextView textView:UITextView) -> CGRect {
        let beginning = textView.beginningOfDocument
        let start = textView.positionFromPosition(beginning, offset: range.location)!
        let end = textView.positionFromPosition(start, offset: range.length)!
        let textRange = textView.textRangeFromPosition(start, toPosition: end)!
        let rect = textView.firstRectForRange(textRange)
        return textView.convertRect(rect, fromView: textView)
    }
    
    let string = "Lorem ipsum dolor sit amet"
    
    let textView = UITextView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    textView.backgroundColor = UIColor.clearColor()
    
    textView.attributedText = {
        let attributedString = NSMutableAttributedString(string: string)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = 1.25
        attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, string.characters.count))
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.whiteColor(), range: NSMakeRange(0, string.characters.count))
    
        let regex = try! NSRegularExpression(pattern: "\\s", options: [])
        let matches = regex.matchesInString(string, options: [], range: NSMakeRange(0, string.characters.count))
        for m in matches {
            attributedString.addAttribute(NSKernAttributeName, value: 6, range: m.range)
        }
        return NSAttributedString(attributedString: attributedString)
    }()
    
    let textViewBG = UIView(frame: textView.bounds)
    textViewBG.backgroundColor = UIColor.whiteColor()
    
    
    let pattern = "[^ ]+"
    let regex = try! NSRegularExpression(pattern: pattern, options: [])
    let matches = regex.matchesInString(string, options: [], range: NSMakeRange(0, string.characters.count))
    
    for m in matches {
        textViewBG.addSubview({
            let range = m.range
            var frame = frameOfTextInRange(range, inTextView: textView)
            frame = CGRectInset(frame, CGFloat(-3), CGFloat(2))
            frame = CGRectOffset(frame, CGFloat(0), CGFloat(3))
            let v = UIView(frame: frame)
            v.layer.cornerRadius = 2
            v.backgroundColor = UIColor(hue: 211.0/360.0, saturation: 0.35, brightness: 0.78    , alpha: 1)
            return v
        }())
    }
    
    textViewBG.addSubview(textView)
    

提交回复
热议问题