iOS_UI控件学习 -> 第一周

iOS_UI控件学习 -> 第一周_第1张图片

UIView的基本属性和方法

说明:
UIView是iOS中所有视图(控件)直接/间接的父类; 所以UIView的属性和方法,对于其他类型的视图都有效

  • 视图: 在屏幕上能看见的所有的东西都属于视图
  • 将视图展示在屏幕上的两个必要条件:
    • 必须设置坐标和大小(默认坐标是(0,0)),大小(0,0))
    • 将视图添加到屏幕上已有的视图上

创建视图的基本步骤:

创建UIView对象
设置frame属性(由坐标和大小(width,height)两个部分组成)
iOS中所有的结构体都有一个对应的Make方法用来快速的创建一个结构体变量
将视图添加到界面上
设置背景颜色

背景颜色:
视图的背景颜色默认是透明色
背景颜色的设置方式:

  • 通过类型方法创建指定颜色
    通过三原色来创建颜色
    创建灰色

在当前视图添加其他视图的两种方式
方式一:
创建视图对象并且设置frame属性(添加到白色视图上)

        let yellowView = UIView.init()
        self.view.addSubview(yellowView)
        yellowView.backgroundColor = UIColor.yellowColor()
        yellowView.frame = CGRectMake(35, 35, 50, 50)

方式二:

        let yellowView = UIView.init(frame: CGRectMake(25, 25, 50, 50))
        redView.addSubview(yellowView)
        yellowView.backgroundColor = UIColor.yellowColor()

小结:
计算视图的坐标的时候,注意相对性。当前视图被添加到那个视图上,那么当前视图的坐标就是相当于谁来算的。

Frame的相关属性

坐标及中心点

        // 创建一个视图对象
        let redView = UIView.init()

        // 添加到界面上
        self.view.addSubview(redView)

        // 设置背景颜色
        redView.backgroundColor = UIColor.redColor()

        // 1.frame(坐标和大小)
        redView.frame = CGRectMake(100, 100, 100, 100)

        // 2.center(中心点)
        // a.通过frame可以确定视图的中心点坐标
        print(redView.center)

        // b.可以通过改变center的值,去改变视图的坐标
        redView.center = CGPointMake(200, 200)
        print(redView.frame)

        // 3.bounds(坐标和大小)
        // 掌握默认情况下,bounds的坐标是(0,0),大小和视图的frame大小一样
        print(redView.bounds)

        // 了解:
        // 如果改变bounds的大小,frame的大小和坐标都改变,center不变

        redView.bounds = CGRectMake(0, 0, 250, 250)
        print("frame\(redView.frame)")
        print("center\(redView.center)")


bounds

  • 如果改变bounds的坐标,不影响当前视图的位置,但是影响添加到当前视图上的指示图的坐标,不建议修改bounds

        redView.bounds = CGRectMake(0, 0, 100, 100)
        let yellowView = UIView.init(frame: CGRectMake(10, 10, 40, 40))
        yellowView.backgroundColor = UIColor.yellowColor()
        redView.addSubview(yellowView)

transform(形变)

  • 缩放
  • 旋转 - 旋转角度(圆周率对应的角度值)
  • 平移
  • 组合 - 多种形变之间的组合

注意
当前视图发生形变,那么添加到当前视图上的所有的视图会跟着一起形变

        // a.缩放
        // 参数1: x方向上的缩放比例
        // 参数2: y方向上的缩放比例
        redView.transform = CGAffineTransformMakeScale(0.77, 1.5)


        // b.旋转
        redView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_4))

        // c.平移
        // 参数1: 在x方向上平移的距离,负值 -> 向左移,正值 -> 向右移
        // 参数2: 在y方向上平移的距离,负值 -> 向上移,正值 -> 向下移
        redView.transform = CGAffineTransformMakeTranslation(0, 250)

        // d.多个形变同时发生
        // 在另外一个形变的前提下旋转
        // 参数1: 另外一个形变
        redView.transform = CGAffineTransformRotate(
        CGAffineTransformMakeScale(0.5, 0.5), CGFloat(M_PI_4 / 2))

        // 在另外一个形变的前提下平移
        redView.transform =
        CGAffineTransformTranslate(redView.transform, 0, 300)

        // 在另外一个形变的前提下缩放
        redView.transform = CGAffineTransformScale(
        CGAffineTransformMakeTranslation(100, 0), 0.5, 1)

        // 组合两个形变
        // 旋转形变
        let rotate = CGAffineTransformMakeRotation(0.3)
        // 平移形变
        let transLation = CGAffineTransformMakeTranslation(100, 100)
        // 将旋转形变和平移形变组合
        redView.transform = CGAffineTransformConcat(rotate, transLation)

UIView父子视图

特点及方法

  • 一个视图只有一个父视图,但是它可以有多个子视图
  • 连续将同一个视图添加到两个视图上,只有最后一次添加才是有效的

示例:
1.创建一个UIView类型的父视图并将它显示在主界面上

        // 1.创建一个UIView对象(父视图)
        let redView = UIView.init(frame: CGRectMake(100, 100, 200, 200))

        // 2.设置背景颜色
        redView.backgroundColor = UIColor.redColor()

        // 3.添加到界面上
        // self.view就是redView的父视图,redView就是self.view的子视图
        self.view.addSubview(redView)

2.创建一个UIView类型的子视图并将其添加到父视图上

        // 创建一个黄色到子视图
        let yellowView = UIView.init(frame: CGRectMake(0, 0, 50, 50))
        yellowView.backgroundColor = UIColor.yellowColor()

        redView.addSubview(yellowView)

3.获取一个子视图的父视图,并将其用不同的颜色显示出来

        let superView = redView.superview
        superView?.backgroundColor = UIColor.grayColor()

4.获取一个父视图中的所有子视图

  • 设置子视图的tag值(默认的tag值都是0),设tag值的时候必须大于0,其作用是用来区分界面上不同的视图,通过tag值可以拿到指定的视图
        redView.tag = 100
        yellowView.tag = 200

                for item in subViews {
            // (1) 遍历视图数组通过tag值获取相应的视图
            if item.tag == 100 {
                print("红色视图")
                item.backgroundColor = UIColor.orangeColor()
            }

            if item.tag == 200 {
                print("黄色视图\(item)")
            }
        }

            // (2) 遍历视图数组通过判断视图类型获取视图
            for item in subViews {

            // 判断item是否是UILabel类型的,如果是就返回true,如果不是就返回false
            if item.isKindOfClass(UILabel.self) {
                print(item)
            }
        }
            // (3) 通过tag值直接获取相应视图
            let subView2 = self.view.viewWithTag(200)
            subView2?.frame.origin.y = 100

