关于UIButton的图文混排之图片

一,概述

    UIButton在日常开发中经常用到UI控件,它是继承自UIControl,并且集成UIImageview和UIlabel封装而成的 日常开发中我们经常需要做一些定制,这些定制很简单,就是改变image和title的位置而已.

二,涉及的相关属性

* UIButton的属性

@property(nonatomic)         UIEdgeInsets contentEdgeInsets UI_APPEARANCE_SELECTOR(UI_APPEARANCE_SELECTOR 表示可以外观定制);
@property(nonatomic)         UIEdgeInsets titleEdgeInsets;  
@property(nonatomic)         UIEdgeInsets imageEdgeInsets; 

* UIControl的属性

@property(nonatomic)          UIControlContentVerticalAlignment contentVerticalAlignment; 
@property(nonatomic)          UIControlContentHorizontalAlignment contentHorizontalAlignment;

三,相关的简单测试

UIButton * abutton =({
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame =CGRectMake(0, 0, 200, 200);
        button.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2);
        [button setTitle:@"我好怕怕!" forState:UIControlStateNormal];
        [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"small"] forState:UIControlStateNormal];
        [button setBackgroundColor:[UIColor orangeColor]];
        button;
    });
    [self.view addSubview:abutton];
    //测试
      //button 内部imageView的frame
    NSLog(@"%@",NSStringFromCGRect(abutton.imageView.frame));
      //button 内部label 的frame
    NSLog(@"%@",NSStringFromCGRect(abutton.titleLabel.frame)); 

1>仅有文字

     

打印结果:

2016-09-14 10:56:06.213 撒打发士大夫撒旦法[2948:48347] {{0, 0}, {0, 0}}

2016-09-14 10:56:06.213 撒打发士大夫撒旦法[2948:48347] {{61.333333333333336, 89.333333333333329}, {77.333333333333329, 21.666666666666668}}

分析结果:

      控件本身的大小是(200,200),此时label的大小是{77.333333333333329, 21.666666666666668} 位置为居中.

2>仅有图片

   

打印结果:

2016-09-14 10:59:47.868撒打发士大夫撒旦法[3140:52538] {{72, 71}, {56, 58}}

2016-09-14 10:59:47.870撒打发士大夫撒旦法[3140:52538] {{0, 0}, {0, 0}}

分析结果 :

  此时控件本身的大小是(200,200),此时imageView的大小是{56, 58} 位置居中.  而此时我们查看图片的尺寸大小,它的大小也是{56,58}

  这样似乎看来,button控件内部对ImageView的设置是以图片本身尺寸的大小进行创建的.

3>文字和图片共存

     1> 图片尺寸小于(200 ,200)

         

打印结果:

2016-09-14 11:12:21.496 撒打发士大夫撒旦法[3543:59053] {{33.333333333333336, 71}, {56, 58}}

2016-09-14 11:12:21.496 撒打发士大夫撒旦法[3543:59053] {{89.333333333333343, 89.333333333333329}, {77.333333333333329, 21.666666666666668}}

    2>图片尺寸大于(200,200)

         

打印结果:

2016-09-14 11:14:29.573撒打发士大夫撒旦法[3608:60400] {{0, 0}, {200, 200}}

2016-09-14 11:14:29.573撒打发士大夫撒旦法[3608:60400] {{200, 89.333333333333329}, {0, 21.666666666666668}}

分析结果:

  当文字和图片同时存在是,当图片本身的尺寸大于button控件的尺寸时,即使设置了文字,仍然只显示图片,不显示文字. 并且图片做伸缩处理铺满整个控件.

四, 相关问题总结

  1> 关于Button图片自适应和文本自适应问题

       *图片自适应*

         我们在上面的测试中,发现当我们的图片尺寸小于button控件本身的尺寸时, 图片是以图片的尺寸来创建ImageView的,且居中显示. 如果我们想让小图片铺满整个Button控件怎么办呢? 

        * 不成功方法:

         1)用ImageView本身自适应的方法可行吗?  显然不行,因为ImageView的大小本身就是依据图片的尺寸进行创建的, 所以当然没有效果.

         2)用Button自身的ContentMode设置,也是没效果的.

       * 成功的方法:
         1) 

       button.contentHorizontalAlignment= UIControlContentHorizontalAlignmentFill;
       button.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;

         2)继承UIButton,重写 imageRectForContentRect 方法返回button的bounds  

      - (CGRect)imageRectForContentRect:(CGRect)bounds{
               return CGRectMake(0.0, 0.0, self.size.width, self.size.height);
      }

      *文本自适应*

           同理图片,titleLabel的大小,是根据传入的文字来进行计算创建的, 那么当文字的宽度高于控件的宽度怎么办呢?

         * 不成功的方法

           1)用titleLabel自身的sizeToFit来自适应可行吗?显然也是不行的,因为titleLabel的大小就是根据文字来创建的,所以当然没有效果.

         * 成功的方法

           1)使用Button的sizeToFit 方法, 不过button的本身的形状会变形, 假如不影响你的需求可以尝试.

           2)使用titleLabel的

