参考:https://www.jianshu.com/p/1d74cc10c8a7
一、
xib无效
button.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
二、
设置titleEdgeInsets或imageEdgeInsets,需要frame确定后才能计算,或者自己用 boundingRectWithSize:options:attributes:context: 计算出title的size
button.titleEdgeInsets = UIEdgeInsetsMake(0, -button.imageView.frame.size.width, 0, button.imageView.frame.size.width);
button.imageEdgeInsets = UIEdgeInsetsMake(0, button.titleLabel.frame.size.width, 0, -button.titleLabel.frame.size.width);
三、
派生一个UIButton的子类,来实现titleEdgeInsets与imageEdgeInsets的自动更新。
- (void)layoutSubviews {
[super layoutSubviews];
[self updateEdgeInsets];
}
- (void)updateEdgeInsets {
self.titleEdgeInsets = UIEdgeInsetsMake(0, -self.imageView.frame.size.width, 0, self.imageView.frame.size.width);
self.imageEdgeInsets = UIEdgeInsetsMake(0, self.titleLabel.frame.size.width, 0, -self.titleLabel.frame.size.width);
}
四、
派生一个UIButton的子类,通过重载 titleRectForContentRect: 和 imageRectForContentRect: 来分别指定文本和图片的显示区域。
@interface FCReverseButton ()
@property (nonatomic, assign) CGRect originalImageRect; // 原图片区域
@property (nonatomic, assign) CGRect originalTitleRect; // 原文本区域
@end
@implementation FCReverseButton
- (CGRect)titleRectForContentRect:(CGRect)contentRect {
if (CGRectIsEmpty(self.originalTitleRect)) {
self.originalTitleRect = [super titleRectForContentRect:contentRect];
}
if (CGRectIsEmpty(self.originalTitleRect) || CGRectIsEmpty(self.originalImageRect)) {
return self.originalTitleRect;
} else {
CGFloat height = MAX(CGRectGetHeight(self.originalTitleRect), CGRectGetHeight(self.originalImageRect));
return CGRectMake(contentRect.origin.x + self.titleEdgeInsets.right, contentRect.origin.y + (height - CGRectGetHeight(self.originalTitleRect)) / 2, CGRectGetWidth(self.originalTitleRect), CGRectGetHeight(self.originalTitleRect));
}
}
- (CGRect)imageRectForContentRect:(CGRect)contentRect {
if (CGRectIsEmpty(self.originalImageRect)) {
self.originalImageRect = [super imageRectForContentRect:contentRect];
}
if (CGRectIsEmpty(self.originalTitleRect) || CGRectIsEmpty(self.originalImageRect)) {
return self.originalImageRect;
} else {
CGFloat height = MAX(CGRectGetHeight(self.originalTitleRect), CGRectGetHeight(self.originalImageRect));
return CGRectMake(contentRect.origin.x + CGRectGetWidth(self.originalTitleRect) + self.imageEdgeInsets.right, contentRect.origin.y + (height - CGRectGetHeight(self.originalImageRect)) / 2, CGRectGetWidth(self.originalImageRect), CGRectGetHeight(self.originalImageRect));
}
}
@end
五、
在坐标系的层面翻转按钮的X轴,再分别将titleLabel和imageView的X轴翻转回来。可以直接对UIButton进行操作,也可以派生一个子类。
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self horizontalReverse];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self horizontalReverse];
}
return self;
}
// 水平翻转
- (void)horizontalReverse {
self.transform = CGAffineTransformMakeScale(-1, 1);
self.imageView.transform = CGAffineTransformMakeScale(-1, 1);
self.titleLabel.transform = CGAffineTransformMakeScale(-1, 1);
}