subViews是主界面(self)自带的视图数组

视图的层次关系

在一个视图上添加多个子视图的时候,子视图之间如果有公共的部分,那么后添加的子视图会覆盖先添加到子视图,这时候可以通过改变他们之间的层次关系来改变视图之间覆盖的状态。

例:

        let view1 = self.creatView(CGRectMake(50, 100, 100, 100), 
        backColor: UIColor.yellowColor())
         let view2 = self.creatView(CGRectMake(100, 150, 100, 100), 
         backColor: UIColor.redColor())
          let view3 = self.creatView(CGRectMake(150, 200, 100, 100), 
          backColor: UIColor.blueColor())
           let view4 = self.creatView(CGRectMake(125, 125, 100, 100), 
          backColor: UIColor.greenColor())

        // 2. 将指定的视图放到最上层
        self.view.bringSubviewToFront(view2)

        // 3. 将指定的视图放到最下层

        // 4. 将指定的视图插入到另一个视图的上面
        self.view.insertSubview(view2, aboveSubview: view3)

        // 5. 将制定的视图插入到另一个视图的下面
        self.view.insertSubview(view2, belowSubview: view1)
    }

    // 创建视图
    func creatView(frame: CGRect, backColor: UIColor) -> UIView {
        // 创建视图对象
        let subView = UIView.init(frame: frame)

        // 设置背景颜色
        subView.backgroundColor = backColor

        // 添加到界面上
        self.view.addSubview(subView)

        // 将创建的视图返回
        return subView

    }

创建UIView的动画

    override func viewDidLoad() {
        super.viewDidLoad()

        // 创建视图
        subView.frame = CGRectMake(0, 0, 100, 100)
        subView.center = self.view.center
        subView.backgroundColor = UIColor.greenColor()
        self.view.addSubview(subView)

        self.UIViewAnimation4()
        layerAction()
    }

    // MARK:  - Layer属性
    func layerAction() {

        // Layer属性是负责视图的形状(显示)

        // 1.切圆角
        // 当圆角的值为正方形的宽的一半,就可以切成一个圆
        self.subView.layer.cornerRadius = 50

        // 2.设置边框
        self.subView.layer.borderWidth = 3

        self.subView.layer.borderColor = UIColor.redColor().CGColor

    }

    func UIViewAnimation4() {

        // 参数1: 动画时间
        // 参数2: 延迟时间
        // 参数3: 弹簧的压力系数
        // 参数4: 弹簧初始加速度
        // 参数5: 选项
        // 参数6: 设置动画结束时视图的状态
        // 参数7: 动画结束之后要执行的闭包
        UIView.animateWithDuration(2, delay: 1, 
        usingSpringWithDamping: 0.2, initialSpringVelocity: 0.1, 
        options: [ .Repeat, .Autoreverse], animations: {
            // 注意: 对于有圆角的视图,改变大小而又不影响形状
            // 只能通过形变去缩放, 不能直接改变frame中的size。
            self.subView.transform = CGAffineTransformMakeScale(0.5, 0.5)
            self.subView.transform = CGAffineTransformMakeTranslation(0,
           -200)}, completion: nil)
    }

    func UIViewAnimation3() {

        // 参数1: 动画时间
        // 参数2: 延迟时间
        // 参数3: 选项, Repeat -> 动画重复执行
        // Autoreverse -> 动画自动回到开始的状态
        // 参数4: 设置动画结束时视图状态的闭包
        // 参数5: 整个动画过程完成后需要执行的闭包
        UIView.animateWithDuration(2, delay: 1, options: [ .Repeat, 
        .Autoreverse], animations: {
            self.subView.transform = 
            CGAffineTransformMakeTranslation(0, -200)
            }, completion: nil)
    }

    // MARK: - 动画方法
    // UIView的动画是用来改变视图的方法视图的frame相关属性、背景颜色、透明度

    func UIViewAnimation2() {

        // 参数3: 整个动画完成之后会自动调用闭包
        UIView.animateWithDuration(2, animations: {

            self.subView.transform = CGAffineTransformMakeTranslation(0, 
            -200)

            }) { (_) in

                // 动画结束后需要执行的代码
                UIView.animateWithDuration(2, animations: {
                    self.subView.transform = 
                    CGAffineTransformMakeTranslation(0, 0)
                })
        }
    }
    func UIViewAnimation1() {

        // 功能: 动画从执行这个方法前视图的状态,切换到闭包里面设置的最终状态
        // 参数1: 动画时间(单位: 秒)
        // 参数2: 闭包,设置动画结束时视图的状态
        UIView.animateWithDuration(2) {

            // 在这里设置视图动画结束时的状态
            self.subView.frame.origin.y = 20

            // 动画的改变视图的大小
            //self.subView.frame.size = CGSizeMake(15, 50)
            self.subView.transform = CGAffineTransformMakeScale(0.5, 0.5)

            // 动画的改变视图的背景颜色
            self.subView.backgroundColor = UIColor.redColor()

            // 动画的改变视图的透明度(0~1)
            self.subView.alpha = 0.2

            self.subView.transform = 
            CGAffineTransformMakeRotation(CGFloat(M_PI_4))
        }

    }