numberOfLines的自动换行.

           3)使用titleLabel的

adjustsFontSizeToFitWidth的方法, 不过titlLabel的字体会变小,来适应UIButton,假如不影响需求可以尝试.

    2>UIButton上的imageEdgeInsets,titleEdgeInsets与contentEdgeInsets的属性使用

        相关含义:

               imageEdgeInsets  设置UIButton的实例变量的图片位于四个边框的间的间距(这里边框,是指图片本身的初始状态来作参考的)

               titleEdgeInsets      设置UIButton的实例变量的标题位于四个边框的间的间距(这里边框,是指标题本身的初始状态来作参考的)

             contentEdgeInsets  UIButton中包含的所有内容与它本身的frame间的边距


       举个例子:

            初始状态:

UIButton * abutton =({
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame =CGRectMake(0, 0, 200, 200);
        button.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2);
        [button setTitle:@"我好怕怕!" forState:UIControlStateNormal];
        [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"small"] forState:UIControlStateNormal];
        [button setBackgroundColor:[UIColor orangeColor]];
        button.titleLabel.adjustsFontSizeToFitWidth =YES;
        button;
    });
    [self.view addSubview:abutton];

 效果图:

   

改变状态

    UIButton * abutton =({
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame =CGRectMake(0, 0, 200, 200);
        button.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2);
        [button setTitle:@"我好怕怕!" forState:UIControlStateNormal];
        [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"small"] forState:UIControlStateNormal];
        button.titleEdgeInsets=UIEdgeInsetsMake(0,-button.imageView.bounds.size.width, 0, button.imageView.bounds.size.width);
        button.imageEdgeInsets =UIEdgeInsetsMake(0,button.titleLabel.bounds.size.width, 0, -button.titleLabel.bounds.size.width);
        [button setBackgroundColor:[UIColor orangeColor]];
        button.titleLabel.adjustsFontSizeToFitWidth =YES;
        button;
    });
    [self.view addSubview:abutton];

效果图:

  

怎么理解呢? 

     button.titleEdgeInsets=UIEdgeInsetsMake(0,-button.imageView.bounds.size.width0, button.imageView.bounds.size.width);

     button.imageEdgeInsets =UIEdgeInsetsMake(0,button.titleLabel.bounds.size.width0, -button.titleLabel.bounds.size.width);


titleLabel左边相对于原来的位置向左移动了ImageView的宽度(-)

titleLabel右边相对于原来的位置向左移动了ImageView的宽度(+)

同是向左移动为什么左边是"-"的,而右边的是"+"的呢? 这是因为UIEdgeInset本身就是相对于内部边界而言的,左边相对于原来的位置已经超出了内部边界, 而右边向左却仍然在内部边界之内.

      3>关于contentVerticalAlignment 和 contentHorizontalAlignment;

         contentVerticalAlignment和contentHorizontalAlignment 是UIControl的两个属性,用于排列内部元素.
  typedef NS_ENUM(NSInteger, UIControlContentVerticalAlignment) {
    UIControlContentVerticalAlignmentCenter  = 0,
    UIControlContentVerticalAlignmentTop     = 1,
    UIControlContentVerticalAlignmentBottom  = 2,
    UIControlContentVerticalAlignmentFill    = 3,
};
  typedef NS_ENUM(NSInteger, UIControlContentHorizontalAlignment) {
    UIControlContentHorizontalAlignmentCenter = 0,
    UIControlContentHorizontalAlignmentLeft   = 1,
    UIControlContentHorizontalAlignmentRight  = 2,
    UIControlContentHorizontalAlignmentFill   = 3,
};
共有16种选择, 其中默认的是居中选择

列举其它的部分选择方式




注意:
      在V:fill H:fill 选择中,title并没有在水平方向铺满全屏,仍然保持titleLab的原始宽度. 这说明TitleLabel的宽度,不能被拉伸,却能被压缩. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值