Changing UILabel text but keeping the rest of the attributes

One line implementation in Swift:

label.attributedText = NSAttributedString(string: "text", attributes: label.attributedText!.attributesAtIndex(0, effectiveRange: nil))

This works for me:

- (void)setText:(NSString *)text withExistingAttributesInLabel:(UILabel *)label {

    // Check label has existing text
    if ([label.attributedText length]) {

        // Extract attributes
        NSDictionary *attributes = [(NSAttributedString *)label.attributedText attributesAtIndex:0 effectiveRange:NULL];

        // Set new text with extracted attributes
        label.attributedText = [[NSAttributedString alloc] initWithString:text attributes:attributes];

    }

}

...

[self setText:@"Some text" withExistingAttributesInLabel:self.aLabel];

This is happening because you're telling Interface builder to take a label that had pre-defined attributes set on its text and replace this attributed text with plain text. Instead of setText, or setTextColor you have to use setAttributedText and specify the attributes that you wish to pass to the attributed string.

Here's an example of how to apply an attributed string to your label programmatically. I'm not aware of any better way, but using this, you can make changes to the text or text color and as long as you set your other attributes along with them, all changes will be applied correctly.

[myLabel setAttributedText:[self myLabelAttributes:@"Some awesome text!"]];

....................

- (NSMutableAttributedString *)myLabelAttributes:(NSString *)input
{
    NSMutableAttributedString *labelAttributes = [[NSMutableAttributedString alloc] initWithString:input];

    [labelAttributes addAttribute:NSStrokeWidthAttributeName value:[NSNumber numberWithFloat:-5.0] range:NSMakeRange(0, labelAttributes.length)];
    [labelAttributes addAttribute:NSStrokeColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0, labelAttributes.length)];
    [labelAttributes addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, labelAttributes.length)];

    return labelAttributes;
}

Swift 4

label.attributedText = NSAttributedString(string: "new label text", attributes: label.attributedText!.attributes(at: 0, effectiveRange: nil))

(a few minors changes from Bartłomiej Semańczyk answer)