1

I have a label with:

label.numberOfLines = 0

And I'm trying to make text of this label strikethrough with:

let index: NSMutableAttributedString = NSMutableAttributedString(string: label.text!)
index.addAttributes([NSStrikethroughStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue, NSStrikethroughColorAttributeName: UIColor.red], range: NSMakeRange(0, index.length))
label.textColor = UIColor.red
label.attributedText = index

Is it true that attributed string is not working with multilines or with labels with numberOfLines set to 0? And if so, how to make multiline text strikethrough?

kotvaska
  • 639
  • 7
  • 11
  • Look at this link http://stackoverflow.com/questions/2652163/draw-underlined-strikethrough-text-multiline-string – Gagan_iOS May 10 '17 at 10:54
  • Yes you are right. Generally it won't work with multiline. It's worth looking at this: http://stackoverflow.com/questions/10550732/font-with-strike-through-it – Sivajee Battina May 10 '17 at 11:03
  • @SivajeeBattina thanks. It sounds like not bad decision, I'll try it and tell if it works – kotvaska May 10 '17 at 11:13

4 Answers4

8

Works fine with multiline if you add NSBaselineOffsetAttributeName before:

let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: (object?.title)!)
attributeString.addAttribute(NSBaselineOffsetAttributeName, value: 0, range: NSMakeRange(0, attributeString.length))
attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 2, range: NSMakeRange(0, attributeString.length))
Alexey Chekanov
  • 1,047
  • 14
  • 25
  • How did you find out that `NSBaselineOffsetAttributeName` is needed? – Rudolf Adamkovič Jul 27 '17 at 15:07
  • Accidentally :-) I've found an example in a discussion, concerning underlying multiline string in tvOS. In this discussion a guy was curious, why everyone had this problem when he hadn't. And he showed his code. The only difference was in this Baseline attribute. So, I tried this on a strikethrough multiline string and it started to work. – Alexey Chekanov Jul 28 '17 at 13:45
  • What a story! Thanks for finding time. – Rudolf Adamkovič Jul 28 '17 at 16:01
  • Thank you!, I was looking for errors that did not exist until I realized my tasks where indeed completed, just not represented by the strikethrough when they were multilined. – the Reverend Aug 17 '17 at 20:08
1

Your code should be like,

 let index: NSMutableAttributedString = NSMutableAttributedString(string: lbl.text!)
    index.addAttributes([NSStrikethroughStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue, NSStrikethroughColorAttributeName: UIColor.red], range: NSMakeRange(0, index.length))
    lbl.textColor = UIColor.red
    lbl.attributedText = index

because index is your mutable string! not title!

And you can not use strike through with multi line label.

If you want strike through effect in multiple lines then you can use UITextView instead of label!

Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
  • 1
    Are you sure your answer is working, I tried with index and it's not working. Note, label has multiline text. Your answer can't provide solution to this question as OP wants strike on multiline text – Krunal May 10 '17 at 11:04
  • It will work if it is single line! There is one mistake in OP, index is mutable string not title! so i have correct that! @Krunal – Ketan Parmar May 10 '17 at 11:08
  • thank you, @Lion. you are right. it is my typo, because I have two different labels that need to strikethrough. but I still have the same question :) – kotvaska May 10 '17 at 11:10
  • @kotvaska : you can use `UITextView` instead of label, if you want text with strike through and multilines both! – Ketan Parmar May 10 '17 at 11:22
0

Write it like,

    self.label.numberOfLines = 0
    let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: self.label.text!)
    attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 1, range: NSMakeRange(0, attributeString.length))
    self.label.attributedText = attributeString

Working at my end.

enter image description here

Jigar Tarsariya
  • 3,189
  • 3
  • 14
  • 38
0

I came up with two solutions. They are based on @SivajeeBattina answer.

First one is to strike out text with help of http://adamvarga.com/strike/.

private func returnStrikedOutTextFromString(_ str: String) -> String {
    var newString = ""

    let normal = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя "
    let strikethrough = "А̶Б̶В̶Г̶Д̶Е̶Ё̶Ж̶З̶И̶Й̶К̶Л̶М̶Н̶О̶П̶Р̶С̶Т̶У̶Ф̶Х̶Ц̶Ч̶Ш̶Щ̶Ъ̶Ы̶Ь̶Э̶Ю̶Я̶а̶б̶в̶г̶д̶е̶ё̶ж̶з̶и̶й̶к̶л̶м̶н̶о̶п̶р̶с̶т̶у̶ф̶х̶ц̶ч̶ш̶щ̶ъ̶ы̶ь̶э̶ю̶я̶ ̶̶"

    for i in 0..<str.characters.count {

        let range: Range<String.Index> =
                normal.range(of: str
                        .substring(to: str.index(str.startIndex, offsetBy: i + 1))
                        .substring(from: str.index(str.startIndex, offsetBy: i)))!
        let index: Int = normal.distance(from: normal.startIndex, to: range.lowerBound)

        newString = String(format: "%@%@", newString,
                NSLocalizedString(strikethrough
                        .substring(to: strikethrough.index(strikethrough.startIndex, offsetBy: index + 1))
                        .substring(from: strikethrough.index(strikethrough.startIndex, offsetBy: index)),
                        comment: ""))

    }

    return newString

}

And second one is: https://github.com/GuntisTreulands/UnderLineLabel

kotvaska
  • 639
  • 7
  • 11