145

I want to create a UILabel in which the text is like this

enter image description here

How can I do this? When the text is small, the line should also be small.

craft
  • 2,017
  • 1
  • 21
  • 30
Dev
  • 3,885
  • 10
  • 39
  • 65

21 Answers21

261

SWIFT 5 UPDATE CODE

let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: "Your Text")
    attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 2, range: NSRange(location: 0, length: attributeString.length))

then:

yourLabel.attributedText = attributeString

To make some part of string to strike then provide range

let somePartStringRange = (yourStringHere as NSString).range(of: "Text")
attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 2, range: somePartStringRange)

Objective-C

In iOS 6.0 > UILabel supports NSAttributedString

NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:@"Your String here"];
[attributeString addAttribute:NSStrikethroughStyleAttributeName
                        value:@2
                        range:NSMakeRange(0, [attributeString length])];

Swift

let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: "Your String here")
attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 2, range: NSMakeRange(0, attributeString.length))

Definition :

- (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)aRange

Parameters List:

name : A string specifying the attribute name. Attribute keys can be supplied by another framework or can be custom ones you define. For information about where to find the system-supplied attribute keys, see the overview section in NSAttributedString Class Reference.

value : The attribute value associated with name.

aRange : The range of characters to which the specified attribute/value pair applies.

Then

yourLabel.attributedText = attributeString;

For lesser than iOS 6.0 versions you need 3-rd party component to do this. One of them is TTTAttributedLabel, another is OHAttributedLabel.

Cenny
  • 1,916
  • 1
  • 12
  • 19
Paresh Navadiya
  • 38,095
  • 11
  • 81
  • 132
  • For iOS 5.1.1 lesser version how can I use 3 party attributed Label to display attributed text: ? – Dev Oct 30 '12 at 05:30
  • Can You suggest a good Toutorial? The link which you provided is little bit difficult to understand.. :( – Dev Oct 30 '12 at 06:01
  • Can you explain what I should do for creating a third party attributed Label for ios – Dev Oct 30 '12 at 06:24
  • What is @2? Magic number? – pronebird May 19 '14 at 12:34
  • 9
    I guess you forgot to commit that. You should use a proper value from NSUnderlineStyle instead of @2. I am little bit pedantic here. – pronebird May 20 '14 at 19:02
  • It can be expressed shorter, without the need for mutability: ```[[NSAttributedString alloc] initWithString:@"string" attributes:@{NSStrikethroughStyleAttributeName : @(NSUnderlineStyleSingle)}];``` – Mikkel Selsøe Apr 28 '15 at 13:26
  • For me it doesn't work if I try to strikethrough only part of string, but not all. Is this intended? And is it possible to still make it strikethrough just one word inside long text? – Jonauz Apr 13 '17 at 04:15
  • Why NSAttributedStringKey.strikethroughStyle: NSUnderlineStyle.styleSingle.rawValue is not working in swift 4 ? – Hassan Taleb Jun 21 '17 at 08:36
  • How to get striked on the center of the label? – Rashid KC Jul 18 '17 at 09:12
  • See [this](https://stackoverflow.com/q/43074652/1359088) thread if you have issues with the strikethrough appearing. – James Toomey Sep 21 '17 at 23:00
61

In Swift, using the single strikethrough line style:

let attributedText = NSAttributedString(
    string: "Label Text",
    attributes: [.strikethroughStyle: NSUnderlineStyle.single.rawValue]
)
label.attributedText = attributedText

Additional strikethrough styles (Remember to use the .rawValue):

  • .none
  • .single
  • .thick
  • .double

Strikethrough patterns (to be OR-ed with the style):

  • .patternDot
  • .patternDash
  • .patternDashDot
  • .patternDashDotDot

Specify that the strikethrough should only be applied across words (not spaces):

  • .byWord
Witek Bobrowski
  • 3,749
  • 1
  • 20
  • 34
Chris Trevarthen
  • 5,221
  • 2
  • 16
  • 10
38

Strikethrough in Swift 5.0

let attributeString =  NSMutableAttributedString(string: "Your Text")
attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle,
                                     value: NSUnderlineStyle.single.rawValue,
                                         range: NSMakeRange(0, attributeString.length))
self.yourLabel.attributedText = attributeString

It worked for me like a charm.

Use it as extension

extension String {
    func strikeThrough() -> NSAttributedString {
        let attributeString =  NSMutableAttributedString(string: self)
        attributeString.addAttribute(
            NSAttributedString.Key.strikethroughStyle,
               value: NSUnderlineStyle.single.rawValue,
                   range:NSMakeRange(0,attributeString.length))
        return attributeString
    }
}

Call like this

myLabel.attributedText = "my string".strikeThrough()

UILabel extension for strikethrough Enable/Disable.

extension UILabel {

func strikeThrough(_ isStrikeThrough:Bool) {
    if isStrikeThrough {
        if let lblText = self.text {
            let attributeString =  NSMutableAttributedString(string: lblText)
            attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: NSMakeRange(0,attributeString.length))
            self.attributedText = attributeString
        }
    } else {
        if let attributedStringText = self.attributedText {
            let txt = attributedStringText.string
            self.attributedText = nil
            self.text = txt
            return
        }
    }
    }
}

