6

I was using ActiveLabel as third party library to make link in a label for particular words.The code works fine for Swift 3 & 3.2. but does not work for swift 4.

Below code i used

let customType1 = ActiveType.custom(pattern: "\\sTerms & Conditions\\b") //Looks for "are"
            labelTc.enabledTypes.append(customType1)
            labelTc.customize { (label) in
                labelTc.text = "UserAgreement".localized
                label.numberOfLines = 0
                label.lineSpacing = 4
                label.textColor = UIColor(red: 131 / 255, green: 147 / 255, blue: 168 / 255, alpha: 1)
                //Custom types
                label.customColor[customType1] = Constant.AppColor.greenMeadow
                label.customSelectedColor[customType1] = Constant.AppColor.greenMeadow
                label.configureLinkAttribute = { (type, attributes, isSelected) in
                    var atts = attributes
                    switch type {
                    case customType1:
                        atts[NSAttributedStringKey.font._rawValue as String] = UIFont(name: self.labelTc.font.fontName, size: 15.0)
                        atts[NSAttributedStringKey.underlineStyle.rawValue] = NSUnderlineStyle.styleSingle
                        break


                    case .mention:
                        break
                    case .hashtag:
                        break
                    case .url:
                        break
                    case .custom(let pattern):
                        break

                    default :
                        break
                    }

                    return atts
                }

Can anyone give me solution using native code instead of using third party library.

Ahmad F
  • 30,560
  • 17
  • 97
  • 143
TechChain
  • 8,404
  • 29
  • 103
  • 228
  • https://stackoverflow.com/a/44438304/2303865 – Leo Dabus Nov 16 '17 at 14:47
  • 2
    In Swift 4 your attributes should have type `[NSAttributedStringKey: Any]` therefore assignment to them should be `atts[.font] = UIFont(...)`. "Does not work" is not a very good problem description. The library is open source, look into the code, everything is there. – Sulthan Nov 16 '17 at 14:48
  • https://stackoverflow.com/questions/21629784/how-to-make-a-clickable-link-in-an-nsattributedstring-for-a – sohan vanani Nov 20 '17 at 13:13
  • https://www.hackingwithswift.com/example-code/system/how-to-make-tappable-links-in-nsattributedstring – sohan vanani Nov 20 '17 at 13:20
  • for native code I had used UITextView instead of UILabel please check my answer if it helps you https://stackoverflow.com/a/47385511/6080920 – iOS Geek Nov 21 '17 at 05:08

2 Answers2

3

I was able to find out the solution for swift 4 as well.

label.configureLinkAttribute = { (type, attributes, isSelected) in
                var atts = attributes
                switch type {
                case customType1:
                    atts[NSAttributedStringKey.font.rawValue] = UIFont(name: self.labelTc.font.fontName, size: 15.0)
                    atts[NSAttributedStringKey.underlineStyle.rawValue] = NSUnderlineStyle.styleSingle.rawValue
                    break

              default: ()
                }
                return atts
            }
TechChain
  • 8,404
  • 29
  • 103
  • 228
  • If you pretty sure that your answer is the right solution, please make sure to accept (green tick) it. – Ahmad F Nov 23 '17 at 10:17
1

Another solution. For me this better.

  1. Get your text from the UILabel.
  2. Unwrape this text
  3. Do what you want

For example, in my case:

struct DetectedLinkData {

    var link: URL
    var range: Range<String.Index>
    init(link: URL, range: Range<String.Index>) {
        self.link = link
        self.range = range
    }

}

class LinkDetecter {

    static func getLinks(in string: String) -> [DetectedLinkData] {
        guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return []
        }

        var result: [DetectedLinkData] = []
        let matches = detector.matches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count) )
        for match in matches {
            guard let range = Range(match.range, in: string),
                let url = URL(string: String(string[range]) )
                else {
                    continue
            }
            result.append(DetectedLinkData(link: url, range: range))
        }
        return result
    }

}

let temp = LinkDetecter.getLinks(in: message["text"] as? String ?? "")
Koder 228
  • 200
  • 1
  • 8