欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iOS基础控件--UIButton

程序员文章站 2022-05-30 13:49:14
...

UIButton和UITextField一样都不是UIView的直接子类,都是UIView子类UIControl的子类。

UIButton介绍

UIButton是按钮控件,用于用户点击和程序进行交互。按钮的交互是最简单也是最直接的,只需要点击就可以进行操作,所以这个控件也是最常用的。按钮的知识点比较简单,比较难的一点就是按钮上图文排布上面,有的时候可能会因为设计需要我们要让按钮上的图片和文字按照要求排列,这个时候就要有一点计算能力了。本文最后再说具体的实现方式。

UIButton创建

    //UIButton创建
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

UIButton的创建和UIView的创建有所不同,一般情况我们创建按钮使用一个类方法,同时对按钮样式进行赋值。

+ (instancetype)buttonWithType:(UIButtonType)buttonType;

按钮类型的typedef如下:

typedef NS_ENUM(NSInteger, UIButtonType) {
    UIButtonTypeCustom = 0,                         // no button type
    UIButtonTypeSystem NS_ENUM_AVAILABLE_IOS(7_0),  // standard system button

    UIButtonTypeDetailDisclosure,
    UIButtonTypeInfoLight,
    UIButtonTypeInfoDark,
    UIButtonTypeContactAdd,

    UIButtonTypePlain API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios, watchos), // standard system button without the blurred background view

    UIButtonTypeRoundedRect = UIButtonTypeSystem   // Deprecated, use UIButtonTypeSystem instead
};

在开发中我们常用的样式是UIButtonTypeCustom,这个可以理解为自定义样式,也就是可以根据程序员的需求自行设定。其他的比如UIButtonTypeContactAdd这个就是创建一个“+”样式的按钮,要是项目中有这样的需求可以快捷创建设置。

按钮创建完成后需要使用frame属性设置位置和大小。

    //设置按钮的位置和大小
    button.frame = CGRectMake(100, 200, 50, 30);

UIButton的属性

1、titleLabel属性

    @property(nullable, nonatomic,readonly,strong) UILabel     *titleLabel NS_AVAILABLE_IOS(3_0);

从上面可以看出titleLabel属性是一个readonly属性,这个属性常用来获取按钮上的展示文字的Label。而按钮上文字的设置是要和状态state关联的。所以设置按钮上的文字使用方法设置。
2、imageView属性

@property(nullable, nonatomic,readonly,strong) UIImageView *imageView  NS_AVAILABLE_IOS(3_0);

和上面的titleLabel属性一样,这个属性也是一个readonly属性。常用来获取按钮上展示图片的imageView。

UIButton的方法

1、设置按钮上的文字和状态
- (void)setTitle:(nullable NSString *)title forState:(UIControlState)state;
这个方法是设置按钮上展示的文字和文字展示时的状态。

    //设置按钮上的文字 设置为默认状态
    [button setTitle:@"点一下" forState:UIControlStateNormal];
    //设置按钮上的文字 设置为点击状态
    [button setTitle:@"点了一下" forState:UIControlStateSelected];

state的typedef如下,可以根据需要进行设定。

typedef NS_OPTIONS(NSUInteger, UIControlState) {
        UIControlStateNormal       = 0,
        UIControlStateHighlighted  = 1 << 0,                  // used when UIControl isHighlighted is set
        UIControlStateDisabled     = 1 << 1,
        UIControlStateSelected     = 1 << 2,                  // flag usable by app (see below)
        UIControlStateFocused NS_ENUM_AVAILABLE_IOS(9_0) = 1 << 3, // Applicable only when the screen supports focus
        UIControlStateApplication  = 0x00FF0000,              // additional flags available for application use
        UIControlStateReserved     = 0xFF000000               // flags reserved for internal framework use
};

2、设置按钮上文字颜色

