zoukankan      html  css  js  c++  java
  • 干货之UIButton的title和image自定义布局

    当需要实现一个自定义布局图片和标题的按钮时候,不知道有多少少年直接布局了UIButton,亦或是自定义一个UIView,然后以空白UIButton、UILabel、UIImageVew作为subViews。

    两者其实都一样,因为UIButton的内部subViews中,就已经存在一个UILabel和UIImageView。

    不谈论优劣,只记录一下直接布局UIButton的过程。

    因为UIButton已经有一个UILabel显示标题,一个ImageView显示图片,所以可以直接布局。但是需要注意下面记录的问题。

    首先,对一个UIButton实例button直接设置title(使用setTitle或者setAttributedTitle方法)和image(使用setImage方法),会发现,图片和标题依次紧贴并排居中显示。

    然后,修改一下这个button的titleLabel和imageView的frame,会发现,并没有什么作用。

    最后,尝试使用方法setTitleEdgeInsets和setImageEdgeInsets,会发现,没有作用或者布局异常。

     

    问题在于:

    1.获取titleLabel的frame时候,size始终是(0, 0)

    2.修改titleLabel的frame时机不对

     

    将上述修改操作放在方法layoutSubviews中是合适的。

    至于创建UIButton的子类重载方法,还是创建分类来swizzle方法都可以。

     

    即使在这个时机,使用setTitleEdgeInsets还是可能会出现文字显示不全的问题。建议直接修改titleLabel的frame。

    我采用了创建分类的方案。定义了一个方法,在+load方法中与layoutSubViews交换。

    - (void)base_layoutSubviews
    {
        [self base_layoutSubviews];
        
        if (self.resetTitleAndImageLayoutBlock) {
            self.resetTitleAndImageLayoutBlock();
        }
    }

    代码中自定义的block变量,将重置布局代码延迟到此处调用。

    以下代码,是我写的UIButton分类中自定义图片和标题布局的主要方法,其中图片位置暂时只自定义了四种:

    - (void)resetButtonTitleAndImageLayoutWithMidInset:(CGFloat)midInset imageLocation:(ButtonImageLocation)imageLocation
    {
        CGSize titleSize  = [self.titleLabel.attributedText boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;;
        CGSize imageSize = self.imageView.size;
        
        __weak typeof(self) weakSelf = self;
        
        //因为UIButton在layoutSubviews时候,会重置titleLabel的frame,所以需要延迟调用block
        self.resetTitleAndImageLayoutBlock = ^{
            switch (imageLocation) {
                case ButtonImageLocationUp: {
                    CGFloat imageOriginX = (weakSelf.width - imageSize.width) / 2.0;
                    CGFloat imageOriginY = (weakSelf.height - titleSize.height - midInset - imageSize.height) / 2.0;
                    weakSelf.imageEdgeInsets = UIEdgeInsetsMake(imageOriginY, imageOriginX, weakSelf.height - imageOriginY - imageSize.height, imageOriginX);
                    
                    CGFloat titleOriginX = (weakSelf.width - titleSize.width) / 2.0;
                    CGFloat titleOriginY = imageOriginY + imageSize.height + midInset;
                    weakSelf.titleEdgeInsets = UIEdgeInsetsMake(titleOriginY, titleOriginX, weakSelf.height - titleOriginY - titleSize.height, titleOriginX);
                    break;
                }
                case ButtonImageLocationLeft: {
                    CGFloat imageOriginX = (weakSelf.width - imageSize.width - midInset - titleSize.width) / 2.0;
                    CGFloat imageOriginY = (weakSelf.height - imageSize.height) /  2.0;
                    weakSelf.imageEdgeInsets = UIEdgeInsetsMake(imageOriginY, imageOriginX, imageOriginY, weakSelf.width - imageOriginX - imageSize.width);
                    
                    
                    CGFloat titleOriginX = imageOriginX + imageSize.width + midInset;
                    //横向时候,label的frame可以取较大范围
    //                CGFloat titleOriginY = (weakSelf.height - titleSize.height) / 2.0;
    //                weakSelf.titleLabel.frame = CGRectMake(titleOriginX, titleOriginY, titleSize.width, titleSize.height);
                    weakSelf.titleLabel.frame = CGRectMake(titleOriginX, 0, weakSelf.width - titleOriginX, weakSelf.height);
                    [weakSelf.titleLabel setTextAlignment:NSTextAlignmentLeft];
                    break;
                }
                case ButtonImageLocationDown: {
                    CGFloat titleOriginX = (weakSelf.width - titleSize.width) / 2.0;
                    CGFloat titleOriginY = (weakSelf.height - titleSize.height - midInset - imageSize.height) / 2.0;
                    weakSelf.titleEdgeInsets = UIEdgeInsetsMake(titleOriginY, titleOriginX, weakSelf.height - titleOriginY - titleSize.height, titleOriginX);
                    
                    CGFloat imageOriginX = (weakSelf.width - imageSize.width) / 2.0;
                    CGFloat imageOriginY = titleOriginY + titleSize.height + midInset;
                    weakSelf.imageEdgeInsets = UIEdgeInsetsMake(imageOriginY, imageOriginX, weakSelf.height - imageOriginY - imageSize.height, imageOriginX);
                    break;
                }
                case ButtonImageLocationRight: {
                    CGFloat titleOriginX = (weakSelf.width - imageSize.width - midInset - titleSize.width) / 2.0;
                    //横向时候,label的frame可以取较大范围
    //                CGFloat titleOriginY = (weakSelf.height - titleSize.height) / 2.0;
    //                weakSelf.titleLabel.frame = CGRectMake(titleOriginX, titleOriginY, titleSize.width, titleSize.height);
                    weakSelf.titleLabel.frame = CGRectMake(0, 0, titleOriginX + titleSize.width, weakSelf.height);
                    [weakSelf.titleLabel setTextAlignment:NSTextAlignmentRight];
                    
                    CGFloat imageOriginX = titleOriginX + titleSize.width + midInset;
                    CGFloat imageOriginY = (weakSelf.height - imageSize.height) /  2.0;
                    weakSelf.imageEdgeInsets = UIEdgeInsetsMake(imageOriginY, imageOriginX, imageOriginY, weakSelf.width - imageOriginX - imageSize.width);
                    break;
                }
            }
        };
    }

    完整的代码请参考Base项目中UIButton的分类。

    Base项目已更新:https://github.com/ALongWay/base.git

  • 相关阅读:
    SqlServer 查看数据库中所有存储过程
    SqlServer 查看数据库中所有视图
    SqlServer 查询表的详细信息
    SqlServer 遍历修改字段长度
    net core 操作Redis
    Tuning SharePoint Workflow Engine
    Open With Explorer
    Download language packs for SharePoint 2013
    Change Maximum Size For SharePoint List Template when Saving
    Six ways to store settings in SharePoint
  • 原文地址:https://www.cnblogs.com/ALongWay/p/5984805.html
Copyright © 2011-2022 走看看