UILabel基础

  • 基础属性
    override func viewDidLoad() {
        super.viewDidLoad()

        self.creatLabel()

    }

    // MARK: - 创建Label
    func creatLabel() {

        // UILabel: UIView -> UIView的属性和方法UILabel都有
        // ==============从UIView继承下来的属性==============
        // 1. 创建UILabel对象
        let label = UILabel.init(frame: CGRectMake(10, 10, 350, 650))

        // 2. 添加到界面上
        self.view.addSubview(label)

        // 3. 设置背景颜色
        label.backgroundColor = UIColor.yellowColor()

        // ==============从UILabel的专有属性==============
        // 1. text属性
        // 设置label上显示的文字
        label.text = "田不易"

        // 拿到label上当前显示的文字
        print("\(label.text!)")

        // 2.设置字体
        // 使用系统字体设置大小
        label.font = UIFont.systemFontOfSize(20)
        // 使用系统字体设置字体大小和粗细
        // 参数1: 字体大小
        // 参数2: 字体粗细(0~1)
        label.font = UIFont.systemFontOfSize(20, weight: 0.99)

        // 使用系统粗体设置字体大小
        label.font = UIFont.boldSystemFontOfSize(20)
                // 使用系统斜体设置字体大小
        label.font = UIFont.italicSystemFontOfSize(20)

        // 获取系统所有字体的字体名
        print(UIFont.familyNames(),UIFont.familyNames().count)

        // 参数1: 字体名
        // 参数2: 字体大小
        label.font = UIFont.init(name: "HYZhuanShuF", size: 20)

        // 总结使用自己的字体的步骤:
        // 1.将ttf文件拖到工程中
        // 2.在info.plist文件中添加键值对"Fonts provided by application"
        // 将字体添加到系统字体库中
        // 3.通过提供字体名的构造方法去创建字体(先要找到自己添加字体的字体名)
        // 3.设置字体颜色
        label.textColor = UIColor.purpleColor()
        // 4.设置阴影颜色
        label.shadowColor = UIColor.grayColor()
        // 5.设置阴影偏移效果
        label.shadowOffset = CGSizeMake(0, 0)
        // 6.设置文字的居中模式(默认是左对齐)
        label.textAlignment = .Center
        label.text = "天地不仁,以万物为诌狗! 这世间本是没有什么神仙的,但自太古以来,
        人类眼见周遭世界,诸般奇异之事,电闪雷鸣,狂风暴雨,又有天灾人祸,伤亡无数,哀鸿遍
        野,决非人力所能为,所能抵挡。遂以为九天之上,有诸般神灵,九幽之下,亦是阴魂归
        处,阎罗殿堂。于是神仙之说,流传于世。无数人类子民,诚心叩拜,向着自己臆想创造
        出的各种神明顶礼膜拜,祈福诉苦,香火鼎盛。自古以来,凡人无不有一死。但世人皆恶
        死爱生,更有地府阎罗之说,平添了几分苦惧,在此之下,遂有长生不死之说相比与其他
        生灵物种,人类或在体质上处于劣势,但万物灵长,却是绝无虚言。在追求长生的原动力
        下,一代代聪明才智之士,前赴后继,投入毕生精力,苦苦钻研。至今为止,虽然真正意
        义上的长生不死仍未找到,却有一些修真炼道之士,参透些天地造化,以凡人之身,掌握
        强横力量,借助各般秘宝法器之力,竟可震撼天地,有雷霆之威。而一些得到高深的前
        辈,更传说已活上千年之久而不死。世上之人以为得道成仙,便有更多人投入修真炼道之路"
        // 7.设置行数
        label.numberOfLines = 40
        // a.自动换行
        //label.numberOfLines = 0
        // b.设置换行模式
        // ByWordWrapping -> 以单词为单位换行
        // ByCharWrapping -> 以字符为单位换行

        label.lineBreakMode = .ByWordWrapping
    }
  • 根据文字设置Label的大小
        // 需要显示在label上的文字
        let str = "天地不仁,以万物为诌狗! 这世间本是没有什么神仙的,但自太古以来,人类
        眼见周遭世界,诸般奇异之事,电闪雷鸣,狂风暴雨,又有天灾人祸,伤亡无数,哀鸿遍
        野,决非人力所能为,所能抵挡。遂以为九天之上,有诸般神灵,九幽之下,亦是阴魂归
        处,阎罗殿堂。于是神仙之说,流传于世。无数人类子民,诚心叩拜,向着自己臆想创造
        出的各种神明顶礼膜拜,祈福诉苦,香火鼎盛。自古以来,凡人无不有一死。但世人皆恶
        死爱生,更有地府阎罗之说,平添了几分苦惧,在此之下,遂有长生不死之说相比与其他
        生灵物种,人类或在体质上处于劣势,但万物灵长,却是绝无虚言。在追求长生的原动力
        下,一代代聪明才智之士,前赴后继,投入毕生精力,苦苦钻研。至今为止,虽然真正意
        义上的长生不死仍未找到,却有一些修真炼道之士,参透些天地造化,以凡人之身,掌握
        强横力量,借助各般秘宝法器之力,竟可震撼天地,有雷霆之威。而一些得到高深的前
        辈,更传说已活上千年之久而不死。世上之人以为得道成仙,便有更多人投入修真炼道之路"

        // 计算显示指定文字所需要的最小空间
        // 1. 将Swift的字符串转换成OC的字符串
        let ocStr = str as NSString

        // 2. 计算字符串的大小
        // 参数1: 限制显示当前字符串的最大宽度和最大高度
        // 参数2: 设置渲染方式(.UsesLineFragmentOrigin)
        // 参数3: 确定文字的字体(大小)
        // 参数4: NSFontAttributeName -> 字体对应的key值
        // NSForegroundColorAttributeName -> 文字颜色对应的key值
        let strSize = ocStr.boundingRectWithSize(CGSizeMake(350, 64000), 
        options: .UsesLineFragmentOrigin, 
        attributes: [NSFontAttributeName: 
        UIFont.systemFontOfSize(17)], context: nil)
        print(strSize)

        // 3.创建Label显示文字
        let label = UILabel.init(frame: CGRectMake(10, 10, 
        strSize.width, strSize.height))
        label.backgroundColor = UIColor.yellowColor()
        self.view.addSubview(label)
        label.text = str

        // 自动换行
        label.numberOfLines = 0
    }

UIImageView基础

  • 首先要把图片拖入到工程中
        // UIImageView: UIView
        // =============UIView的属性和方法=============
        // 1. 创建UIImageView对象
        let imageView = UIImageView.init(frame: CGRectMake(100, 100, 200, 
        300))

        // 2. 添加到界面上
        self.view.addSubview(imageView)

        // 3. 设置背景颜色
        imageView.backgroundColor = UIColor.greenColor()

        // =============UIImageView专有属性=============
        // 1. 专有属性
        // a.通过图片名去创建一个图片对象
        // (注意: 如果图片的格式是png,那么图片名等后缀可以省略
        // 但是其他格式的图片的图片名的后缀不能省略)
        imageView.image = UIImage.init(named: "back2.jpg")

        // b.通过图片路径去创建一个图片对象
        // 将文件(除了swift文件)放到工程中,实质是放到了当前应用程序的包文件中
        // (想要拿到工程中的图片路径先要获取包文件的路径)
        // 拿到包中指定文件的路径
        let imagePath = NSBundle.mainBundle().pathForResource("back2", 
        ofType: "jpg")

        imageView.image = UIImage.init(contentsOfFile: imagePath!)

        // c.比较通过图片名和通过图片地址创建图片对象的两种方法:
        // (1) 通过图片名创建的图片对象在程序结束后才会被销毁,只会创建一次
        // 通过图片地址创建的图片对象,当前图片对象不再使用的时候就销毁
        // (2) 使用图片名创建图片对象的情况: 创建小图标的时候;在工程中会重复使用的图片
        // (3) 使用图片地址创建图片对象的情况: 不会频繁的在多个界面出现的大图

        // 2. 内容模式
        imageView.contentMode = .ScaleToFill

