UIViewのローカライズ作業をMethod Swizzlingで簡単にする

iOSでStoryboardやXIBのUILabelやUIButtonなどのローカライズを行うことに関してEZ-NET: UIView のローカライズ作業を簡単にするという記事がありました。その記事ではサブクラス化してローカライズを行っているのですが、サブクラスでなくてカテゴリーで実装することもできるんじゃないかと思ってやってみました。

まずMethod Swizzlingを行うクラスを作成します。

#import <Foundation/Foundation.h>
 
@interface MethodSwizzling : NSObject
+ (void)swizzleMethod:(Class)aClass from:(SEL)originalSelector to:(SEL)newSelector;
@end
 
#import <objc/runtime.h>
#import "MethodSwizzling.h"
 
@implementation MethodSwizzling {}
+ (void)swizzleMethod:(Class)aClass from:(SEL)originalSelector to:(SEL)newSelector {
    Method originalMethod = class_getInstanceMethod(aClass, originalSelector);
    Method newMethod = class_getInstanceMethod(aClass, newSelector);
 
    if (class_addMethod(aClass, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
        class_replaceMethod(aClass, newSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, newMethod);
    }
}
@end

そしてUILabelやUIButtonのカテゴリーを作成します。

@interface UILabel (Localize)
- (void)localizedAwakeFromNib;
@end
 
@implementation UILabel (Localize)
+ (void)load {
    [MethodSwizzling swizzleMethod:[UILabel class] from:@selector(awakeFromNib) to:@selector(localizedAwakeFromNib)];
}
 
- (void)localizedAwakeFromNib {
    self.text = NSLocalizedString(self.text, nil);
 
    [self localizedAwakeFromNib];
}
@end
 
@interface UIButton (Localize)
- (void)localizedAwakeFromNib;
@end
 
@implementation UIButton (Localize)
+ (void)load {
    [MethodSwizzling swizzleMethod:[UIButton class] from:@selector(awakeFromNib) to:@selector(localizedAwakeFromNib)];
}
 
- (void)localizedAwakeFromNib {
    [self setTitle:NSLocalizedString(self.titleLabel.text, nil) forState:UIControlStateNormal];
 
    [self localizedAwakeFromNib];
}
@end

Method SwizzlingでawakeFromNibの代わりにlocalizedAwakeFromNibが実行されるように変更しました。
これでUILabelやUIButtonに設定した文字列がローカライズされて表示されます。

問題が出るかもしれないけど、一応こういう方法でも可能だということで。