iOS开发实战:从入门到上架App Store(第2版) (移动开发丛书)
上QQ阅读APP看书,第一时间看更新

2.4 按钮控件——UIButton

对于一个应用类软件来说,展示和交互就是生命。UILabel控件可以说是UIKit框架中最简单基础的显示控件,与之对应的UIButton控件是UIKit框架中最简单基础的交互控件。UIButton通常被称为按钮控件,它的确也发挥着按钮的功能,可以监听用户在屏幕视图上的多种手势操作。

2.4.1 创建一个按钮改变屏幕颜色

通过Xcode创建一个名为UIButtonTest的工程,在ViewController.m的viewDidLoad方法中添加如下代码。

Swift语言版本:

            override func viewDidLoad() {
                super.viewDidLoad()
                let button = UIButton(type: .system)
                button.frame = CGRect(x: 40, y: 100, width: 240, height: 30)
                button.backgroundColor = UIColor.red
                button.setTitle("点我一下", for: .normal)
                button.addTarget(self, action: #selector(changeColor), for: .touchUpInside)
                self.view.addSubview(button)
            }

Objective-C语言版本:

        - (void)viewDidLoad {
            [super viewDidLoad];
            UIButton * button = [UIButton buttonWithType:UIButtonTypeSystem];
            button.frame = CGRectMake(40, 100, 240, 30);
            button.backgroundColor = [UIColor redColor];
            [button setTitle:@"点我一下" forState:UIControlStateNormal];
            [button addTarget:self action:@selector(changeColor) forControlEvents:
    UIControlEventTouchUpInside];
            [self.view addSubview:button];
        }

一般通过UIButton控件的类方法buttonWithType进行按钮控件的初始化,这里传入一个UIButtonType类型的枚举参数确定创建的UIButton控件的风格,可用枚举值及意义如下。

Swift语言版本:

        public enum UIButtonType : Int {
            case custom          //自定义类型
            case system          //系统类型
            case detailDisclosure       //详情按钮类型
            case contactAdd           //添加按钮类型
        }

Objectiive-C语言版本:

        typedef NS_ENUM(NSInteger, UIButtonType) {
            UIButtonTypeCustom=0,                 //自定义类型
            UIButtonTypeSystem ,                    //标准的系统类型
            UIButtonTypeDetailDisclosure,             //详情按钮类型
            UIButtonTypeContactAdd,                 //添加按钮类型
        };

不同的风格枚举创建出来的按钮样式如图2-11~图2-14所示。

图2-11 UIButtonTypeCustom

图2-12 UIButtonTypeSystem

图2-13 UIButtonTypeDetailDisclosure

图2-14 UIButtonTypeContactAdd

UIButton控件包括背景色、字体颜色、字体、单击状态等属性,Custom风格是将这些属性全部采用默认值,需要开发者自行设置,System风格是系统定义好的一组属性设置的风格,DetailDisclosure风格会在左边显示一个详情小图标,ContactAdd风格则是在按钮左边显示一个添加小图标。

回到上面的代码,setTitle方法有两个参数,第一个设置了按钮的标题文字,第二个参数则是设置显示此标题文字时的按钮状态。UIControlState中定义了许多用于交互控件的状态定义,常用定义如下。

Swfit语言版本:

        public struct UIControlState : OptionSet {
            public static var normal: UIControlState{get}         //正常状态
            public static var highlighted: UIControlState{get}      //高亮状态
            public static var disabled: UIControlState{get}        //不可用状态
            public static var selected: UIControlState{get}         //选中状态
        }

Objective-C语言版本:

        typedef NS_OPTIONS(NSUInteger, UIControlState) {
            UIControlStateNormal       =0,                   //正常状态
            UIControlStateHighlighted  =1<<0,                 //高亮状态
            UIControlStateDisabled     =1<<1,                //不可用状态
            UIControlStateSelected     =1<<2,                //选中状态
        };

在上面的枚举中,Normal状态是按钮的初始状态,此时并没有进行任何交互操作;Highlighted状态为高亮状态,即当用户手指单击到按钮但并没有抬起时的状态;Disabled的状态为不可用状态,此时用户的单击操作将无效;Selected为选中状态,用于一些充当切换开关的按钮。

UIButton控件的核心功能是进行用户交互,通过addTarget方法进行触发方法的添加,这个方法需要3个参数,第1个参数为执行此触发方法的对象,一般会填写当前类对象本身self;第2个参数为对应的方法;第3个参数为触发方法的条件,这里需要传入一个UIControlEvents类型数据,其中常用值的意义如下。

Swift语言版本:

        public struct UIControlEvents : OptionSet {
            public static var touchDown: UIControlEvents{get}         //用户手指按下时触发方法
            public static var touchDownRepeat: UIControlEvents{get}   //用户多次重复按下时触发
            public static var touchDragInside: UIControlEvents{get}     //用户在控件范围内拖滑移动时触发
            public static var touchDragOutside: UIControlEvents { get }
                                        //用户在控件范围内按下,并拖拽到控件范围外抬起时触发
            public static var touchDragEnter: UIControlEvents{get}     //用户手指拖滑进控件范围内触发
            public static var touchDragExit: UIControlEvents{get}      //用户手指拖滑结束时触发
            public static var touchUpInside: UIControlEvents { get }
                                    //用户在控件范围内按下并在控件范围内抬起时触发,即单击
            public static var touchUpOutside: UIControlEvents { get }
                                                //用户在控件范围内按下并在范围外抬起时触发
            public static var touchCancel: UIControlEvents{get}        //触摸事件被取消时触发
            public static var valueChanged: UIControlEvents{get}       //控件的value值改变时触发
        }

Swift语言版本:

        typedef NS_OPTIONS(NSUInteger, UIControlEvents) {
            UIControlEventTouchDown,          //用户手指按下时触发方法
            UIControlEventTouchDownRepeat,     //用户多次重复按下时触发
            UIControlEventTouchDragInside,      //用户在控件范围内进行拖滑移动时触发
            UIControlEventTouchDragOutside,     //用户在控件范围内按下并且拖滑到控件范围外时触发
            UIControlEventTouchDragEnter,       //用户手指拖动进控件范围后触发
            UIControlEventTouchDragExit        //用户手指拖动结束时触发
            UIControlEventTouchUpInside        //用户在控件范围内按下并且在范围内抬起时触发,即单击
            UIControlEventTouchUpOutside ,      //用户在控件范围内按下并在范围外抬起时触发
            UIControlEventTouchCancel,          //触摸事件被取消时触发
            UIControlEventValueChanged,        //控件的value值改变时触发
        };

上面定义的选项决定了触发交互的用户操作行为。

下面是实现changeColor触发方法的示例。

Swift语言版本:

            func changeColor()  {
                self.view.backgroundColor = UIColor(red: CGFloat(arc4random()%255)/255.0, green:
    CGFloat(arc4random()%255)/255.0, blue: CGFloat(arc4random()%255)/255.0, alpha: 1)
            }

Objective-C语言版本:

        -(void)changeColor{
            self.view.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:
    arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
        }

changeColor方法中使用通过RGBA方式创建颜色对象,前3个参数分别设置了颜色红、绿、蓝3色值,第4个参数设置了颜色的透明度值,每个参数的取值都为0~1之间的浮点值。

运行工程,单击视图上的按钮,可以看到视图颜色随机切换的霓虹效果。

2.4.2 更加多彩的UIButton控件

2.4.1节的例子只是创建了一个未加任何修饰的按钮控件,可以通过UIButton的一些属性为其添加背景或内容图片来创建更多彩的按钮控件。

首先,向工程项目中添加一张图片,在工程的导航窗口部分单击Assets.xcassets包文件,选择一张图片将其拖入素材区,如图2-15所示。

图2-15 向工程中添加图片素材

通过修改为下面的代码对按钮控件进行相关设置。

Swift语言版本:

        let button = UIButton(type: .custom)
        button.setBackgroundImage(UIImage(named: "image"), for: .normal)

Objective-C语言版本:

        UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setBackgroundImage:[UIImage imageNamed:@"image"] forState:UIControlStateNormal];

