通过调整UIButton的 imageEdgeInsets , titleEdgeInsets ,可以任意调换button的标题和图片的位置。
具体原理参看:https://www.jianshu.com/p/034e61768c1f
核心是:
- 默认内容水平居中、垂直居中情况下,对imageEdgeInsets的设置,会影响整体的安全区域,然后在新的安全区域内重新整体居中摆放,影响了整体的布局(进而影响了image),但不会影响titleLabel的位置;对titleEdgeInsets设置也只会影响整体中心点的布局(进而影响titleLabel),而不会影响image;
- 重排后整体中心点是保持不变的,在此条件下,分别计算重排后image和titleLabel的中心点偏移量,往后移、下移为正;往左移、上移为负, 然后分别对imageEdgeInsets、titleEdgeInsets赋值;
- 最后重新计算重排后整体size的变化,如变大, inset值为正,如缩小,inset值为负,对contentEdgeInsets赋值。
代码示例:
- (void)setImagePosition2:(LXMImagePosition)postion spacing:(CGFloat)spacing
{
CGFloat space = spacing;
CGFloat imageWidth = self.currentImage.size.width;
CGFloat imageHeight = self.currentImage.size.height;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// Single line, no wrapping. Truncation based on the NSLineBreakMode.
CGSize size = [self.currentTitle sizeWithFont:self.titleLabel.font];
#pragma clang diagnostic pop
CGFloat titleWidth = size.width;
CGFloat titleHeight = size.height;
UIEdgeInsets imageEdgeInsets = UIEdgeInsetsZero;
UIEdgeInsets titleEdgeInsets = UIEdgeInsetsZero;
UIEdgeInsets contentEdgeInsets = UIEdgeInsetsZero;
CGFloat imageCenterOffsetX = 0;
CGFloat imageCenterOffsetY = 0;
CGFloat titleCenterOffsetX = 0;
CGFloat titleCenterOffsetY = 0;
// After reset, the center keeps the same.
switch (postion) {
case LXMImagePositionLeft:
imageCenterOffsetX = -space/2;
imageCenterOffsetY = 0;
titleCenterOffsetX = space/2;
titleCenterOffsetY = 0;
contentEdgeInsets = UIEdgeInsetsMake(0, space/2, 0, space/2);
break;
case LXMImagePositionRight:
imageCenterOffsetX = ((imageWidth+titleWidth)/2 - imageWidth/2)*2 + space/2;
imageCenterOffsetY = 0;
titleCenterOffsetX = -(imageWidth+titleWidth/2 - (imageWidth+titleWidth)/2)*2 - space/2;
titleCenterOffsetY = 0;
contentEdgeInsets = UIEdgeInsetsMake(0, space/2, 0, space/2);
break;
case LXMImagePositionTop:
case LXMImagePositionBottom:
{
// top
imageCenterOffsetX = (imageWidth+titleWidth)/2 - imageWidth/2;
imageCenterOffsetY = -(((imageHeight+titleHeight)/2-imageHeight/2)+space/2);
titleCenterOffsetX = -((imageWidth+titleWidth/2)- (imageWidth+titleWidth)/2);
titleCenterOffsetY = (imageHeight+titleHeight - titleHeight/2)-(imageHeight+titleHeight)/2 + space/2;
CGFloat changeWidth = imageWidth + titleWidth - MAX(imageWidth, titleWidth);
CGFloat changeHeight = imageHeight+titleHeight - MAX(imageHeight, titleHeight) + space;
contentEdgeInsets = UIEdgeInsetsMake(changeHeight/2, -changeWidth/2, changeHeight/2, -changeWidth/2);
if (postion == LXMImagePositionBottom) {
imageCenterOffsetY = -imageCenterOffsetY; // opposite
titleCenterOffsetY = -titleCenterOffsetY;
}
}
break;
default:
break;
}
//相当于整体平移(imageCenterOffsetX , imageCenterOffsetY,),但不影响titleLabel
imageEdgeInsets = UIEdgeInsetsMake(imageCenterOffsetY, imageCenterOffsetX, -imageCenterOffsetY, -imageCenterOffsetX);
//相当于整体平移(titleCenterOffsetY , titleCenterOffsetX,),但不影响image
titleEdgeInsets = UIEdgeInsetsMake(titleCenterOffsetY, titleCenterOffsetX, -titleCenterOffsetY, -titleCenterOffsetX);
self.imageEdgeInsets = imageEdgeInsets;
self.titleEdgeInsets = titleEdgeInsets;
self.contentEdgeInsets = contentEdgeInsets;
}
其中imageEdgeInsets = UIEdgeInsetsMake(imageCenterOffsetY, imageCenterOffsetX, -imageCenterOffsetY, -imageCenterOffsetX);
的
含义是安全区先顶部减小imageCenterOffsetY,左侧减小imageCenterOffsetX,然后底部增加imageCenterOffsetY,右侧增加imageCenterOffsetX, 相当于整体平移(imageCenterOffsetX , imageCenterOffsetY),自然image的中心也平移了(imageCenterOffsetX , imageCenterOffsetY)。由于这个设置只对image起作用,因此title不受影响。
网友评论