// // 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