运行工程,会看到如图2-16所示的效果,按钮被添加了图片背景。

图2-16 为按钮添加背景图片

可以发现,背景图片的效果是当图片作为背景时,按钮标题显示在图片层之上。UIButon中还有一个方法用于设置图片为内容图片,这种情况下图片将和标题并列显示,代码如下。

Swift语言版本:

    button .setImage(UIImage(named: "image"), for: .normal)

Objective-C语言版本:

   [button setImage:[UIImage imageNamed:@"image"] forState:UIControlStateNormal];

效果如图2-17所示。

图2-17 为按钮添加内容图片

在图2-17中可以看到,图片和文字是左右并排排列并且共同居中显示的。在很多时候,开发者会需要上下排列或以其他形式进行图片和文字的排列,UIButton类中也提供了接口供开发者进行内容、图片和文字的位置设置,示例代码如下。

Swift语言版本:

                  button.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0)
                  button.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0)
                  button.titleEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 0)

Objective-C语言版本:

            [button setContentEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
            [button setImageEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
            [button setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 0)];

setContentEdgeInsets方法用于设置整体内容的区域偏移量,UIEdgeInsetsMake()方法中的4个参数分别代表上、左、下、右4个方向的偏移量,读者可以对这4个值进行修改并观察效果。setImageEdgeInsets方法只设置内容图片的位置偏移量,setTitleEdgeInsets方法只设置内容标题的位置偏移量。