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

自定义表情键盘
表情包含:默认、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
    }
    
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

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