UIImageView帧动画

    // MARK: - 属性
    var imageView = UIImageView()

    // MARK: - 生命周期
    override func viewDidLoad() {
        super.viewDidLoad()

        self.creatImageView()

        // 创建一个定时器,并且自动开启
        // 参数1: 定时时间
        // 参数2: 调用方法的对象
        // 参数3: 存储定时时间到了以后,需要调用的方法
        // (可以带参也可以不带参,但是如果带参只能带一个参,并且参数类型是NSTimer类型)
        // 参数4: 给当前的NSTimer的userInfo属性赋的值
        // 参数5: 是否重复
        // 功能: 每隔0.1秒,self去调用一次timerAction方法
        NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: 
        "timerAction:", userInfo: "Zhang Xiaofan", repeats: true)

    }

    func timerAction(timer: NSTimer) {
        print(timer.userInfo)
        self.imageView.frame.origin.x += 10

        // 判断是否到了屏幕边缘,如果到了就停止移动
        if self.imageView.frame.origin.x - imageView.bounds.width > 
        self.view.bounds.width - self.imageView.bounds.width {

            // 暂停计时器
            //timer.fireDate = NSDate.distantFuture()

            // 解除暂停
            //timer.fireDate = NSDate.distantPast()

            imageView.frame.origin.x = -imageView.bounds.width


        }
    }

    func creatImageView() {

        // 1. 创建一个UIImageView对象
        // 通过图片去创建一个imageView;UIImageView的大小是图片的大小,坐标是(0,0)
        imageView = UIImageView.init(image: UIImage.init(named: 
        "DOVE 1.png"))
        // 2. 显示在界面上
        self.view.addSubview(imageView)

        // 3. 使用UIImageView播放帧动画
        // a. 设置帧动画数组
        // 创建一个空数组
        var imagesArray = [UIImage]()

        // 通过for循环创建18张图片
        for item in 1...18 {
            // 拼接图片名
            let imageName = "DOVE \(item).png"
            // 创建对应的图片
            let image = UIImage.init(named: imageName)
            // 将图片存入数组
            imagesArray.append(image!)
        }

        imageView.animationImages = imagesArray

        // b. 设置动画时间, 单位: 秒
        imageView.animationDuration = 1.0001

        // c. 设置动画的重复次数(默认是0 -> 无限循环)
        //imageView.animationRepeatCount = 20

        // d. 开始动画
        imageView.startAnimating()
    }

UIButton基础

  • 系统自带的Button
    override func viewDidLoad() {
        super.viewDidLoad()

        titleButton()
        imageButton()
        imageTitleButton()

    }

    // MARK: - 图片文字按钮
    func imageTitleButton() {

        // 同时设置title和image属性,显示是图片在左,文字在右
        // 同时设置title和groundImage属性,显示是图片在下层,文字在上层
        // 创建对象
        let combineButton = UIButton.init(frame: CGRectMake(100, 300, 200, 
        100))
        self.view.addSubview(combineButton)

        // 设置标题
        combineButton.setTitle("标题", forState: .Normal)
        combineButton.setTitleColor(UIColor.whiteColor(), forState: .Normal)

        // 设置图片
        //combineButton.setImage(UIImage.init(named: "luffy1"), forState: 
        //.Normal)

        combineButton.setBackgroundImage(UIImage.init(named: 
        "luffy2"), forState: .Normal)
        // 添加事件
        combineButton.addTarget(self, action: "buttonAction:", 
        forControlEvents: .TouchDown)

    }

    // MARK: - 图片按钮

    func imageButton() {

        // 1. 创建一个按钮对象
        let imageButton = UIButton.init(frame: CGRectMake(100, 200, 80, 
        80))

        // 2. 添加到界面上
        self.view.addSubview(imageButton)

        // 3. 设置图片
        // 参数1: 图片
        // 参数2: 状态(正常、高亮、选中、不可用)
        imageButton.setImage(UIImage.init(named: "luffy1.png"), forState: 
        .Normal)

        // 4. 添加按钮点击事件
        imageButton.addTarget(self, action: "buttonAction:", 
        forControlEvents: .TouchDown)

    }

    // MARK: - 文字按钮
    func titleButton() {

        // UIButton: UIControl: UIView
        // UIButton上有一个titleLabel专门负责按钮上文字的显示
        // 有一个imageView专门负责按钮上图片的显示
        // ==============UIView的属性和方法==============
        // 1. 创建UIButton对象
        let titleButton = UIButton.init(frame: CGRectMake(100, 100, 
        100, 50))

        // 设置背景颜色
        titleButton.backgroundColor = UIColor.purpleColor()

        // 添加到界面上
        self.view.addSubview(titleButton)

        // ===============UIButton专用的属性和方法===============
        //titleButton.titleLabel
        //titleButton.imageView

        // 设置按钮上显示的文字
        // 参数1: 想要在按钮上显示的文字(可以给不同到状态设置不一样的文字)
        // 参数2: 状态
        // Normal -> 正常状态(按钮正常显示,没有被点击或者按下的时候)
        // Highlighted -> 高亮(按钮被摁下,未被弹起时的状态)
        // Selected -> 选中状体
        // Disabled -> 不可用状态(按钮不能被点击)
        titleButton.setTitle("正常", forState: .Normal)
        titleButton.setTitle("高亮", forState: .Highlighted)

        titleButton.setTitle("选中", forState: .Selected)
        titleButton.setTitle("不可用", forState: .Disabled)

        // 设置当前按钮是否选中(默认为false)
        titleButton.selected = false

        // 3. 设置当前按钮是否可用(默认是true -> 可用)
        titleButton.enabled = true

        // 4. 设置文字颜色(可用给不同的状态设置不一样的颜色)
        titleButton.setTitleColor(UIColor.yellowColor(), forState: .Normal)
        titleButton.setTitleColor(UIColor.grayColor(), forState: .Disabled)

        // 注意: 按钮上的文字和文字颜色必须通过对应的set方法去根据状态去设置。
        // 其他和文字相关的属性可以通过拿到titleLabel去设置
        // 5. 设置按钮上的文字字体
        titleButton.titleLabel?.font = UIFont.systemFontOfSize(30)

        // 6. 设置按钮上的文字的对齐方式
        titleButton.titleLabel?.textAlignment = .Center

        // 7. 给按钮添加事件
        // 参数1: 调用方法的对象
        // 参数2: 指定事件发生后参数1需要去调用的方法
        // (这个方法可以不带参也,如果带参只能带一个,并且参数的类型是UIButton类型)
        // 实参就是当前添加事件的按钮本身
        // 参数3: 事件
        // TouchDown -> 摁下事件
        // TouchUpInside -> 摁下弹起事件
        // 功能: 当按钮被摁下弹起的时候,self会调用buttonAction方法
        titleButton.addTarget(self, action: "buttonAction:", 
        forControlEvents: .TouchUpInside)

    }

    // MARK: - 按钮点击
    func buttonAction(btn: UIButton) {

        // 设置按钮的背景颜色是随机色
        btn.backgroundColor = UIColor.init(red: CGFloat(
        arc4random() % 256) / 255, green: 
        CGFloat(arc4random() % 256) / 255, 
        blue: CGFloat(arc4random() % 256) / 255, alpha: 1)
    }

  • 自定义Button
    override func viewDidLoad() {
        super.viewDidLoad()

        // 1. 创建按钮对象
        let btn = YTButton(frame: CGRectMake(100, 100, 100, 120))

        // 2. 设置文字
        btn.setTitle("SB路飞", forState: .Normal)
        btn.setTitleColor(UIColor.purpleColor(), forState: .Normal)
        btn.titleLabel?.textAlignment = .Center

        // 3. 设置图片
        btn.setImage(UIImage.init(named: "luffy4"), forState: .Normal)

        // 4. 添加到界面上
        self.view.addSubview(btn)

        // 5. 添加按钮点击事件
        btn.addTarget(self, action: "btnAction", forControlEvents: 
        .TouchDown)
    }

    func btnAction() {
        print("我是sb,爱点不点")
    }

