UIButton自适应设定 imageEdgeInsets 和 titleEdgeInsets 属性

2018.8.30

1.关于设定UIButtonimageEdgeInsetstitleEdgeInsets属性,在之前的开发过程中,一直反反复复地被虐,虽然每次都能通过微调参数实现想要的效果,但每次都要琢磨好久,也是很麻烦,故而再次找了资料理清思路后弄出了这个分类方法,期望以后不需要再被虐了。。。

2.另外,当前的方法仍不完美,毕竟未能穷举开发中会遇到的所有情况,仅大致实现了最通用的几种做法,关于内部实现,其实也还是微调参数 = =!

3.关于未能支持图片和标题动态变化的情况,目前还没有一个可实现的思路

  1. 相关方法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

你可能感兴趣的:(UIButton自适应设定 imageEdgeInsets 和 titleEdgeInsets 属性)