ios学习笔记2--UIButton基础知识和自定义详解

来源:互联网 发布:音频发生器软件 编辑:程序博客网 时间:2024/05/23 17:24

UIButton是我们经常用的UI控件,继承UIControl。这里将对UIButton的基本使用方法和自定义UIButton进行详细介绍。

一、UIBUtton基本知识介绍

对于我们学习一个新的控件、无外乎两种方法。第一种是在xcode中的.m文件查看该控件的属性和相关方法,第二种直接在storyBoard中拖入该控件,然后在Xcode中的属性检查器面板,查看该控件属性。这里选择第二种,形象生动。

这里写图片描述

无论学习什么控件,都需要把该控件的基本属性熟记于心。

1、Type
主要有以下几种
这里写图片描述

  • Custom
    该属性允许开发者设计按钮外观、而不是系统默认样式,比如要自定义Button样式。

  • System
    该属性使得按钮呈现默认风格。

  • Detail Disclosure
    该属性使得按钮呈现一个详情图标。这里写图片描述

  • InfoLight
    该属性使得按钮呈现一个图标,同Detail Disclosure。

  • InfoDark
    该属性使得按钮呈现一个图标,同Detail Disclosure。
  • ContactAdd
    该属性使得按钮呈现一个图标。这里写图片描述

总结:在我们使用Button过程中,一般直接选用Custom。

2、State Config
该属性用来设置按钮的的状态。按钮总共有4种状态:

默认状态:UIControlStateNormal

高亮状态:UIControlStateHighlighted
对应属性:highlighted

选中状态:UIControlStateSelected
对应属性:selected

禁用状态:UIControlStateDisabled
对应属性:enabled

备注:高亮和选中状态的区别:高亮指的是用户碰触该按钮的时候,按钮显示高亮效果、用户离开时按钮高亮效果消失;选中状态是需要开发者设置selected属性为YES时,才会展示某种效果、设置为NO时,效果消失。

3、Title
标题、默认使用Plain、不过多解释

4、Font
设置文本标题字体大小、不过多解释

5、TextColor
设置文本标题颜色、不过多解释

6、Shadow Color
文本标题阴影颜色、需要设置Shadow Offset

7、Image
如果给按钮设置image,前面设置的Title属性可能会不起作用,该按钮只会显示一张图片。如果还想显示文字,则需要设置titleEdgeInsets和imageEdgeInsets属性<后面的自定义button会详细讲解>。

8、Backgroud
设置按钮的背景图片、不会遮挡标题文字

9、Shadow Offset
设置阴影文本与正常文本的偏移量

这里写图片描述

Width:大于0,阴影文本相对右偏移,反之,左偏移
Height:大于0,阴影文本相对下偏移,反之,上偏移

10、Line Break
对button文本标题的截断、因为标题太长、显示不全。有以下三种模式:
Truncate Head : 对字符串多余对开头部分截断,用…代替截断部分。
Truncate Middle : 对字符串多余的中间部分截断,用…代替截断部分。
Truncate Tail : 对字符串多余的结尾部分截断,用…代替截断部分。

11、Edge和Inset
二者结合在一起使用才有意义、不是孤立存在的。
Edge指的是边界,Inset指的是边界间距。
下面自定义Button会详细介绍到。

二、改变button中图片和文字的位置

默认情况下设置按钮的图片和文字,展示效果是图片在右边、文字在左边。
相关代码如下:

UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];[btn setImage:[UIImage imageNamed:@"qq.jpg"] forState:UIControlStateNormal];[btn setTitle:@"title" forState:UIControlStateNormal];[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];btn.layer.borderColor = [UIColor redColor].CGColor;btn.layer.borderWidth = 1.0;btn.frame = CGRectMake(100, 100, 200, 200);[self.view addSubview:btn];

效果图如下:

这里写图片描述

接下来将设置图片上文字下、图片左文字右、图片下文字上三种模式。

我们会通过两种方法进行,第一种方法:通过UIEdgeInsets设置边距;第二种方法通过完全自定义的方法。最后,我们将会对比这两种方法的优缺点。

方法一:通过UIEdgeInsets设置边距

1、UIEdgeInsets设置边距
首先需要介绍UIEdgeInsets

