自定义表情键盘 - 一维、二维、三维数组使用

自定义表情键盘
表情包含:默认、Emoji和浪小花
提供方式:bundle文件
框架结构:

自定义表情键盘.png
分析:
     目前有一维数组:
     - 默认表情    一共108个
     - emoji表情  一共80个
     - 浪小花      一共40个
     
     把以上的一维数组转成二维数组
            
        表情分类:     每一个一维数组中包含元素个数:      索引:
     
        默认表情       [20 20 20 20 20 8]           0 - 19 , 20 - 39 ..... ,100- 107
     
        emoji表情     [20 20 20 20 ]               0 - 19 , 20 - 39 , 40 -59
     
        浪小花         [20 20]                      0 - 19 , 20 - 39
代码实现:

① 因为表情信息会多次使用,所以提供一个全局访问点,便于使用

    //全局访问点(单例)
    static let sharedTool: JSEmoticonTool = JSEmoticonTool()

② 获取表情包bundle路径

    // 懒加载获取Bundle
    lazy var emoticonBundle: NSBundle = {
        // 获取bundle路径
        let path = NSBundle.mainBundle().pathForResource("Emoticons.bundle", ofType: nil)!
        // 获取bundle
        let bundle = NSBundle(path: path)!
        // 返回bundle
        return bundle
    }()

③ 提供一个公共方法,从bundle中的plist文件提取出一维数组

    // MARK: - 读取plist文件中的数组,转成模型一维数组
    private func getEmoticons(fileName: String) -> [JSEmoticonModel] {
        
        ///...Classes/Compose/View/Emoticon/Emoticons.bundle/Contents/Resources/emoji/info.plist
        // 读取plist文件中的数组转成模型一维数组
        
        // 文件路径
        let file = emoticonBundle.pathForResource("\(fileName)/info.plist", ofType: nil)!
        // plist文件转数组
        let array = NSArray(contentsOfFile: file)!
        
        // 创建可变临时数组
        var tmpArr: [JSEmoticonModel] = [JSEmoticonModel]()
        // 遍历Array
        for dict in array {
            
            // KVC 字典转模型
            let element = JSEmoticonModel(dict: dict as! [String: AnyObject])
            
            // 保存模型
            tmpArr.append(element)
            
        }
        // 返回存放模型的一维数组
        return tmpArr
        
    }

补充

  • pathForResource获取到的路径并不完整,只能获取到bundle的Resources文件夹,所以进行了拼接,得到完整的路径
bundle_path.png
  • 并且bundle中存放的图片无法直接通过转模型后的图片名直接使用,需要根据导入的bundle文件拼接完整路径才可以
// 图片表情
// 从模型中获取补充的路径名
let path = emoticonModel.path ?? ""
 // 从模型中获取图片的名称
 let png = emoticonModel.png ?? ""
// 拼接图片的全路径
 let name = path + png               
let image = UIImage(named: name, inBundle: JSEmoticonTool.sharedTool.emoticonBundle, compatibleWithTraitCollection: nil)        
button.setImage(image, forState: UIControlState.Normal)

④ 根据公共方法懒加载表情数据,得到的是一维数组

    // default 表情 : 一维数组
    lazy var defaultEmoticons: [JSEmoticonModel] = {
        return self.getEmoticons("default/")
    }()
    // emoji 表情 : 一维数组
    lazy var emojiEmoticons: [JSEmoticonModel] = {
        return self.getEmoticons("emoji/")
    }()
    // 浪小花 表情 : 一维数组
    lazy var lxhEmoticons: [JSEmoticonModel] = {
        return self.getEmoticons("lxh/")
    }()

⑤ 根据表情键盘布局规则,将一维数组转二维数组

    // 显示列数
    let EmoticonMaxCol = 7
    // 显示行数
    let EmoticonMaxRow = 3
    // 每页显示的个数
    let EmoticonMaxCount = EmoticonMaxCol * EmoticonMaxRow - 1

每一页显示固定的表情个数,所以需要将一维数组重新按照每页显示表情个数重新分组
遍历每一个一维数组,将一维数组转成二维数组

    // MARK: - 一维数组转二维数组
    func getEmoticonsGroup(emoticons: [JSEmoticonModel]) -> [[JSEmoticonModel]] {
        
        // 计算页数
        let pageCount = (emoticons.count + EmoticonMaxCount - 1) / EmoticonMaxCount
        
        // 创建一个临时的可变的二维数组
        var tempArray:[[JSEmoticonModel]] = [[JSEmoticonModel]]()
        
        // 遍历一维数组(正序) 截取一维数组
        for i in 0..<pageCount {
            
            // 位置和长度
            let loc = EmoticonMaxCount * i
            var len = EmoticonMaxCount
            
            // 避免数组越界
            if loc + len > emoticons.count {
                len = emoticons.count - loc
            }
            
            // 截取范围
            let range = NSMakeRange(loc, len)
            
            // 数组的截取
            let arr = (emoticons as NSArray).subarrayWithRange(range) as! [JSEmoticonModel]

            // 保存一维数组
            tempArray.append(arr)
            
        }
        
        // 返回二维数组
        return tempArray
    }

⑥ 最后将得到的二维数组合成为三维数组

    // 表情 : 三维数组
    lazy var allEmoticons: [[[JSEmoticonModel]]] = {
        return [
            self.getEmoticonsGroup(self.defaultEmoticons),
            self.getEmoticonsGroup(self.emojiEmoticons),
            self.getEmoticonsGroup(self.lxhEmoticons)
                ]
    }()

这样,再通过CollectionView分配数据时:
三维数组的长度 --> CollectionView --> NumberOfSection
二维数组的长度 --> CollectionView --> NumberOfItemInSection
一维数组的元素 --> CollectionView --> Cell所需数据

// 数据源方法
extension JSEmojiconPageView: UICollectionViewDataSource {
    
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        
        return JSEmoticonTool.sharedTool.allEmoticons.count
    }
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        
        return JSEmoticonTool.sharedTool.allEmoticons[section].count
    }
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(collectionViewCellId, forIndexPath: indexPath) as! JSEmojiconPageViewCell
        cell.indexpath = indexPath
        
        cell.emoticons = JSEmoticonTool.sharedTool.allEmoticons[indexPath.section][indexPath.item]
        
        return cell
    }
    
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,229评论 4 61
  • 不可描绘的未来 急促得很苍白 而你紧张得像个小孩。 风儿吹过,花也飘来 悄悄躲在橱窗外看隔壁女孩 很可爱,你笑开了...
    墨苏因阅读 199评论 0 0
  • 现在有很多爬虫框架,比如scrapy、webmagic、pyspider都可以在爬虫工作中使用,也可以直接通过re...
    DaVinciDW阅读 1,334评论 0 1
  • 2017年1月14日打卡 周六,阳光明媚的一天。风很凉。 虽然在阳台上晒太阳不科学,但是真要去楼下全身暴露在寒风中...
    沈曼柔阅读 221评论 3 2
  • 今天要说的这个女孩是我的“师傅”,大三的时候,我在学校食堂水吧兼职,认识了她,为什么我们能成为师徒呢? 因为我们同...
    曾琦阅读 433评论 5 9