学习ios之高级控件和协议(数据源协议和委托协议)

本文详细介绍iOS中的选择器、集合视图(UICollectionView)及UITableView控件的使用方法,包括时间选择器、自定义选择器的创建及数据绑定,UICollectionView的创建与配置流程,以及UITableView的基本用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、选择器
ios的选择器分的比较清楚,分为时间选择器和自定义的选择器,先说说时间选择器吧,比较简单
1、时间选择器
这里写图片描述

这里写图片描述

直接看代码,所有介绍都在代码中

    var datePicker:UIDatePicker!
    var label:UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let frame=UIScreen.main.bounds
        let xMargin:CGFloat=20
        //初始化时间选择器
        self.datePicker=UIDatePicker.init(frame: CGRect(x: xMargin,y: 20,width: frame.size.width-2*xMargin,height: 170 ))
        //时间显示模式 这里选择日期和时间 还有时间模式、日期模式、计时器模式
        self.datePicker.datePickerMode=UIDatePickerMode.dateAndTime
        //设置本地化设置 显示为简体中文
        self.datePicker.locale=Locale(identifier: "zh-Hans")
        self.view.addSubview(self.datePicker)

        //初始化label 显示选择的时间
        self.label=UILabel.init(frame: CGRect(x: xMargin,y: frame.size.height/2, width: frame.size.width-2*xMargin,height: 31))
        self.label.textAlignment=NSTextAlignment.center
        self.view.addSubview(self.label)

        //初始化一个UIButton 点击button 让label显示当前的时间
        let button=UIButton.init(type: UIButtonType.system)
        button.frame=CGRect(x: (frame.size.width-70)/2, y: self.label.frame.origin.y+30,width: 70,height: 31)
        button.setTitle("click me", for: UIControlState.normal)
        button.addTarget(self, action: #selector(ViewController.showTime(sender:)), for: UIControlEvents.touchUpInside)
        self.view.addSubview(button)



    }

    func showTime(sender:Any) {

        let date:Date=self.datePicker.date
        //获取时间以本地化的语言描述 返回一个字符串
        let des=date.description(with: NSLocale.current)

        NSLog("当前的时间%@",des)
        //时间格式化工厂 跟android中的基本一样
        let format:DateFormatter=DateFormatter()
        format.dateFormat="YYYY-MM-dd HH:mm:ss"
        self.label.text=format.string(from: date)

    }

2、普通选择器(自定义选择器数据)
自定义选择器需要有数据源,这里我们使用plist文件,先看怎么导入plist文件
这里写图片描述

下面可以点击options,选择复制到项目内

这里写图片描述

很简单,需要注意的是,注意plist文件的root是什么类型,是Array 还是 Dictionary,然后使用相应的NSArray 或者 NSDictionary 把文件内容读取到数组或者字典中去

这里写图片描述

我们看项目最终效果:

这里写图片描述

//
//  ViewController.swift
//  P5.1UIPicker
//
//  Created by LF on 2017/4/2.
//  Copyright © 2017年 yinwei. All rights reserved.
//

import UIKit

class ViewController: UIViewController,UIPickerViewDelegate,UIPickerViewDataSource {

    var pickView:UIPickerView!
    var name:UILabel!

    var pickerData:NSArray!
    var pickerProvincesData:NSMutableArray!
    var pickerCitiesData:NSMutableArray!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //初始化选择器的数据来源 这里的plist文件是自己在网上下的
        let plistPath=Bundle.main.path(forResource: "ProvincesAndCities", ofType: "plist")

        //注意这里的根Root是Array 有的可能是 dictionary
        let dic=NSArray.init(contentsOfFile: plistPath!)

        self.pickerData=dic

        //省份名数据
        //使用可变数组 后面为遍历提供方便可以直接添加新的元素数据到数组中去
         self.pickerProvincesData=NSMutableArray.init()
        //遍历pickerData把省份存储到数组中
        for province in pickerData {

        //province是字典类型 然后取出 key 为State的就是省份
        self.pickerProvincesData.add((province as! NSDictionary).value(forKey: "State") as! String)

        }


        //显示的第一条数据

        let cityesDic=(self.pickerData[0] as! NSDictionary).value(forKey: "Cities") as! NSArray

        self.pickerCitiesData=NSMutableArray.init()

        for city in cityesDic {
        //city为字典类型,取出key 为city的值 即为城市名称
        self.pickerCitiesData.add((city as! NSDictionary).value(forKey: "city") as! String)
        }


        //初始化UIPickerView
        let frame=UIScreen.main.bounds
        let xSpace:CGFloat=27
        let ySpace:CGFloat=77
        self.pickView=UIPickerView.init(frame: CGRect(x: xSpace,y: ySpace,width: frame.size.width-2*xSpace,height: 170))


        self.view.addSubview(self.pickView)


        //绑定协议
        self.pickView.dataSource=self
        self.pickView.delegate=self

        //初始化一个UILabel
        self.name=UILabel.init(frame: CGRect(x: xSpace, y: 300 ,width: frame.size.width-2*xSpace,height: 31))
        self.name.textAlignment=NSTextAlignment.center
        self.view.addSubview(self.name)

        //初始化一个UIButton
        let button=UIButton.init(type: UIButtonType.system)
        button.frame=CGRect(x: (frame.size.width-70)/2,y: 330,width: 70,height: 31)
        button.setTitle("click me", for: UIControlState.normal)
        button.addTarget(self, action: #selector(ViewController.showSelected(sender:)), for: UIControlEvents.touchUpInside)
        self.view.addSubview(button)

    }