UITextField基础

    var textField = UITextField()
    var textField2 = UITextField()

    override func viewDidLoad() {
        super.viewDidLoad()

        // UITextField: UIControl: UIView
        // ================UIView的属性和方法===============
        // 1. 创建UITextField对象
        textField = UITextField.init(frame: CGRectMake(100, 100, 200, 50))

        // 2. 添加到界面上
        self.view.addSubview(textField)

        // 3. 设置背景颜色
        textField.backgroundColor = UIColor.purpleColor()

        // 4.
        textField2 = UITextField.init(frame: CGRectMake(100, 200, 200, 50))
        self.view.addSubview(textField2)
        textField2.backgroundColor = UIColor.purpleColor()

        // ==============textField的专有属性和方法=============
        // 1. 文字相关
        // (1) text属性
        // 设置文本输入框的内容
        //textField.text = "输入内容"

        // 拿到文本输入框的内容
        //print(textField.text!)

        // (2) 文字颜色
        textField.textColor = UIColor.yellowColor()

        // (3) 设置文字字体
        textField.font = UIFont.systemFontOfSize(20)

        // (4) 设置占位文字(在输入框的内容为空的时候就会显示出来)
        textField.placeholder = "请输入账号"

        // (5) 设置文本的对齐方式(默认是左对齐)
        textField.textAlignment = .Left

        // (6) 密文显示(默认是false)
        textField2.secureTextEntry = true

        // 2. 显示相关
        // (1) 设置文本框的样式
        textField.borderStyle = .Bezel

        // (2) 设置清除按钮模式
        // (前提是输入框中有文字)
        // Always -> 一直显示
        // Never -> 从不显示
        // WhileEditing -> 当文本输入框处于编辑状态的时候才显示
        // UnlessEditing -> 当文本输入框处于非编辑状态的时候才显示
        // 注: 当文本输入框中有光标的时候就是处于编辑状态
        textField.clearButtonMode = .Always

        // (3) 左视图
        let leftImage = UIImageView.init(frame: CGRectMake(0, 0, 40, 40))
        leftImage.image = UIImage.init(named: "luffy_1")
        leftImage.backgroundColor = UIColor.purpleColor()
        // 设置左视图
        textField.leftView = leftImage

        // 设置左视图的显示模式(确定什么时候显示,默认是从不显示)
        textField.leftViewMode = .Always

//        let label = UILabel.init(frame: CGRectMake(0, 0, 40, 25))
//        label.text = "账号:"
//        textField.leftView = label
//        textField.leftViewMode = .Always

        // (4) 右视图
        // 当右视图显示的时候,清除按钮不能显示
        /**
        let rightLabel = UILabel.init(frame: CGRectMake(0, 0, 40, 40))
        rightLabel.text = ""
        textField.rightView = rightLabel
        textField.rightViewMode = .Always
        */

        let btn = UIButton.init(frame: CGRectMake(0, 0, 40, 40))
        btn.setTitle("", forState: .Normal)
        textField.rightView = btn
        textField.rightViewMode = .Always
        btn.addTarget(self, action: "clean", forControlEvents: .TouchDown)

        // 3键盘相关
        // (1) 设置键盘上返回按钮样式
        textField.returnKeyType = .Default

        // (2) 键盘样式
        textField.keyboardType = .URL

        // (3) 设置自定义键盘
        // 自定义的键盘只有高度有效宽度是屏幕的宽度
        let myInputView = UIView.init(frame: CGRectMake(0, 0, 0, 256))
        myInputView.backgroundColor = UIColor.grayColor()
        //textField.inputView = myInputView

        // (4) 设置子键盘
        let accessoryView = UIView.init(frame: CGRectMake(0, 0, 0, 45))
        accessoryView.backgroundColor = UIColor.greenColor()
        textField.inputAccessoryView = accessoryView

        // 4. 代理
        // delete -> 委托
        // self -> 代理
        textField.delegate = self

        textField2.delegate = self

    }

    func clean() {
        textField.text = ""
        textField.placeholder = "请输入账号!"

    }

  • 扩展ViewController类
// MARK: - UITextFieldDelegate
extension ViewController: UITextFieldDelegate {


    // 1. 在textField将要编辑的时候会自动调用
    // 参数: 当前这个协议对应的委托
    // 返回值: 设置当前的textField是否可以进行编辑(默认是true)
    func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
        print("将要开始编辑")
        return true // false -> 让textField不能进行编辑
    }

    // 2. 当文本输入框已经开始编辑的时候会自动调用这个方法
    func textFieldDidBeginEditing(textField: UITextField) {
        print("已经处于编辑")
    }

    // 3. 当文本输入框将要结束编辑的时候会自动调用这个方法
    // 返回: 设置当前的textField是否可以结束编辑(默认是true)
    func textFieldShouldEndEditing(textField: UITextField) -> Bool {
        // 要求文本输入框中的文字长度要大于等于8的时候才能结束编辑 
        if textField.text?.characters.count >= 8 {
            return true
        }

        print("将要结束编辑")
        return false
    }

    // 4. 当文本输入框已经结束编辑的时候会自动调用这个方法
    func textFieldDidEndEditing(textField: UITextField) {

        print("已经结束编辑")

    }

    // 5. 当点击textField弹出来的键盘上的按键时候会自动调用这个方法
    // 参数1: 委托
    // 参数2: 当前输入的字符所在的位置
    // 参数3: 当前输入的字符串(在键盘上按的键的值)
    // 返回值: 是否可以改变textField的text属性, false -> 按键盘上的按键无效
    func textField(textField: UITextField, 
    shouldChangeCharactersInRange range: NSRange, 
    replacementString string: String) -> Bool {

        print(range)
        print(string)
        if string == "0" {
            print("登录美国情报局")
        }
        return true
    }

    // 6. 当摁下键盘上的返回按钮的时候,会自动调用
    func textFieldShouldReturn(textField: UITextField) -> Bool {

        print("返回按钮被点击")

        // 收起键盘 -> * 3
        // 1. 放弃第一响应者
        textField.resignFirstResponder()
        // 2. 直接让指定的textField结束编辑
        textField.endEditing(true)
        // 3. 让self.view上的所有子视图都结束编辑
        self.view.endEditing(true)

        return true
    }

}