Use it like this :

   yourLabel.strikeThrough(btn.isSelected) // true OR false
Mushrankhan
  • 749
  • 9
  • 12
Purnendu roy
  • 818
  • 8
  • 15
  • 1
    Do you happen to know a solution to StrikeThrough not being removed? Similar to https://forums.developer.apple.com/thread/121366 – Jeroen Apr 21 '20 at 10:43
36

I prefer NSAttributedString rather than NSMutableAttributedString for this simple case:

NSAttributedString * title =
    [[NSAttributedString alloc] initWithString:@"$198"
                                    attributes:@{NSStrikethroughStyleAttributeName:@(NSUnderlineStyleSingle)}];
[label setAttributedText:title];

Constants for specifying both the NSUnderlineStyleAttributeName and NSStrikethroughStyleAttributeName attributes of an attributed string:

typedef enum : NSInteger {  
  NSUnderlineStyleNone = 0x00,  
  NSUnderlineStyleSingle = 0x01,  
  NSUnderlineStyleThick = 0x02,  
  NSUnderlineStyleDouble = 0x09,  
  NSUnderlinePatternSolid = 0x0000,  
  NSUnderlinePatternDot = 0x0100,  
  NSUnderlinePatternDash = 0x0200,  
  NSUnderlinePatternDashDot = 0x0300,  
  NSUnderlinePatternDashDotDot = 0x0400,  
  NSUnderlineByWord = 0x8000  
} NSUnderlineStyle;  
Kjuly
  • 34,476
  • 22
  • 104
  • 118
23

SWIFT CODE

let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: "Your Text")
    attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 2, range: NSMakeRange(0, attributeString.length))

then:

yourLabel.attributedText = attributeString

Thanks to Prince answer ;)

Community
  • 1
  • 1
pekpon
  • 761
  • 1
  • 10
  • 24
16

SWIFT 4

    let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: "Your Text Goes Here")
    attributeString.addAttribute(NSAttributedStringKey.strikethroughStyle, value: NSUnderlineStyle.styleSingle.rawValue, range: NSMakeRange(0, attributeString.length))
    self.lbl_productPrice.attributedText = attributeString

Other method is to used String Extension
Extension

extension String{
    func strikeThrough()->NSAttributedString{
        let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: self)
        attributeString.addAttribute(NSAttributedStringKey.strikethroughStyle, value: NSUnderlineStyle.styleSingle.rawValue, range: NSMakeRange(0, attributeString.length))
        return attributeString
    }
}

Calling the function : Used it like so

testUILabel.attributedText = "Your Text Goes Here!".strikeThrough()

Credit to @Yahya - update Dec 2017
Credit to @kuzdu - update Aug 2018

Muhammad Asyraf
  • 1,748
  • 15
  • 20
  • Doesn't work for me. Purnendu roy's answer work for me. The only difference is that you pass in `value` `0` and Purnendu roy pass `value: NSUnderlineStyle.styleSingle.rawValue` – kuzdu Jul 27 '18 at 15:15
  • @kuzdu funny thing that my answer was back in dec 2017 it works back then he just copied my code and add up NSUnderlineStyle.styleSingle.rawValue ^-^ But no problem i will update this answer just to make you happy – Muhammad Asyraf Aug 01 '18 at 06:54
