2

I am trying to create an attributed string in which there is a Link appended at the end of the string :

func addMoreAndLessFunctionality (textView:UITextView){
        if textView.text.characters.count >= 120
        {
            let lengthOfString = 255
            var abc : String =  (somelongStringInitiallyAvailable as NSString).substringWithRange(NSRange(location: 0, length: lengthOfString))
            abc += " ...More"
            textView.text = abc
            let attribs = [NSForegroundColorAttributeName: StyleKit.appDescriptionColor, NSFontAttributeName: StyleKit.appDescriptionFont]
            let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: abc, attributes: attribs)


            attributedString.addAttribute(NSLinkAttributeName, value: " ...More", range: NSRange(location:255, length: 8))

          textView.attributedText = attributedString
            textView.textContainer.maximumNumberOfLines = 3;

        }
}

What I am trying to achieve here is that if characters in text view's text more than 255, it should show the "...More" link in text view which is tapable, on tap I am already able get the delegate "shouldInteractWithUrl" called, where I am increasing the no of lines in text view, and also change the text of link to "...Less". On tap of Less I again call this same method so that it can truncate again. :

    func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool
{
    print("textview should interact with URl")

    let textTapped = textView.text[textView.text.startIndex.advancedBy(characterRange.location)..<textView.text.endIndex]

    if textTapped == " ...More"{

        var abc : String =  (self.contentDetailItemManaged?.whatsnewDesc)!
        abc += " ...Less"
        textView.textContainer.maximumNumberOfLines = 0
        let attribs = [NSForegroundColorAttributeName: StyleKit.appDescriptionColor, NSFontAttributeName: StyleKit.appDescriptionFont]
        let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: abc, attributes: attribs)
        attributedString.addAttribute(NSLinkAttributeName, value: " ...Less", range: NSRange(location:abc.characters.count-8 , length: 8))

        textView.attributedText = attributedString


    }
    else if textTapped == " ...Less"{

        textView.attributedText = nil
        textView.text = somelongStringInitiallyAvailable
        self.addMoreAndLessFunctionality(textView)
    }

    return true
}

Now the problem, when the 1st method is called for the first time (it is called after I have set the textview's text), it works fine, but after clicking on "...More", textview expands normally, "...More" changes to " ...Less". And when " ...Less" is tapped, It crashes and exception occurs :

[NSConcreteTextStorage attribute:atIndex:effectiveRange:]: Range or index out of bounds'

any help would be greatly appreciated. (Also string "...More" has a space in beginning, so total 8 chars, i may have missed this space while typing above code)

Thanks :)

Rana
  • 451
  • 4
  • 16
  • You should stop using `text` property and use only `attributedText` property of the `UITextView` object. Aso, for `textTapped`, why don't you check only the URL? – Larme Aug 22 '16 at 21:37
  • @Larme what difference will it make if i don't use text property, can you please elaborate? and regarding URL, I missed the obvious, thanks for reminding. – Rana Aug 23 '16 at 04:00
  • It's useless, because afterwards you set the attributedText. Look there (http://stackoverflow.com/questions/36064762/change-font-size-without-change-uitextview-attributedtext) for instance with some related issue with mixing text and attributedText. – Larme Aug 23 '16 at 08:02

1 Answers1

2

return false in func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool

jessehao
  • 21
  • 4
  • Welcome to StackOverflow. While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. [How to Answer](https://stackoverflow.com/help/how-to-answer) – fewlinesofcode Dec 17 '18 at 12:35