自定义键盘

  • 自定义键盘,自定义协议及继承该协议的类用作委托代理
// MARK : - WYlKeyBoard协议
protocol WYlKeyBoardDelegate {
    
    // 让代理去显示指定按钮上的内容
    func showContent(button: UIButton)
    
}


// 1. 在创建当前类的对象的时候同时创建在这个视图上所有的子视图
// 并且添加(不需要设置子视图的frame)
// 2. 计算子视图的frame

// MARK: - 构造方法和属性
class WYlKeyBoard: UIView {

    // 代理
    var delegate: WYlKeyBoardDelegate? = nil

    // 重写父类的构造方法
    override init(frame: CGRect) {
        super.init(frame: frame)

        // 在这个方法中创建所有的子视图
        self.creatSubViews()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}


// MARK: - 创建子视图
extension WYlKeyBoard {

    // 计算子视图的frame
    // 这个方法第一次调用是在当前视图将要显示在界面上的时候才会调用
    // (在这个方法中拿到的当前视图的frame是视图最终的frame值)
    // 在当前视图显示出来之后,如果视图的frame发生改变那么就会自动调用这个方法
    override func layoutSubviews() {
        super.layoutSubviews()

        // 按键的间距
        let margin: CGFloat = 10
        // 按键的宽度
        let keyW = self.frame.size.width
        // 按钮的高度
        let keyH = self.frame.size.height
        // 按钮的列数
        let col: CGFloat = 3
        // 按钮的行数
        let row: CGFloat = 4
        // 按钮的宽度
        let btnW = (keyW - (col + 1) * margin) / col
        // 按钮的高度
        let btnH = (keyH - (row + 1) * margin) / row

        var i = 0

        // 拿到当前视图上的子视图
        for item in self.subviews {

            // a. 计算按钮的frame
            // 找到按键对应的按钮
            if item.tag == 100 {

                // 计算按钮的XY坐标
                let btnX = margin + (btnW + margin) * CGFloat(i % Int(col))
                let btnY = margin + (btnH + margin) * CGFloat(i / Int(col))

                item.frame = CGRectMake(btnX, btnY, btnW, btnH)

                // 找到一个按钮 i += 1
                i += 1

            }

            // b. 计算imageView的frame
            if item.tag == 200 {
                item.frame = CGRectMake(20, -40, 50, 50)
            }

        }

    }

    // 创建子视图
    func creatSubViews() {

        // 键盘上需要显示的内容
        let titlesArray = ["1", "2", "3", "4", "5", "6", "7", "8", "9",  
        "C", "0", "返回"]

        // 遍历数组创建对应的按钮
        // 1: 下标
        // item: 数组元素
        for (_, item) in titlesArray.enumerate() {

            // 创建对应的按钮
            let btn = UIButton.init()
            btn.setTitle(item, forState: .Normal)
            btn.backgroundColor = UIColor.greenColor()
            btn.tag = 100
            btn.layer.cornerRadius = 5
            btn.addTarget(self, action: "btnAction:", forControlEvents: 
            .TouchDown)
            self.addSubview(btn)

        }

        // 3. 创建一个imageView
        let imageView = UIImageView.init()
        imageView.image = UIImage.init(named: "luffy_1")
        imageView.tag = 200
        self.addSubview(imageView)

    }

    // 按钮点击事件
    func btnAction(btn: UIButton) {

        // 想要将按钮上的内容显示到ViewController中的textField上
        // 但是WYlkeyBoard是做不到的,但是ViewController可以。
        // 确定三要素:
        // 委托: WYlkeyBoard
        // 协议: 将指定按键上的内容显示在textField上
        // 代理: ViewController


        // currentTitle属性 -> 按钮上的文字
        print(btn.currentTitle!)

        // 让代理去显示代理上的内容
        self.delegate?.showContent(btn)

    }

}
  • 调用自定义键盘使之显示在界面上
class ViewController: UIViewController, WYlKeyBoardDelegate {

    // MARK: - 属性
    var textField = UITextField()

    // MARK: - 生命周期
    override func viewDidLoad() {
        super.viewDidLoad()

        // 1. 创建一个局部变量
        textField = UITextField.init(frame: CGRectMake(100, 100, 200, 50))
        self.view.addSubview(textField)
        textField.backgroundColor = UIColor.purpleColor()
        textField.layer.cornerRadius = 25

        // 使用自定义键盘
        let keyBoard = WYlKeyBoard(frame: CGRectMake(0, 0, 100, 256))

        // 设置KeyBoard的代理
        keyBoard.delegate = self

        keyBoard.backgroundColor = UIColor.grayColor()
        textField.inputView = keyBoard

    }

    // MARK: - YTKeyBoard delegate
    func showContent(button: UIButton) {

        if button.currentTitle == "返回" {
            // 收起键盘
            self.textField.resignFirstResponder()
            return
        }
        else if button.currentTitle == "C" {
            // 判断textField中的文字是否为空,不为空菜做刷新操作
            if textField.text?.characters.count > 0 {

                // 拿到最后一个字符的Index
                let last = self.textField.text?.endIndex.predecessor()

                // 移除最后一个字符
                var text = self.textField.text!
                text.removeAtIndex(last!)
                self.textField.text = text
            }
            return
        }

        textField.text = textField.text! + button.currentTitle!
    }
}

其他基础控件集合

开关按钮、滑条、步进器、进度条、活动指示器、多段选择器

// MARK: - 生命周期和属性
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.backgroundColor = UIColor.grayColor()
        self.creatSwitch()
        creatSlider()
        creatStepper()
        creatProgress()
        creatActivity()
        creatSegement()
    }

}


// MARK: - 创建控件
extension ViewController {