10

Strike out UILabel text in Swift iOS. PLease try this it's working for me

let attributedString = NSMutableAttributedString(string:"12345")
                      attributedString.addAttribute(NSAttributedStringKey.baselineOffset, value: 0, range: NSMakeRange(0, attributedString.length))
                      attributedString.addAttribute(NSAttributedStringKey.strikethroughStyle, value: NSNumber(value: NSUnderlineStyle.styleThick.rawValue), range: NSMakeRange(0, attributedString.length))
                      attributedString.addAttribute(NSAttributedStringKey.strikethroughColor, value: UIColor.gray, range: NSMakeRange(0, attributedString.length))

 yourLabel.attributedText = attributedString

You can change your "strikethroughStyle" like styleSingle, styleThick,styleDouble enter image description here

Karthick C
  • 1,519
  • 17
  • 16
9

You can do it in IOS 6 using NSMutableAttributedString.

NSMutableAttributedString *attString=[[NSMutableAttributedString alloc]initWithString:@"$198"];
[attString addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:2] range:NSMakeRange(0,[attString length])];
yourLabel.attributedText = attString;
Manu
  • 4,730
  • 2
  • 20
  • 45
Bhushan B
  • 2,470
  • 4
  • 26
  • 38
6

Swift 5

extension String {

  /// Apply strike font on text
  func strikeThrough() -> NSAttributedString {
    let attributeString = NSMutableAttributedString(string: self)
    attributeString.addAttribute(
      NSAttributedString.Key.strikethroughStyle,
      value: 1,
      range: NSRange(location: 0, length: attributeString.length))

      return attributeString
     }
   }

Example:

someLabel.attributedText = someText.strikeThrough()
  • Difference between value: 1 and value: 2 – Naresh Sep 18 '19 at 07:09
  • 2
    @iOS value is the thickness of the line that strikethrough the text. The larger the value, the thicker the line that crosses out the text – Vladimir Pchelyakov Sep 18 '19 at 07:23
  • @VladimirPchelyakov No. The value corresponds to `NSUnderlineStyle` rawValue (NSNumber). 1 = single, 2 = thick, 9 = double, and there is many other styles between thick and double – Leo Dabus Oct 26 '20 at 00:55
4

For anyone looking on how to do this in a tableview cell (Swift) you have to set the .attributeText like this:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("TheCell")!

    let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: message)
    attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 2, range: NSMakeRange(0, attributeString.length))

    cell.textLabel?.attributedText =  attributeString

    return cell
    }

If you want to remove the strikethrough do this otherwise it will stick around!:

cell.textLabel?.attributedText =  nil
Micro
  • 10,303
  • 14
  • 82
  • 120
4

Swift5 UILabel Extension. Removing strikethrough sometimes doesn't work. Use this code in that case.

extension UILabel {
    func strikeThrough(_ isStrikeThrough: Bool = true) {
        guard let text = self.text else {
            return
        }
        
        if isStrikeThrough {
            let attributeString =  NSMutableAttributedString(string: text)
            attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: NSMakeRange(0,attributeString.length))
            self.attributedText = attributeString
        } else {
            let attributeString =  NSMutableAttributedString(string: text)
            attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: [], range: NSMakeRange(0,attributeString.length))
            self.attributedText = attributeString
        }
    }
}
Li Jin
  • 1,879
  • 2
  • 16
  • 23
3

I might be late to the party.

Anyway, I am aware about the NSMutableAttributedString but recently I achieved the same functionality with slightly different approach.

  • I added the UIView with height = 1.
  • Matched the leading and trailing constraints of the UIView with the label's leading and trailing constraints
  • Aligned the UIView at centre of the Label

After following all the above steps my Label, UIView and its constraints were looking like below image.

enter image description here

user7420795
  • 199
  • 1
  • 15
3

Swift 4 and 5

extension NSAttributedString {