- (void)setTitleColor:(nullable UIColor *)color forState:(UIControlState)state UI_APPEARANCE_SELECTOR; // default if nil. use opaque white
    //设置按钮上文字颜色 默认状态为蓝色,点击状态为红色
    [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
    [button setTitleColor:[UIColor redColor] forState:UIControlStateSelected];

3、设置按钮上的图片

- (void)setImage:(nullable UIImage *)image forState:(UIControlState)state; 

和设置文字一样,根据设置需要设定不同状态下的图片

    //设置按钮上的图片,默认状态下为图片add   点击状态下为图片del
    [button setImage:[UIImage imageNamed:@"add"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"del"] forState:UIControlStateSelected];

4、设置按钮上的背景图片

- (void)setBackgroundImage:(nullable UIImage *)image forState:(UIControlState)state UI_APPEARANCE_SELECTOR; // default is nil

这里的背景图片和上面的图片不同,背景图片是作为按钮的背景。一般不会涉及到和文字的排布问题。
使用方法和上面一样,这里就不写了。(程序员都很懒。。。。。)下面来说一下重点的按钮上文字和图片的排布。

按钮的点击事件

    //给按钮添加点击事件
    [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

给按钮添加点击事件的方法很简单,需要给这个方法赋值3个参数,第一个是调用点击事件的对象,一般是self也就是本类,第二个是点击事件处理方法名称,这里使用btnClick:命名,这个名称后面的“:”表示方法需要参数,而这个参数就是点击的按钮,没有“:”表示不需要参数。第三个是点击事件相应的方式,这里有很多种,UIControlEventTouchUpInside只是其中一种,表示当点击按下去的时候调用。

typedef NS_OPTIONS(NSUInteger, UIControlEvents) {
    UIControlEventTouchDown                                         = 1 <<  0,      // on all touch downs
    UIControlEventTouchDownRepeat                                   = 1 <<  1,      // on multiple touchdowns (tap count > 1)
    UIControlEventTouchDragInside                                   = 1 <<  2,
    UIControlEventTouchDragOutside                                  = 1 <<  3,
    UIControlEventTouchDragEnter                                    = 1 <<  4,
    UIControlEventTouchDragExit                                     = 1 <<  5,
    UIControlEventTouchUpInside                                     = 1 <<  6,
    UIControlEventTouchUpOutside                                    = 1 <<  7,
    UIControlEventTouchCancel                                       = 1 <<  8,

    UIControlEventValueChanged                                      = 1 << 12,     // sliders, etc.
    UIControlEventPrimaryActionTriggered NS_ENUM_AVAILABLE_IOS(9_0) = 1 << 13,     // semantic action: for buttons, etc.

    UIControlEventEditingDidBegin                                   = 1 << 16,     // UITextField
    UIControlEventEditingChanged                                    = 1 << 17,
    UIControlEventEditingDidEnd                                     = 1 << 18,
    UIControlEventEditingDidEndOnExit                               = 1 << 19,     // 'return key' ending editing

    UIControlEventAllTouchEvents                                    = 0x00000FFF,  // for touch events
    UIControlEventAllEditingEvents                                  = 0x000F0000,  // for UITextField
    UIControlEventApplicationReserved                               = 0x0F000000,  // range available for application use
    UIControlEventSystemReserved                                    = 0xF0000000,  // range reserved for internal framework use
    UIControlEventAllEvents                                         = 0xFFFFFFFF
};

上面的这个typedef就是全部的ControlEvents,根据设计的需求可以设置不同的ControlEvents。

重点

一般带有图片和文字的按钮设计分两种,第一种是图片为背景,上面有文字,这样的设计实现起来很简单,直接设置按钮的背景图和文字即可。第二种就是乱七八糟设计,图片和文字的位置可以是任何位置。程序员看到这样的设计就头疼,就不能简单点么?

按钮上图文混排要说到按钮的两个属性:titleEdgeInsets和imageEdgeInsets。
titleEdgeInsets是titleLabel相对于其上下左右的inset,跟tableView的contentInset是类似的;调用的方法分别是setTitleEdgeInsets:和setImageEdgeInsets:。这两个方法的参数都是一个UIEdgeInsetsMake,

UIKIT_STATIC_INLINE UIEdgeInsets UIEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) {
    UIEdgeInsets insets = {top, left, bottom, right};
    return insets;
}

UIEdgeInsetsMake的4个值分别是上、左、下、右。通过对这4个值的设定就可以进行图文混排。

先来说一下按钮上图片和文字相对于按钮的关系:

情况1:在按钮上只有文字的时候,这个时候,文字所在的Label的位置是相对于按钮的。
iOS基础控件--UIButton
在上面这张图片上,按钮上文本设置是居中的,文本label的位置是相对于按钮本身的居中。

情况2:在按钮上只有图片,这个情况和上面的情况一样,图片的位置设定也是相对于按钮本身的。

情况3:按钮上既有图片也有文本,这个时候在默认设置情况下,图片在左,文本在右。这个时候图片的上下左是相对于按钮的,右是相对于文本的。同理,文本的上下右是相对于按钮的,左是相对于图片的。

对上面的关系有了了解我们就可以对按钮上图文混排进行设计了。
简单的上下排布:

    //使图片和文字水平居中显示
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
    //文字距离上边框的距离增加imageView的高度,距离左边框减少imageView的宽度,距离下边框和右边框距离不变
    [button setTitleEdgeInsets:UIEdgeInsetsMake(button.imageView.frame.size.height+10 ,-button.imageView.frame.size.width, 0.0,0.0)];
    //图片距离右边框距离减少图片的宽度,其它不边
    [button setImageEdgeInsets:UIEdgeInsetsMake(-10, 0.0,0.0, button.titleLabel.bounds.size.width)];

简单的左右换位排布:

    //文本距离按钮边框的上下不变 左边距-图片宽度 右边距+图片宽度
    [button setTitleEdgeInsets:UIEdgeInsetsMake(0, -button.imageView.bounds.size.width, 0, button.imageView.bounds.size.width)];
    //图片距离按钮边框的上下不变 左边距+文本宽度 右边距-文本宽度
    [button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, -button.titleLabel.bounds.size.width)];

既然是混排肯定就不是只有上下和左右。关于其他的排列方式这里就不介绍了。百度一下能找到很多关于混排的类别。这里放一个别人帖子的连接iOS Button的文字和图片上下或左右排列的方法