    // 1. 开关
    func creatSwitch() {
        // (1) 创建开关对象
        // UISwith: UIControl: UIView
        let sw = UISwitch.init(frame: CGRectMake(100, 100, 100, 50))

        // (2) 添加到界面上
        self.view.addSubview(sw)

        // (3) 核心属性: 开关状态(默认是:关(false))
        // 设置开关的状态
        sw.on = true
        sw.setOn(false, animated: true)

        // 拿到当前状态
        print(sw.on)

        // (4) 核心方法:
        // 参数1: 调用方法的对象
        // 参数2: 指定的事件发生后参数1要去调用的方法对应的selector
        // 参数3: 事件
        // 功能: 当开关的值发生改变的时候,self会去调用switchAction方法
        sw.addTarget(self, action: "switchAction:", forControlEvents: 
        .ValueChanged)

        // (5) 设置开关开启后状态的颜色(默认为绿色)
        sw.onTintColor = UIColor.blueColor()
        sw.tintColor = UIColor.purpleColor()
        sw.thumbTintColor = UIColor.yellowColor()

        // (6) 图片
        //sw.onImage = UIImage.init(named: "luffy_1.png")
        //sw.offImage = UIImage.init(named: "luffy_1.png")

    }

    // 2. 滑条
    func creatSlider() {

        // (1) 创建滑条对象
        // UISlider: UIControl: UIView
        let slider = UISlider.init(frame: CGRectMake(60, 150, 300, 100))

        // (2) 添加到界面上
        self.view.addSubview(slider)

        // (3) 核心属性: 值
        // value: 滑块位置对应的值(默认: 0~1)
        slider.value = 0.5

        // 设置滑条最小值和最大值
        slider.minimumValue = 0
        slider.maximumValue = 100

        // (4) 核心方法
        // sliderAction
        slider.addTarget(self, action: "sliderAction:", forControlEvents: 
        .ValueChanged)

        // (5) 图片相关
        /**
        slider.setThumbImage(UIImage.init(named: "luffy1.png"), forState: 
        .Normal)
        slider.maximumValueImage = UIImage.init(named: "luffy1.png")
        slider.minimumValueImage = UIImage.init(named: "luffy1.png")

        slider.setMaximumTrackImage(UIImage.init(named: "luffy1.png"), 
        forState: .Normal)
        */

        // (6) 颜色相关
        //slider.thumbTintColor = UIColor.purpleColor()
        slider.minimumTrackTintColor = UIColor.redColor()
        slider.maximumTrackTintColor = UIColor.blueColor()
        // (7) 是否连续改变
        slider.continuous = false
        slider.setValue(50, animated: true)

    }

    // 3. 步进器
    func creatStepper() {

        // (1) 创建步进器对象
        let stepper = UIStepper.init(frame: CGRectMake(100, 250, 100, 50))

        // (2) 添加到界面上
        self.view.addSubview(stepper)

        // (3) 核心属性
        // 当前值
        stepper.value = 0
        print(stepper.value)

        // 最小值和最大值
        stepper.minimumValue = 0
        stepper.maximumValue = 5

        // 步进(每摁一下加或者减,增加/减少的值)
        stepper.stepValue = 1   // 步进的值必须大于0

        // (4) 核心方法
        stepper.addTarget(self, action: "stepperAction:", forControlEvents: 
        .ValueChanged)

        // (5) 设置值是否连续改变(摁住不放的时候)
        stepper.continuous = false  // 默认为true

        // (6) 设置是否重复 false -> 摁住不放的时候不计数
        // true -> 摁住不放依旧计数(默认为true)
        stepper.autorepeat = false

        // (7) 颜色相关
        stepper.tintColor = UIColor.redColor()
        stepper.backgroundColor = UIColor.purpleColor()
        stepper.setBackgroundImage(UIImage.init(named: "luffy1.png"), 
        forState: .Normal)
    }

    // 4. 进度条
    func creatProgress() {

        // (1) 创建进度条对象
        let progress = UIProgressView.init(frame: CGRectMake(50, 350, 
        300, 20))
        progress.tag = 100

        // (2) 添加到界面上
        self.view.addSubview(progress)

        // 核心属性
        // 进度: 0~1
        // 设置当前进度
        progress.progress = 0.5
        progress.setProgress(0.6, animated: true)

        // 颜色相关
        progress.tintColor = UIColor.yellowColor()
        progress.trackTintColor = UIColor.redColor()

        // 图片相关
        progress.progressImage = UIImage.init(named: "luffy1.png")

    }

    // 5. 活动指示器
    func creatActivity() {

        // (1) 创建活动指示器对象
        let activity = UIActivityIndicatorView.init(frame: CGRectMake(60, 
        400, 50, 50))

        // (2) 添加到界面上
        self.view.addSubview(activity)

//        activity.backgroundColor = UIColor.greenColor()
//        activity.color = UIColor.redColor()

        // (3) 想要让活动指示器显示,必须让它开始动画
        activity.startAnimating()

        // (4) 停止动画 -> 活动指示器消失
        //activity.stopAnimating()

        // (5) 设置活动指示器的样式
        activity.activityIndicatorViewStyle = .WhiteLarge

    }

    // 6. 多段选择器
    func creatSegement() {

        // (1) 创建多段选择器对象
        // UISegmentedControl: UIControl
        // 参数1: 分段选择器上的内容对应的数组
        let segement = UISegmentedControl.init(items: ["武庚纪","秦时明月", 
        "天行九歌",])
        segement.frame = CGRectMake(50, 450, 200, 40)
        // (2) 添加到界面上
        self.view.addSubview(segement)

        // (3) 核心属性
        // 每个分段上的内容
        // a. 每个分段上的内容 -> 通过创建分段选择器的时候去设置
        // b. 当前选中的分段多下标(从0开始)
        segement.selectedSegmentIndex = 0

        // (4) 核心方法
        segement.addTarget(self, action: "segementAction:", 
        forControlEvents: .ValueChanged)

        // (5) 拿到分段选择的分段数
        print(segement.numberOfSegments)

        // (6) 显示相关
        segement.tintColor = UIColor.whiteColor()

    }

}

// MARK: - 事件响应
extension ViewController {

    // 1. 开关事件
    func switchAction(sw: UISwitch) {

        if sw.on {

            print("开关已开启")
        }
        else {

            print("开关已关闭")
        }
    }

    // 2. 滑条事件
    func sliderAction(slider: UISlider) {

        print(slider.value)

        // 拿到进度条
        let progress = self.view.viewWithTag(100) as! UIProgressView
        let t = slider.value / (slider.maximumValue - slider.minimumValue)
        progress.setProgress(t, animated: true)

    }

    func stepperAction(stepper: UIStepper) {
        print(stepper.value)
    }

