UIButton的九种常见布局

作者 : 开心源码 本文共6173个字,预计阅读时间需要16分钟 发布时间: 2022-05-12 共148人阅读

本文处理UIButton常见的九种布局,上中下,左中右,以及文字和图片之间的距离问题。
git链接如下: Sameny/UIButton-STAlignment
/ 重要
支持UIButton常见排列
请在button的frame确定之后调使用
如在viewWillAppear之后货layoutSubviews方法中
/

首先定义少量枚举:

1.文字和图片朝向:

typedef NS_ENUM(NSUInteger, STContentAlignOrientation) {    STContentAlignOrientationVertical,    STContentAlignOrientationHorizontal,};

2.定义文字和图片整体的content的9个位置

typedef NS_ENUM(NSUInteger, STContentAlignment) {    STContentAlignmentLeft,    STContentAlignmentCenter,    STContentAlignmentRight,        STContentAlignmentTopLeft,    STContentAlignmentTopCenter,    STContentAlignmentTopRight,        STContentAlignmentBottomLeft,    STContentAlignmentBottomCenter,    STContentAlignmentBottomRight,};
  1. 定义几种常使用方法
- (void)verticalAlignmentWithSpace:(CGFloat)space imageAtTop:(BOOL)imageAtTop;- (void)horizontalAlignmentWithSpace:(CGFloat)space imageAtLeft:(BOOL)imageAtLeft;/** 水平方向设置UIButton中的文字和图片对齐方式  @param space 文案和图片之间的间距 @param imageAtTop YES:图片在上 @param alignment 整体内容对齐方式 */- (void)verticalAlignmentWithSpace:(CGFloat)space imageAtTop:(BOOL)imageAtTop alignment:(STContentAlignment)alignment;/** 水平方向设置UIButton中的文字和图片对齐方式 @param space 文案和图片之间的间距 @param imageAtLeft YES:图片在左 @param alignment 整体内容对齐方式 */- (void)horizontalAlignmentWithSpace:(CGFloat)space imageAtLeft:(BOOL)imageAtLeft alignment:(STContentAlignment)alignment;/** 设置UIButton中的文字和图片对齐方式  @param alignOrientation 垂直/水平放置文案和图片 @param space 文案和图片之间的间距 @param imageAtHead YES:图片在前(上/左) @param alignment 整体内容对齐方式 */- (void)alignmentWithContentAlignOrientation:(STContentAlignOrientation)alignOrientation space:(CGFloat)space imageAtHead:(BOOL)imageAtHead alignment:(STContentAlignment)alignment;

4.核心代码实现
其余方法都是调使用该方法实现

