2018.8.30
1.关于设定
UIButton
的imageEdgeInsets
和titleEdgeInsets
属性,在之前的开发过程中,一直反反复复地被虐,虽然每次都能通过微调参数实现想要的效果,但每次都要琢磨好久,也是很麻烦,故而再次找了资料理清思路后弄出了这个分类方法,期望以后不需要再被虐了。。。
2.另外,当前的方法仍不完美,毕竟未能穷举开发中会遇到的所有情况,仅大致实现了最通用的几种做法,关于内部实现,其实也还是
微调参数 = =!
3.关于未能支持图片和标题动态变化的情况,目前还没有一个可实现的思路
- 相关方法
xf_NotNull
(字符串不为空),xf_GetWidth
(获取控件的宽度值),xf_GetHeight
(获取控件的高度值),请自行替换。
// UIButton+Category.h
/**
UIButton内部布局样式枚举类型 UIButtonInsideLayoutAdaptiveAlignment
*/
typedef NS_ENUM(NSInteger, UIButtonInsideLayoutAdaptiveAlignment) {
UIButtonInsideLayoutAdaptiveAlignmentBlend = 0, // 图片和标题完全居中,且标题覆盖于图片之上
UIButtonInsideLayoutAdaptiveAlignmentVertical, // 图标和标题在竖直方向上排列,上图下标题
UIButtonInsideLayoutAdaptiveAlignmentVerticalFlip, // 图标和标题在竖直方向上排列,上标题下图
UIButtonInsideLayoutAdaptiveAlignmentHorizontal, // 图标和标题在水平方向上排列,左图右标题
UIButtonInsideLayoutAdaptiveAlignmentHorizontalFlip, // 图标和标题在水平方向上排列,左标题右图
};
/**
自适应设定 UIButton 的 imageEdgeInsets 和 titleEdgeInsets 属性
@param alignment 图片和标题的布局方式,居中覆盖,竖直方向,水平方向
@param spacing 图片和标题的内间距
@param offset 偏移量,也可以直接设置 contentEdgeInsets 属性的 top 和 left 值
补充:1.设定合适的 Frame 很重要,2.不支持文字和图片的动态变化,或者保证动态变化的文字和图片的大小保持不变,
*/
- (void)insideLayoutAdaptiveAlignment:(UIButtonInsideLayoutAdaptiveAlignment)alignment
Spacing:(CGFloat)spacing Offset:(CGPoint)offset;
// UIButton+Category.m
- (void)insideLayoutAdaptiveAlignment:(UIButtonInsideLayoutAdaptiveAlignment)alignment
Spacing:(CGFloat)spacing Offset:(CGPoint)offset {
/**
top-left-bottom-right取负值 > 不能超出button边界 > imageView不能被压缩
top-left-bottom-right取负值 > 不能超出button边界 > titleLabel水平方向不能被压缩
titleLabel垂直方向不能被压缩 > 不能超出button边界
*/
NSAssert(self.imageView.image && self.titleLabel.text.length>,
@"Please set the title or image first.");
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
self.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
self.titleEdgeInsets = UIEdgeInsetsMake(0, -[self.imageView xf_GetWidth], 0, 0);
[self layoutIfNeeded];
UIImageView *imageView = self.imageView;
UILabel *titleLabel = self.titleLabel;
CGRect iRect = imageView.frame;
CGRect tRect = titleLabel.frame;
CGFloat top = ([self xf_GetHeight] - (iRect.size.height+tRect.size.height+spacing))/2;
CGFloat left = ([self xf_GetWidth] - (iRect.size.width+tRect.size.width+spacing))/2;
CGFloat iTop = top + offset.y;
CGFloat tTop = top + iRect.size.height + spacing + offset.y;
CGFloat iLeft = ([self xf_GetWidth]-iRect.size.width)/2 + offset.x;
CGFloat tLeft = - iRect.size.width + ([self xf_GetWidth]-tRect.size.width)/2 + offset.x;
CGFloat tRight = 0.0f;
switch (alignment) {
case UIButtonInsideLayoutAdaptiveAlignmentBlend:{
iTop = ([self xf_GetHeight]-iRect.size.height)/2 + offset.y;
tTop = ([self xf_GetHeight]-tRect.size.height)/2 + offset.y;
break;
}
case UIButtonInsideLayoutAdaptiveAlignmentVertical:{
break;
}
case UIButtonInsideLayoutAdaptiveAlignmentVerticalFlip:{
iTop = top + tRect.size.height + spacing + offset.y;
tTop = top + offset.y;
break;
}
case UIButtonInsideLayoutAdaptiveAlignmentHorizontal:{
iTop = ([self xf_GetHeight]-iRect.size.height)/2 + offset.y;
tTop = ([self xf_GetHeight]-tRect.size.height)/2 + offset.y;
iLeft = left + offset.x;
tLeft = left + spacing + offset.x;
tRight = [self xf_GetWidth]-(iRect.size.width+tRect.size.width) - tLeft;
break;
}
case UIButtonInsideLayoutAdaptiveAlignmentHorizontalFlip:{
iTop = ([self xf_GetHeight]-iRect.size.height)/2 + offset.y;
tTop = ([self xf_GetHeight]-tRect.size.height)/2 + offset.y;
iLeft = left + tRect.size.width + spacing + offset.x;
tLeft = - iRect.size.width + left + offset.x;
break;
}
}
self.imageEdgeInsets = UIEdgeInsetsMake(iTop, iLeft, -iTop, -iLeft);
self.titleEdgeInsets = UIEdgeInsetsMake(tTop, tLeft, -tTop, tRight);
}
参考链接:
1.理解UIButton的imageEdgeInsets和titleEdgeInsets
2.Aligning text and image on UIButton with imageEdgeInsets and titleEdgeInsets