    func showSelected(sender:Any) {

        let row1=self.pickView.selectedRow(inComponent: 0)
        let row2=self.pickView.selectedRow(inComponent: 1)
        let pro=self.pickerProvincesData[row1] as! String
        let city=self.pickerCitiesData[row2] as! String
        self.name.text=String.init(format: "%@ %@市", pro,city)


    }



    //选择器的拔轮的行数
    func numberOfComponents(in pickerView: UIPickerView) -> Int {

        return 2
    }

    //选择器中某个拔轮的行数
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

        if(component==0){

           return self.pickerProvincesData.count
        }

        return self.pickerCitiesData.count
    }


    //委托协议
    //为选择器的某个拔轮提供显示数据
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {

        if(component==0){

            return self.pickerProvincesData[row] as? String

        }

        return self.pickerCitiesData[row] as? String
    }
    //选中选择器的某个拔轮时调用
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        //选中省份时确定城市拔轮的数据
        if(component==0){

            let cityesDic=(self.pickerData[row] as! NSDictionary).value(forKey: "Cities") as! NSArray

            //清空城市数组
            self.pickerCitiesData.removeAllObjects()

            for city in cityesDic {

                self.pickerCitiesData.add((city as! NSDictionary).value(forKey: "city") as! String)
            }

            self.pickView.reloadComponent(1)

        }


    }


}

所有内容都在代码中了,比较详细了,应该可以看得懂,不在赘述了

二、UIColoctionView 集合视图
集合视图就像我们看小说时的那种 书架 类型 ,分 一行 一行的 ,每行上面都有几本书
每一行 在集合视图中 也叫作节
每本书 叫做单元格了
这里面主要学习UIColoctionView 视图如何创建和如何使用它的相关的协议
看效果图
这里写图片描述

我设置的数据比较简单,就是7条数据,一节两条数据
详细都在代码中注释了
首先为每个单元格 绑定了一个类 projectMy 相当于android中 适配器中的集合或者数组的类

import Foundation

//创建格简单的类,相当于android中适配器的数据类
class ProjectMy {

    var name:String
    var description:String
    init(name:String,description:String) {
        self.name=name
        self.description=description
    }

}

创建自定义单元格样式,相当于Android中的item视图

import UIKit

//创建单元格  相当于 android中的 item 布局文件
class ProCollectionViewCell: UICollectionViewCell {

    var name:UILabel!
    var details:UITextView!

    override init(frame: CGRect) {
        super.init(frame:frame)

        //获取单元格的大小
        let size:CGSize=self.frame.size

        //初始化name
        self.name=UILabel.init(frame: CGRect(x: 0, y: size.height-31, width: size.width,height: 31))
        self.name.textAlignment=NSTextAlignment.center
        self.addSubview(self.name)

        //初始化
        self.details=UITextView.init(frame: CGRect(x: 0, y: 0,width: size.width, height: size.height-31))
        self.details.textAlignment=NSTextAlignment.left
        self.details.isEditable=false //设置不可编辑
        self.addSubview(self.details)



    }

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

}

看controller文件

//
//  ViewController.swift
//  P5UIColection
//
//  Created by LF on 2017/4/2.
//  Copyright © 2017年 yinwei. All rights reserved.
//

import UIKit

//实现 集合视图委托协议 UICollectionViewDelegate 和 数据源协议UICollectionViewDataSource
class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {

    var pros:Array<ProjectMy>!

    var coloction:UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //创建模拟数据
        let p=ProjectMy.init(name: "健身", description: "好好锻炼,长出八块腹肌~呵呵哈哈哈,发出神经质的笑声!呵呵哈哈哈")
        self.pros=Array.init(repeating: p, count: 7)

        self.initViews()


    }

    //初始化视图
    func initViews() {

        //创建流式布局
        let layout=UICollectionViewFlowLayout()

        //设置单元格属性
        //设置单元格大小
        layout.itemSize=CGSize.init(width: 150, height: 150)

        //设置单元格内边距
        layout.sectionInset=UIEdgeInsets.init(top: 5, left: 5, bottom: 5, right: 5)
        //设置行间距
        layout.minimumLineSpacing=10
        //设置单元格间距
        layout.minimumInteritemSpacing=10

        self.coloction=UICollectionView.init(frame: self.view.frame, collectionViewLayout: layout)

        //设置单元格标示与单元格类型 
        //单元格标示是为了 复用单元格 防止每次都重新创建 跟 Android的holder 一个道理
        self.coloction.register(ProCollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")
        self.coloction.backgroundColor=UIColor.white

        self.coloction.delegate=self
        self.coloction.dataSource=self

        self.view.addSubview(self.coloction)


    }

    let NUM_COLUM=2 //每行的单元格数
    //实现重要的数据源协议
    //行数 节数
    func numberOfSections(in collectionView: UICollectionView) -> Int {

        //计算节数 即 行数
        if(self.pros.count%NUM_COLUM==0){

           return self.pros.count/NUM_COLUM
        }

        return self.pros.count/NUM_COLUM+1

    }

    //每一行的单元格数
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        //判断是否源数据能否占满每一行 占满返回2个 不能占满 返回一个
        if((section+1)*NUM_COLUM<=self.pros.count){

            return NUM_COLUM

        }

        return 1


    }

    //为单元格提供数据
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


        let cell=collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier", for: indexPath) as! ProCollectionViewCell

        let p:ProjectMy=self.pros[indexPath.section*NUM_COLUM+indexPath.row]

        cell.name.text=p.name
        cell.details.text=p.description

        return cell


    }


    //实现委托协议 实现两个常用的
    //选中单元格之后触发
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {



    }

    //取消选中单元格之后触发
    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {


    }



}

接下来学习IOS中最重要的控件,UITableView 最常用的 相信有这一节的基础,UITableView 不会太难~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值