iOSはbutton画像と文字のframeを任意に設定します

2828 ワード

交換方法の分類
#import 
@interface NSObject (SwizzleMethod)
+ (void)swizzleMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;
@end

#import "NSObject+SwizzleMethod.h"

@implementation NSObject (SwizzleMethod)

+ (void)swizzleMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector;   {
    Method originalMethod = class_getInstanceMethod([self class], originalSelector);
    Method swizzledMethod = class_getInstanceMethod([self class], swizzledSelector);
    if (class_addMethod([self class],originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod))) {
        class_replaceMethod([self class],swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}
@end

コード:UIButton(LayoutSubviews)の作成
# import 
@interface UIButton (LayoutSubviews)
@property (assign, nonatomic) CGRect imageViewFrame;
@property (assign, nonatomic) CGRect titleLabelFrame;
@end

#import "UIButton+LayoutSubviews.h"

@implementation UIButton (LayoutSubviews)
+ (void)load; {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleMethod:@selector(layoutSubviews) swizzledSelector:@selector(aop_layoutSubviews)];
    });
}
- (CGRect)imageViewFrame; {
    return [objc_getAssociatedObject(self, @selector(imageViewFrame)) CGRectValue];
}
- (void)setImageViewFrame:(CGRect)imageViewFrame; {
    objc_setAssociatedObject(self, @selector(imageViewFrame), [NSValue valueWithCGRect:imageViewFrame], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGRect)titleLabelFrame; {
    return [objc_getAssociatedObject(self, @selector(titleLabelFrame)) CGRectValue];
}
- (void)setTitleLabelFrame:(CGRect)titleLabelFrame; {
    objc_setAssociatedObject(self, @selector(titleLabelFrame), [NSValue valueWithCGRect:titleLabelFrame], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)aop_layoutSubviews; {
    [self aop_layoutSubviews];
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    CGRect imageRect = self.imageViewFrame;
    if (!CGRectEqualToRect(imageRect, CGRectZero)) {
self.imageView.frame.origin.y, self.imageView.frame.size.width, self.imageView.frame.size.height);
        if (!CGRectEqualToRect(self.imageView.frame, imageRect)) {
            self.imageView.frame = imageRect;
        }
    }
    if (!CGRectEqualToRect(self.titleLabelFrame, CGRectZero)) {
        if (!CGRectEqualToRect(self.titleLabel.frame, self.titleLabelFrame)) {
            self.titleLabel.frame = self.titleLabelFrame;
        }
    }
    
    [CATransaction commit];
}
@end

外部にUIButtonのtitleLabelとimageViewの位置を直接設定すればよい.