    // 3. 分段选择器事件
    func segementAction(segement: UISegmentedControl) {

        // 拿到当前被选中打分段的title
        print(segement.selectedSegmentIndex)
        print(segement.titleForSegmentAtIndex(
        segement.selectedSegmentIndex)!)
    }

}

自定义分段选择器

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // 系统的分段选择器
        let segement = UISegmentedControl.init(items: ["青云门", "天音寺", 
        "焚香谷"])
        segement.frame = CGRectMake(100, 100, 200, 40)
        self.view.addSubview(segement)
        segement.addTarget(self, action: "action", forControlEvents: 
        .ValueChanged)

        // 自定义分段选择器
        let selfSegement = WYlSegementControl.init(items: ["鬼王宗", 
        "万毒门", "合欢宗", "炼血堂"])
        selfSegement.frame = CGRectMake(80, 180, 250, 40)
        selfSegement.backgroundColor = UIColor.grayColor()
        selfSegement.titleColor = UIColor.whiteColor()
        self.view.addSubview(selfSegement)
        selfSegement.layer.cornerRadius = 5
        selfSegement.titleSelectedColor = UIColor.orangeColor()
        selfSegement.selectedSegementIndex = 1
        selfSegement.addTarget(self, action: "selfAction:")
    }
    func action() {
        print("Zhang Xiaofan")
    }

    func selfAction(segement: WYlSegementControl) {
        print("Lu Xueqi")
        print(segement.selectedSegementIndex)
    }
}
let BtnTag = 100

class WYlSegementControl: UIView {

    // MARK: - 属性:

    // 当前被选中的按钮的下标
    var selectedSegementIndex = 0 {

        // 即将要将新值赋给selectedSegementIndex
        // 这个时候selectedSegementIndex还是原来的值
        willSet {

            // 1. 先将原来选中的按钮变成非选中状态
            let btn1 = self.viewWithTag(BtnTag + selectedSegementIndex) 
            as! UIButton
            btn1.backgroundColor = UIColor.grayColor()
            btn1.selected = false

            // 2. 将指定的按钮变成选中状态
            // newValue -> 将要赋给当前属性的那个新的值
            let btn2 = self.viewWithTag(BtnTag + newValue) as! UIButton
            btn2.backgroundColor = UIColor.greenColor()
            btn2.selected = true

        }

        // 已经给selectedSegementIndex赋值
        didSet {
            UIView.animateWithDuration(0.3) {
                self.slider.frame.origin.x = 
                CGFloat(self.selectedSegementIndex) * 
                self.slider.frame.size.width
            }
        }

    }

    // 文字选中后的颜色
    var titleSelectedColor = UIColor.blueColor()
    {
        didSet {
            for item in self.subviews {

                if item.tag >= BtnTag {
                    let btn = item as! UIButton
                    // 改变按钮的文字颜色
                    btn.setTitleColor(self.titleSelectedColor, forState: 
                    .Selected)
                }
            }
        }
    }

    // 文字颜色:
    var titleColor = UIColor.blackColor() {

        // 每次从外部给titleColor赋值的时候
        // 都需要用最新的titleColor的值去更新按钮的文字颜色

        didSet {

            for item in self.subviews {

                if item.tag >= BtnTag {
                    let btn = item as! UIButton
                    // 改变按钮的文字颜色
                    btn.setTitleColor(self.titleColor, forState: .Normal)
                }

            }

        }

    }
    // 4. items
    private var items: [String]
    // 5. 滑块
    private var slider = UIView()
    // 6. 保存target
    private var target: AnyObject? = nil
    // 7. 保存action
    private var action: Selector? = nil

    init(items: [String]) {
        self.items = items

        // CGRectZero -> 坐标是(0,0), 大小也是(0,0)
        super.init(frame: CGRectZero)

        // 创建items中的每个数组元素对应的按钮
        creatSubView()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


}

// MARK: - 提供给外部使用的方法
extension WYlSegementControl {

    func addTarget(target: AnyObject?, action: Selector) {
        self.target = target
        self.action = action
    }

}

// MARK: - 创建子视图
extension WYlSegementControl {

    // 创建子视图
    func creatSubView() {

        for (i, item) in self.items.enumerate() {

            // 创建按钮不设置frame属性
            let btn = UIButton.init()
            // 设置文字
            btn.setTitle(item, forState: .Normal)
            // 设置tag值
            btn.tag = BtnTag + i
            // 设置文字颜色
            btn.setTitleColor(self.titleColor, forState: .Normal)
            // 设置被选中后的文字颜色
            btn.setTitleColor(titleSelectedColor, forState: .Selected)
            // 让默认第0个按钮处于被选中状态
            if i == 0 {
                btn.selected = true
            }

            btn.addTarget(self, action: "btnAction:", forControlEvents: 
            .TouchDown)

            // 添加到界面上
            self.addSubview(btn)

        }

        // 创建滑块
        self.slider.backgroundColor = self.titleSelectedColor
        self.addSubview(self.slider)

    }

}

//
extension WYlSegementControl {

    func btnAction(btn: UIButton) {

        if self.selectedSegementIndex == btn.tag - BtnTag {
            // 更新选中的下标
            self.selectedSegementIndex = btn.tag - BtnTag
            // 通知外部值改变了
            if self.target != nil {

                // 让target去调用action中的方法
                // 参数1: 需要调用的方法对应的Selecter
                // 参数2: 如果Selecter中方法带参
                // 那么这个参数的值就是Selecter中方法的实参
                self.target?.performSelector(self.action!, withObject: 
                self)

            }
        }

        self.selectedSegementIndex = btn.tag - BtnTag
    }
}

// MARK: - 计算子视图的frame
extension WYlSegementControl {

    override func layoutSubviews() {
        super.layoutSubviews()

        // 当前分段选择器的宽和高
        let segementW = self.frame.size.width
        let segementH = self.frame.size.height

        // 计算按钮的frame
        let btnW = segementW/CGFloat(self.items.count)
        let btnH = segementH
        let btnY: CGFloat = 0

        // 遍历所有的子视图
        var i: CGFloat = 0
        for item in self.subviews {
            // 找到其中的按钮
            if item.tag >= BtnTag {

                let btnX = i * btnW
                item.frame = CGRectMake(btnX, btnY, btnW, btnH)

                // 找到一个按钮i + 1
                i += 1
            }

        }

        // 计算滑块的frame
        let sliderX = CGFloat(self.selectedSegementIndex) * btnW
        let sliderH: CGFloat = 2
        let sliderY = segementH - sliderH
        let sliderW: CGFloat = btnW
        self.slider.frame = CGRectMake(sliderX, sliderY, sliderW, sliderH)

    }

}

你可能感兴趣的:(iOS_UI控件学习 -> 第一周)