iOS Swift版纯代码使用UICollectionView

前言:

读者如果是以应对学校学习可移步至 iOS Swift版 UICollectionView的使用,这篇文章是基于StoryBoard实现的,难度很小;如果想要了解UICollectionView内的控件布局展示内容,请移步至UICollectionView cell子项布局的分析。下面的UICollectionView的实现是基于纯代码方式,内容对于初学者而言可能有些许繁琐,但总体来说还是比较简单的。

正文:

1: 准备图片数据

这步是为了准备数据源,图片文件拖拽到Assets.xcassets文件夹内即可。名称随意。

2:编写UICollectionViewCell类

import UIKit
import Foundation

class CollectionViewCell: UICollectionViewCell {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        let image = UIImage(named: "psc");
        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
        
        imageView.image = image
        
        self.addSubview(imageView)
    }
 
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
        
    }
}

说明:自定义UICollectionViewCell子类,重写构造方法,在里面进行cell子项内部控件的初始化与布局。

3:在ViewController实现UICollectionViewDelegate, UICollectionViewDataSource

实现完后Xcode会提示报错,修复后会多出两个协议,如下:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    }
    
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    }

第一个方法为待返回cell子项的数目,也就是要展示的数目;第二个方法为返回待创建的cell内容和其子项

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 25
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CELL_ID", for: indexPath) as! CollectionViewCell
            
        return cell
        
    }

在第二个方法内我们看到了一个这样的方法: collectionView.dequeueReusableCell() ,该方法的作用是获得cell对象,其第一个参数是UICollectionView对象注册时的ID,string类型,as!后面跟的就是一开始建立的cell子项类。

4:定义UICollectionView控件并准备初始化UICollectionView

这一步就很简单了,基本上就是设置UICollectionView的各种属性。

var collectionView: UICollectionView!

// 设置布局方向
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal

// 调用UICollectionView的构造方法来初始化控件大小和位置
collectinoView = UICollectionView(frame: CGRect(x: 0, y: 50, width: self.view.frame.width, height: 100), collectionViewLayout: flowLayout)
collectinoView.backgroundColor = UIColor.white

// 设置数据源和代理
collectinoView.delegate = self
collectinoView.dataSource = self

// 注册UICollectionView,第一个参数是一开始的cell子项类,第二个是ID
collectinoView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CELL_ID")
self.view.addSubView(collectionView)  

5:全部代码:

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
    
    var collectinoView: UICollectionView!
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 25
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CELL_ID", for: indexPath) as! CollectionViewCell
            
        return cell

    }
    
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
            print("index is \(indexPath.row)")
    }
    
    private func initView(){
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.scrollDirection = .horizontal
        collectinoView = UICollectionView(frame: CGRect(x: 0, y: 50, width: self.view.frame.width, height: 100), collectionViewLayout: flowLayout)
        collectinoView.backgroundColor = UIColor.white
        collectinoView.delegate = self
        collectinoView.dataSource = self
        collectinoView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CELL_ID")
        
        self.view.addSubview(collectinoView)
               
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        initView()
    }


}

6: 设置监听

实现这个方法即可: func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
这个方法内获取indexPath即为点击的子项

常见问题:

1:如何在一个ViewController里面编写多个UICollectionView控件?

有Android或Winform开发经验的读者会知道,它们都有与iOS里面的UICollectionView控件对应的控件,Android为RecyclerView,Winform为ListView。在Android中是由对应的适配器(Adapter)、Bean,构成。如果要在一个Activity里面实现多个RecyclerView只须多写几个适配器和Bean然后在Activity里面实例化即可。那么在ViewController里面提供的几个方法似乎只像是给一个UICollectionView提供的,该如何在一个ViewController里面编写多个UICollectionView控件呢?答案就在完成协议后系统提示我们要修复的那几个方法里面的参数。
以返回cell数目这个方法为例,假设我们需要在一个视图里面编写两个UICollectionView控件,那么这个方法应该这样写:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    switch collectionView {
    case self.firstCollectionView:
        return 1
    case self.secondCollectionView:
        return 2
    default:
        return 0
    }
    
}

另外一个返回cell对象的方法读者可以类比推出,不再赘述。

2:空的构造布局?

读者可能会遇到如下报错:

UICollectionView must be initialized with a non-nil layout paramete  

其大意为UICollectionView必须随着一个非空的布局参数而初始化。那么原因也就明了:该控件初始化的地方并没有传入布局参数(流式布局)。
例如,出问题的代码可能像下面这样:

collectinoView = UICollectionView(frame: CGRect(x: 0, y: 50, width: self.view.frame.width, height: 100))  

那么,正确写法应该这样写:

let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .horizontal
collectinoView = UICollectionView(frame: CGRect(x: 0, y: 50, width: self.view.frame.width, height: 100), collectionViewLayout: flowLayout)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS Swift中连接扫描枪的代码主要分为两个部分:Bluetooth连接和接收扫描数据。 首先,需要在应用中引入CoreBluetooth库。在ViewController中创建一个BLEManager类,并像下面这样定义其属性和方法: ```swift class BLEManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate { var centralManager: CBCentralManager? var peripheral: CBPeripheral? var characteristic:CBCharacteristic? override init() { super.init() centralManager = CBCentralManager(delegate: self, queue: nil) } func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == .poweredOn { central.scanForPeripherals(withServices:nil, options: nil) print("Scanning started") } else { print("Bluetooth not available.") } } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { if (peripheral.name == "Your peripheral name") { self.centralManager?.stopScan() self.peripheral = peripheral self.peripheral?.delegate = self self.centralManager?.connect(self.peripheral!, options: nil) } } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { if peripheral == self.peripheral { peripheral.discoverServices(nil) print("Connected to your peripheral") } } func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { for service in peripheral.services! { peripheral.discoverCharacteristics(nil, for: service) } } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { for characteristic in service.characteristics! { if characteristic.uuid == CBUUID(string: "Your characteristic UUID") { self.characteristic = characteristic peripheral.setNotifyValue(true, for: characteristic) print("Characteristic found") } } } func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if characteristic == self.characteristic { if let data = characteristic.value { let string = String(data: data, encoding: .utf8)! print("Scanned barcode is: \(string)") } } } } ``` 接着,在ViewController中初始化BLEManager并调用centralManager的方法: ```swift var bleManager: BLEManager? override func viewDidLoad() { super.viewDidLoad() bleManager = BLEManager() } ``` 最后,需要将扫描枪的UUID和特征UUID替换为自己的。这样,应用就能连接扫描枪并接收扫描数据了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值