188 lines
5.9 KiB
Objective-C
188 lines
5.9 KiB
Objective-C
//
|
||
// KBImagePositionButton.m
|
||
// keyBoard
|
||
//
|
||
// Created by Kiro on 2026/1/27.
|
||
//
|
||
|
||
#import "KBImagePositionButton.h"
|
||
|
||
@implementation KBImagePositionButton
|
||
|
||
- (instancetype)initWithFrame:(CGRect)frame {
|
||
if (self = [super initWithFrame:frame]) {
|
||
[self setupDefault];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (instancetype)initWithCoder:(NSCoder *)coder {
|
||
if (self = [super initWithCoder:coder]) {
|
||
[self setupDefault];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (instancetype)initWithImagePosition:(KBImagePosition)imagePosition spacing:(CGFloat)spacing {
|
||
if (self = [super initWithFrame:CGRectZero]) {
|
||
_imagePosition = imagePosition;
|
||
_spacing = spacing;
|
||
[self setupDefault];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (void)setupDefault {
|
||
// 关键修复:不要判断 _imagePosition == 0,因为 KBImagePositionTop 的值就是 0
|
||
// 如果是通过 initWithFrame 或 initWithCoder 初始化,_imagePosition 默认就是 0 (KBImagePositionTop)
|
||
// 只有通过 initWithImagePosition 初始化时,才会明确设置 _imagePosition
|
||
|
||
// 为非自定义初始化设置默认值
|
||
if (self.spacing == 0) {
|
||
_spacing = 8;
|
||
}
|
||
|
||
[self updateEdgeInsets];
|
||
}
|
||
|
||
#pragma mark - Setter
|
||
|
||
- (void)setImagePosition:(KBImagePosition)imagePosition {
|
||
_imagePosition = imagePosition;
|
||
[self updateEdgeInsets];
|
||
[self setNeedsLayout];
|
||
}
|
||
|
||
- (void)setSpacing:(CGFloat)spacing {
|
||
_spacing = spacing;
|
||
[self updateEdgeInsets];
|
||
[self setNeedsLayout];
|
||
}
|
||
|
||
- (void)setImage:(UIImage *)image forState:(UIControlState)state {
|
||
[super setImage:image forState:state];
|
||
// 延迟更新,确保 image 已经设置好
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[self updateEdgeInsets];
|
||
});
|
||
}
|
||
|
||
- (void)setTitle:(NSString *)title forState:(UIControlState)state {
|
||
[super setTitle:title forState:state];
|
||
// 延迟更新,确保 title 已经设置好
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[self updateEdgeInsets];
|
||
});
|
||
}
|
||
|
||
#pragma mark - EdgeInsets
|
||
|
||
- (void)updateEdgeInsets {
|
||
CGSize imageSize = self.currentImage.size;
|
||
CGSize titleSize = CGSizeZero;
|
||
|
||
if (self.currentTitle.length > 0 && self.titleLabel.font) {
|
||
NSDictionary *attributes = @{NSFontAttributeName: self.titleLabel.font};
|
||
titleSize = [self.currentTitle sizeWithAttributes:attributes];
|
||
}
|
||
|
||
switch (self.imagePosition) {
|
||
case KBImagePositionTop: {
|
||
// 图片在上,文字在下
|
||
self.imageEdgeInsets = UIEdgeInsetsMake(
|
||
-(titleSize.height + self.spacing), // top: 向上移动
|
||
0, // left
|
||
0, // bottom
|
||
-titleSize.width // right: 向左移动文字的宽度
|
||
);
|
||
|
||
self.titleEdgeInsets = UIEdgeInsetsMake(
|
||
imageSize.height + self.spacing, // top: 向下移动
|
||
-imageSize.width, // left: 向左移动图片的宽度
|
||
0, // bottom
|
||
0 // right
|
||
);
|
||
break;
|
||
}
|
||
|
||
case KBImagePositionBottom: {
|
||
// 图片在下,文字在上
|
||
self.imageEdgeInsets = UIEdgeInsetsMake(
|
||
titleSize.height + self.spacing, // top: 向下移动
|
||
0, // left
|
||
0, // bottom
|
||
-titleSize.width // right
|
||
);
|
||
|
||
self.titleEdgeInsets = UIEdgeInsetsMake(
|
||
-(imageSize.height + self.spacing), // top: 向上移动
|
||
-imageSize.width, // left
|
||
0, // bottom
|
||
0 // right
|
||
);
|
||
break;
|
||
}
|
||
|
||
case KBImagePositionLeft: {
|
||
// 图片在左,文字在右(默认)
|
||
self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, self.spacing);
|
||
self.titleEdgeInsets = UIEdgeInsetsMake(0, self.spacing, 0, 0);
|
||
break;
|
||
}
|
||
|
||
case KBImagePositionRight: {
|
||
// 图片在右,文字在左
|
||
self.imageEdgeInsets = UIEdgeInsetsMake(
|
||
0,
|
||
titleSize.width + self.spacing,
|
||
0,
|
||
-(titleSize.width + self.spacing)
|
||
);
|
||
|
||
self.titleEdgeInsets = UIEdgeInsetsMake(
|
||
0,
|
||
-(imageSize.width + self.spacing),
|
||
0,
|
||
imageSize.width + self.spacing
|
||
);
|
||
break;
|
||
}
|
||
}
|
||
NSLog(@"imageEdgeInsets: %@", NSStringFromUIEdgeInsets(self.imageEdgeInsets));
|
||
NSLog(@"titleEdgeInsets: %@", NSStringFromUIEdgeInsets(self.titleEdgeInsets));
|
||
}
|
||
|
||
- (CGSize)intrinsicContentSize {
|
||
CGSize imageSize = self.currentImage ? self.currentImage.size : CGSizeZero;
|
||
CGSize titleSize = CGSizeZero;
|
||
|
||
if (self.currentTitle.length > 0 && self.titleLabel.font) {
|
||
NSDictionary *attributes = @{NSFontAttributeName: self.titleLabel.font};
|
||
titleSize = [self.currentTitle sizeWithAttributes:attributes];
|
||
}
|
||
|
||
CGSize size = CGSizeZero;
|
||
|
||
switch (self.imagePosition) {
|
||
case KBImagePositionTop:
|
||
case KBImagePositionBottom: {
|
||
// 垂直排列
|
||
size.width = MAX(imageSize.width, titleSize.width);
|
||
size.height = imageSize.height + self.spacing + titleSize.height;
|
||
break;
|
||
}
|
||
|
||
case KBImagePositionLeft:
|
||
case KBImagePositionRight: {
|
||
// 水平排列
|
||
size.width = imageSize.width + self.spacing + titleSize.width;
|
||
size.height = MAX(imageSize.height, titleSize.height);
|
||
break;
|
||
}
|
||
}
|
||
|
||
return size;
|
||
}
|
||
|
||
@end
|