0

I am trying to retroactively localize an app by subclassing an IBDesignable to have a property like so:

@property IBInspectable NSString *localizedKey;

Then I thought I could easily override the proper function in the UILabel's lifecycle to do this:

if (self.localizedKey) self.text = NSLocalizedString(self.localizedKey, nil);

Here's an example of what I tried to do:

- (void) drawRect:(CGRect)rect {
    NSLog(@"roundedlabel");
    [super drawRect:rect];
    [self.layer setCornerRadius:cornerRadius];
    [self.layer setMasksToBounds:YES];
    [self.layer setBorderWidth:borderWidth];
    [self.layer setBorderColor:[borderColor CGColor]];
    self.clipsToBounds = YES;
}

- (void) willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    NSLog(@"roundedlabel");
    if (self.localizedKey) self.text = NSLocalizedString(self.localizedKey, nil);
}

I also tried moving the if (self.localizedKey) to various locations in drawRect.

My plan was to then set up the Localizable.strings file manually with known localizedKeys assigned working through the XIB files. However, I am finding two things.

  1. It seems as though the normal methods called in the life cycle of a view are not being called for my IBDesignable UILabel subclass. I have entered log statements into drawRect and willMoveToSuperview, and these log statements never print out.
  2. XCode almost always crashes & immediately closes when I try to open a xib in Interface Builder that contains this subclassed label (so no error messages).

At run time, when I see a view that involves an affected xib, I don't see any sign of the localized string AND I don't see 'roundedlabel' printed anywhere in my log.

What's going on? In particular:

(1) How come these functions don't run at all for my subclassed IBDesignable UILabel subclass? (2) Is there a way to do what I want to do?

helloB
  • 3,472
  • 10
  • 40
  • 87
  • have you already subclassed `UILabel` or you've done it just for the designable? is there a reason you chose designable as the approach to take? – Wain Apr 05 '16 at 21:08
  • @Wain I am seeking to retroactively localize many xibs where the copy & layout are frequently changed. For this reason, I don't want to generate many separately localized xib files (too difficult to maintain), and I want to avoid migrating all the text assignments to .m files rather than xibs. – helloB Apr 06 '16 at 00:51

1 Answers1

0

I'd create an extension on UILabel and use runtime key values in the storyboard / XIB to set the localisation keys.

extension UILabel {
    func setHBLocalisationKey(key: String) {
        self.text = ...
     }
}

or

@implementation UILabel (HBLocalisation)

    - (void)setHBLocalisationKey:(NSString *)key {
        self.text = NSLocalizedString(key, nil);
    }

@end

This will now work on any label without requiring a custom subclass and it won't tamper with the Xcode UI which seems to be causing some issues with your current approach.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • thanks for your answer, but I'm not sure how your recommendation fully translates over to my approach in Objective C. I don't see how doing this as a class extension rather than as a subclass changes the issue. In particular, ultimately I need the function to run at run time. My problem is that I can't seem to find a function that is running at runtime. – helloB Apr 06 '16 at 14:21
  • sorry, too used to writing in swift now :( if you're using IBDesignable then it's static anyway. you could use a category in the same way as the extension, it'll work in exactly the same way. it's a different approach, it doesn't translate to your approach, just to your requirement – Wain Apr 06 '16 at 14:30
  • I'm all for it, but part of my question is why the methods don't seem to get executed? What would I call the category and how would I set it? – helloB Apr 06 '16 at 14:41
  • i've added the category, the category method is executed by setting the key value pair `HBLocalisationKey` : `XXX` the storyboard as described here: https://developer.apple.com/library/mac/recipes/xcode_help-interface_builder/Chapters/AddUserDefinedRuntimeAttributes.html – Wain Apr 06 '16 at 14:45
  • i don't know why your current approach isn't working, i don't know enough about it, but it's also more complex and has more requirements then my suggestion – Wain Apr 06 '16 at 14:47