- (void)alignmentWithContentAlignOrientation:(STContentAlignOrientation)alignOrientation space:(CGFloat)space imageAtHead:(BOOL)imageAtHead alignment:(STContentAlignment)alignment {    NSString *title = self.titleLabel.text;    UIFont *font = self.titleLabel.font;    UIImage *image = self.imageView.image;        if (!title && !image) return;        CGFloat h_delta = 0;    CGFloat v_delta = 0;    CGFloat centerOffsetY = 0; // 只在STContentAlignOrientationVertical时生效//    CGSize textSize = title?[title sizeWithAttributes:@{NSFontAttributeName:font}]:CGSizeZero;    CGSize textSize = self.titleLabel.intrinsicContentSize;    if (CGSizeEqualToSize(CGSizeZero, textSize) && title.length) {        textSize = [title sizeWithAttributes:@{NSFontAttributeName:font}];    }    CGSize imageSize = image?image.size:CGSizeZero;        space = space/2; // 文字和图像各移动一半,保证整体对齐    if (alignOrientation == STContentAlignOrientationHorizontal) {        if (imageAtHead) {            [self setImageEdgeInsets:UIEdgeInsetsMake(0, -space, 0, space)];            [self setTitleEdgeInsets:UIEdgeInsetsMake(0, space, 0, -space)];        }        else {            [self setImageEdgeInsets:UIEdgeInsetsMake(0, textSize.width + space, 0, -textSize.width - space)];            [self setTitleEdgeInsets:UIEdgeInsetsMake(0, -imageSize.width - space, 0, imageSize.width + space)];        }                h_delta = (self.bounds.size.width - textSize.width - imageSize.width)/2.f - space;        v_delta = (self.bounds.size.height - MAX(textSize.height, imageSize.height))/2.f;    }    else {        if (imageAtHead) {            [self setImageEdgeInsets:UIEdgeInsetsMake(-imageSize.height/2 - space, textSize.width/2, imageSize.height/2 + space, -textSize.width/2)];            [self setTitleEdgeInsets:UIEdgeInsetsMake(textSize.height/2 + space, -imageSize.width/2, -textSize.height/2 - space, imageSize.width/2)];        }        else {            [self setImageEdgeInsets:UIEdgeInsetsMake(imageSize.height/2 + space, textSize.width/2, -imageSize.height/2 - space, -textSize.width/2)];            [self setTitleEdgeInsets:UIEdgeInsetsMake(-textSize.height/2 - space, -imageSize.width/2, textSize.height/2 + space, imageSize.width/2)];        }        h_delta = (self.bounds.size.width - MAX(textSize.width, imageSize.width))/2.f;        v_delta = (self.bounds.size.height - textSize.height - imageSize.height)/2.f - space;                /** 思想          1. 假定offset > 0            a.当我们的整体需要往上偏移的时候,top = -offset,bottom = offset            b.当我们的整体需要往下偏移的时候,top = offset,bottom = -offset         2. 假定offset < 0            a.当我们的整体需要往上偏移的时候,top = offset,bottom = -offset            b.当我们的整体需要往下偏移的时候,top = -offset,bottom = offset         */        centerOffsetY = (textSize.height - imageSize.height)/2.f; // 中心相对偏移量,假如centerOffsetY > 0,说明需要整体向image方向移动;反之向text方向移动        if (!imageAtHead) {            centerOffsetY *= -1.f; // 这样就转换成 centerOffsetY > 0,则往上移动;centerOffsetY < 0,则往下移动。这样就使offset = abs(centerOffsetY),centerOffsetY的正负性就代表了需要移动的方向。这样就和思想重合了        }    }        switch (alignment) {        case STContentAlignmentLeft:            [self setContentEdgeInsets:UIEdgeInsetsMake(-centerOffsetY, -h_delta, centerOffsetY, h_delta)];            break;        case STContentAlignmentCenter:            [self setContentEdgeInsets:UIEdgeInsetsMake(-centerOffsetY, 0, centerOffsetY, 0)];            break;        case STContentAlignmentRight:            [self setContentEdgeInsets:UIEdgeInsetsMake(-centerOffsetY, h_delta, centerOffsetY, -h_delta)];            break;                    case STContentAlignmentTopLeft:            [self setContentEdgeInsets:UIEdgeInsetsMake(-v_delta - centerOffsetY, -h_delta, v_delta + centerOffsetY, h_delta)];            break;        case STContentAlignmentTopCenter:            [self setContentEdgeInsets:UIEdgeInsetsMake(-v_delta - centerOffsetY, 0, v_delta + centerOffsetY, 0)];            break;        case STContentAlignmentTopRight:            [self setContentEdgeInsets:UIEdgeInsetsMake(-v_delta - centerOffsetY, h_delta, v_delta + centerOffsetY, -h_delta)];            break;                    case STContentAlignmentBottomLeft:            [self setContentEdgeInsets:UIEdgeInsetsMake(v_delta - centerOffsetY, -h_delta, -v_delta + centerOffsetY, h_delta)];            break;        case STContentAlignmentBottomCenter:            [self setContentEdgeInsets:UIEdgeInsetsMake(v_delta - centerOffsetY, 0, -v_delta + centerOffsetY, 0)];            break;        case STContentAlignmentBottomRight:            [self setContentEdgeInsets:UIEdgeInsetsMake(v_delta - centerOffsetY, h_delta, -v_delta + centerOffsetY, -h_delta)];            break;    }}

5.提供少量常使用的简单的方法,方便用

- (void)verticalAlignmentWithSpace:(CGFloat)space imageAtTop:(BOOL)imageAtTop {    [self alignmentWithContentAlignOrientation:STContentAlignOrientationVertical space:space imageAtHead:imageAtTop alignment:STContentAlignmentCenter];}- (void)horizontalAlignmentWithSpace:(CGFloat)space imageAtLeft:(BOOL)imageAtLeft {    [self alignmentWithContentAlignOrientation:STContentAlignOrientationHorizontal space:space imageAtHead:imageAtLeft alignment:STContentAlignmentCenter];}- (void)verticalAlignmentWithSpace:(CGFloat)space imageAtTop:(BOOL)imageAtTop alignment:(STContentAlignment)alignment {    [self alignmentWithContentAlignOrientation:STContentAlignOrientationVertical space:space imageAtHead:imageAtTop alignment:alignment];}- (void)horizontalAlignmentWithSpace:(CGFloat)space imageAtLeft:(BOOL)imageAtLeft alignment:(STContentAlignment)alignment {    [self alignmentWithContentAlignOrientation:STContentAlignOrientationHorizontal space:space imageAtHead:imageAtLeft alignment:alignment];    }

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » UIButton的九种常见布局

发表回复