1
This commit is contained in:
39
keyBoard/Class/Common/V/KBImagePositionButton.h
Normal file
39
keyBoard/Class/Common/V/KBImagePositionButton.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// KBImagePositionButton.h
|
||||
// keyBoard
|
||||
//
|
||||
// Created by Kiro on 2026/1/27.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// 图片位置枚举
|
||||
typedef NS_ENUM(NSInteger, KBImagePosition) {
|
||||
KBImagePositionTop, // 图片在上,文字在下
|
||||
KBImagePositionBottom, // 图片在下,文字在上
|
||||
KBImagePositionLeft, // 图片在左,文字在右(默认)
|
||||
KBImagePositionRight // 图片在右,文字在左
|
||||
};
|
||||
|
||||
/// 可以指定图片位置的按钮
|
||||
@interface KBImagePositionButton : UIButton
|
||||
|
||||
/// 图片位置(默认 KBImagePositionLeft)
|
||||
@property (nonatomic, assign) KBImagePosition imagePosition;
|
||||
|
||||
/// 图片和文字之间的间距(默认 8)
|
||||
@property (nonatomic, assign) CGFloat spacing;
|
||||
|
||||
/**
|
||||
便捷初始化方法
|
||||
|
||||
@param imagePosition 图片位置
|
||||
@param spacing 图片和文字之间的间距
|
||||
*/
|
||||
- (instancetype)initWithImagePosition:(KBImagePosition)imagePosition spacing:(CGFloat)spacing;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
187
keyBoard/Class/Common/V/KBImagePositionButton.m
Normal file
187
keyBoard/Class/Common/V/KBImagePositionButton.m
Normal file
@@ -0,0 +1,187 @@
|
||||
//
|
||||
// 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
|
||||
Reference in New Issue
Block a user