    /// Returns a new instance of NSAttributedString with same contents and attributes with strike through added.
     /// - Parameter style: value for style you wish to assign to the text.
     /// - Returns: a new instance of NSAttributedString with given strike through.
     func withStrikeThrough(_ style: Int = 1) -> NSAttributedString {
         let attributedString = NSMutableAttributedString(attributedString: self)
         attributedString.addAttribute(.strikethroughStyle,
                                       value: style,
                                       range: NSRange(location: 0, length: string.count))
         return NSAttributedString(attributedString: attributedString)
     }
}

Example

let example = NSAttributedString(string: "440").withStrikeThrough(1)
myLabel.attributedText = example

Results

enter image description here

Rashid Latif
  • 2,809
  • 22
  • 26
2

Use below code

NSString* strPrice = @"£399.95";

NSMutableAttributedString *titleString = [[NSMutableAttributedString alloc] initWithString:strPrice];

[finalString addAttribute: NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger: NSUnderlineStyleSingle] range: NSMakeRange(0, [titleString length])];
self.lblOldPrice.attributedText = finalString;   
Hardik Thakkar
  • 15,269
  • 2
  • 94
  • 81
2

Swift 4.2

let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: product.price)

attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: NSMakeRange(0, attributeString.length))

lblPrice.attributedText = attributeString
Harshal Valanda
  • 5,331
  • 26
  • 63
2

Swift 5 - short version

let attributedText = NSAttributedString(
    string: "Label Text",
    attributes: [.strikethroughStyle: NSUnderlineStyle.single.rawValue]
)

yourLabel.attributedText = attributedText
Witek Bobrowski
  • 3,749
  • 1
  • 20
  • 34
Dan Developer
  • 171
  • 1
  • 4
1

Change the text property to attributed and select the text and right click to get the font property. Click on the strikethrough. Screenshot

adiga
  • 34,372
  • 9
  • 61
  • 83
1

On iOS 10.3 has an issue on rendering strikethrough line fixes by Adding a NSBaselineOffsetAttributeName, as explained here, to the attributed string brings back the strikethrough line. Overriding drawText:in: can be slow especially on Collection View or Table View Cells.

One sol - Add view to render a line.

Second sol -

attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 2, range: NSMakeRange(0, attributeString.length))
attributeString.addAttribute(NSAttributedString.Key.baselineOffset, value: 2, range: NSMakeRange(0, attributeString.length))```
TheCodeTalker
  • 685
  • 6
  • 14
0

For those who face issue with multi line text strike

    let attributedString = NSMutableAttributedString(string: item.name!)
    //necessary if UILabel text is multilines
    attributedString.addAttribute(NSBaselineOffsetAttributeName, value: 0, range: NSMakeRange(0, attributedString.length))
     attributedString.addAttribute(NSStrikethroughStyleAttributeName, value: NSNumber(value: NSUnderlineStyle.styleSingle.rawValue), range: NSMakeRange(0, attributedString.length))
    attributedString.addAttribute(NSStrikethroughColorAttributeName, value: UIColor.darkGray, range: NSMakeRange(0, attributedString.length))

    cell.lblName.attributedText = attributedString
Waseem Sarwar
  • 2,645
  • 1
  • 21
  • 18
0

Create String extension and add below method

static func makeSlashText(_ text:String) -> NSAttributedString {


 let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: text)
        attributeString.addAttribute(NSStrikethroughStyleAttributeName, value: 2, range: NSMakeRange(0, attributeString.length))

return attributeString 

}

then use for your label like this

yourLabel.attributedText = String.makeSlashText("Hello World!")
Josh Gray
  • 49
  • 3
0

This is the one you can use in Swift 4 because NSStrikethroughStyleAttributeName has been changed to NSAttributedStringKey.strikethroughStyle

let attributeString: NSMutableAttributedString =  NSMutableAttributedString(string: "Your Text")

attributeString.addAttribute(NSAttributedStringKey.strikethroughStyle, value: 2, range: NSMakeRange(0, attributeString.length))

self.lbl.attributedText = attributeString
vikram
  • 181
  • 2
  • 5