typedef struct UIEdgeInsets {    CGFloat top, left, bottom, right;  // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'} UIEdgeInsets;  

这里的四个参数表示距离上边界、左边界、下边界、右边界的距离,默认都是零。此时图片和文字在按钮的正中间。

以前在设置这个参数时,有一个误解,比如说设置按钮图片的上边距为60、即UIEdgeInsetsMake(60, 0, 0, 0)。一直以为是下面这种效果:

这里写图片描述

其实应该是这种效果:top、left、bottom、right是相对于原来的位置而言的。

这里写图片描述

疑问:设置距离上边距60,为什么这里标注30???
解答:其实这个和按钮的contentHorizontalAlignment、contentVerticalAlignment两个属性有关<下面用button的content属性代替>;默认情况下,两个属性都是AlignmentCenter,此时imageView和titleLabel两个子控件实际移动距离是设置距离的一半(60 / 2);下面会详细介绍。

小结:
top :大于0、向下移动;反之向上移动
left:大于0、向右移动;反之向左移动
bottom: 大于0、向上移动;反之向下移动
right: 大于0、向左移动;反之向右移动

2、图片右文字左模式
思路:将imageView向右平移一个自身控件的宽度、将titleLabel向左平移一个自身控件宽度。

代码如下:

//3、获取控件宽度CGFloat imageViewWidth = btn.imageView.frame.size.width;CGFloat titleWidth = btn.titleLabel.frame.size.width;//4、设置内边距[btn setImageEdgeInsets:UIEdgeInsetsMake(0, imageViewWidth, 0, 0)];[btn setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, titleWidth)];

效果如下:

这里写图片描述

此时效果图并不是我们想要的,就像上面提到的,这里是由于button的两个特殊属性引起的,此时需要将设置距离=自身宽度 * 2。

//4、设置内边距[btn setImageEdgeInsets:UIEdgeInsetsMake(0, imageViewWidth * 2, 0, 0)];[btn setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, titleWidth * 2)];

实际效果如下:
这里写图片描述

此时有个疑问,如果设置button中的两个属性为其它模式,移动距离是否还是设置距离的2倍???

经过一翻实验发现:如果将contentHorizontalAlignment设置为UIControlContentHorizontalAlignmentCenter,则左右移动距离=设定距离 / 2;其它模式下左右移动距离=设定距离。同理,如果将contentVerticalAlignment设置为UIControlContentVerticalAlignmentCenter,则上下移动距离= 设定距离 / 2;其它模式下上下移动距离=设定距离。

另外,如果将imageView和titleLabel设置为以下四种情况,则在当前位置,二者无法进行左右互换:

这里写图片描述

下面写的代码默认button的content属性为center。

为了方便理解,代码见gitHub地址:
https://github.com/yscMichael/UIButton_ChangeSubviewsPosition

3、图片上文字下模式
思路:将imageView向上移动(自身高度/2)、向右移动(自身宽度/2);将titleLabel向下移动(自身高度/2)、向左移动(自身宽度/2)。

//3、获取控件宽度CGFloat imageViewWidth = btn.imageView.frame.size.width;CGFloat imageViewHeight = btn.imageView.frame.size.height;CGFloat titleWidth = btn.titleLabel.frame.size.width;CGFloat titleHeight = btn.titleLabel.frame.size.height;//4、设置内边距[btn setImageEdgeInsets:UIEdgeInsetsMake(0, imageViewWidth, imageViewHeight, 0)];[btn setTitleEdgeInsets:UIEdgeInsetsMake(titleHeight, 0, 0, titleWidth)];

效果如下图:
这里写图片描述

4、图片下文字上模式
思路:将imageView向下移动(自身高度/2)、向右移动(自身宽度/2);将titleLabel向上移动(自身高度/2)、向左移动(自身宽度/2)。

//3、获取控件宽度CGFloat imageViewWidth = btn.imageView.frame.size.width;CGFloat imageViewHeight = btn.imageView.frame.size.height;CGFloat titleWidth = btn.titleLabel.frame.size.width;CGFloat titleHeight = btn.titleLabel.frame.size.height;//4、设置内边距[btn setImageEdgeInsets:UIEdgeInsetsMake(imageViewHeight, imageViewWidth, 0, 0)];[btn setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, titleHeight, titleWidth)];

效果图如下:

这里写图片描述

补充:默认情况下,imageView和titleLabel控件二者中心点与UIButton的中心点重合。

5、此方法使用局限性
当图片过大的时候,当前按钮只会显示一张图片;因为我们开发人员无法控制按钮内部的imageView和titleLabel两个子控件大小、只能移动位置。
这里写图片描述

解释:
1.当button.width < image.width时,只显示被压缩后的图片,图片是按fillXY的方式压缩。

2.当button.width > image.width,且 button.width < (image.width + text.width)时,图片正常显示,文本被压缩。

3.当button.width > (image.width + text.width),两者并列默认居中显示,可通过button的属性contentHorizontalAlignment改变对齐方式。

方法二、自定义Button

思路:设置内部imageView子控件的高度=宽度=当前按钮的高度;设置内部titleLabel的高度=当前按钮的高度、宽度=(当前按钮的宽度 - 当前按钮的高度)。

重写系统的两个方法:
-(CGRect)titleRectForContentRect:(CGRect)contentRect
-(CGRect)imageRectForContentRect:(CGRect)contentRect

详细见gitHub代码:
https://github.com/yscMichael/YYButton

0 0
原创粉丝点击