搭建微博編輯頁面的表情鍵盤


當下發狀態和發評論已經漸漸成為不少軟件的必備功能,這兩者功能基本類似。但是有普通編輯和高級編輯之分,普通的評論只能發文本,一旦可以發送表情(非emoji表情)就需要用到圖文混排。並且系統只能提供emoji表情,要用到其他自定義表情需要自行添加表情鍵盤。

因為表情鍵盤和圖文混排寫在一起太長了分為兩期。本期以新浪微博的發微博頁面為例,整理添加表情鍵盤的步驟,下期會總結自己在編寫圖文混排中遇到的種種問題和解決方案。基本的頁面類似於這樣,有部分細節沒做不過也無關大雅了。編寫的語言用的是swift

如果你不是在董鉑然博客園看到本文,請點擊查看原文

我表情鍵盤的做法是,在發布微博控制器頁面底部添加一個toolbar 然后底部的約束拖一根線到控制器里,可以根據監聽鍵盤的彈出動態修改。

下面的表情鍵盤是新建一個xib或者storyboard 建一個普通控制器,上面放collectionView,下面放一個view或者toolbar顯示表情的種類。

collectionViewCell內部放一個imageView 和 一個Label。因為emoji表情是需要用label顯示的。

下圖是兩個設計界面

左邊的撰寫微博控制器和上面的效果截圖有些不同。因為設置了導航欄的顏色主題是黃色。里面灰色的placeholder請發布微博是用代碼添加的設置為textView的子控件。上面的設置可以自行腦補在此不作過多贅述了,本文主要是總結表情鍵盤和圖文混排

右邊的表情鍵盤控制器也是可以清楚地看到cell里有imgView和label

這里記得要在撰寫微博控制器里設置,點擊小圓臉就設置第一響應者,並且把彈出鍵盤的inputView設置成我們自定義的這個表情鍵盤控制器。

然后就是里面cell的流水布局,把控制器里的布局拖到控制器中修改

 override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        setupLayout()
    }
    func setupLayout(){
        
        let row:CGFloat = 3
        let col:CGFloat = 7
        let m:CGFloat = 10
        
        let screenSize = self.collectionView.bounds.size
        let w = (screenSize.width - (col + 1) * m) / col
        
        layout.itemSize = CGSizeMake(w, w)
        layout.minimumInteritemSpacing = m
        layout.minimumLineSpacing = m
        
        /// 每一組之間的邊距
        layout.sectionInset = UIEdgeInsetsMake(m, m, m, m)
        
        layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
        
        collectionView.pagingEnabled = true
    }

 之所以寫在ViewDidLayoutSubViews方法中,是為了等前面的布局完全加載好。

布局完畢后應該就是可以看到此效果。

然后就是加載表情圖片,把表情圖片依次填到這些方框中

表情圖片的加載方法:

1.下載個新浪微博的ipa解壓,在里面能夠找到所有的表情包都是裝在一個emticons文件夾里

2.文件夾中有個emoticons.plist文件,里面是一個數組,里面包含四個字典分別是四種表情的各項參數。和四個文件夾里裝着四種表情

3.每一種表情的文件夾里還有一個info.plist文件,這個文件里是個字典包含幾個自己表情參數和一個數組,里面裝的是本類別的所有表情

4.這里面的參數目測應該就能看懂分別是干什么的 如圖 

 

5.這里加載表情圖片時要注意不能直接使用第三方框架字典轉模型,因為字典轉模型之后的模型數組內值都是連續的,但是每頁的右下角還需要添加一個刪除按鈕,所以產生矛盾

6.所以加載表情圖片的基本思路是,手寫方法一層一層加載,先把emoticons.plist轉模型,再通過里面的path可以取到每一個info.plist再轉模型。

7.然后info.plist中有一個數組里裝着所有的表情,每一個表情又是一個字典再給他轉模型。並設置個模型數組

8.前面設置collectionView的布局是3*7,這里就設置collectionView的Section每組21個,除去一個刪除按鈕正好是每頁20個表情。

9.把模型和模型數組整理好,該addObject的就addObject。

 

最后在數據源方法中加載:

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        /// 返回有幾種表情
        return emoticonSection?.count ?? 0
    }
    
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        /// 返回每個種類中的表情數量
        return emoticonSection![section].emoticons.count
    }
    
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("EmoticonsCell", forIndexPath: indexPath) as! EmoticonCell
        /// 屬性賦值
        cell.emoticon = emoticonSection![indexPath.section].emoticons[indexPath.item]
        
        return cell
    }

 至於cellForItem里的屬性賦值,是在自定義的EmoticonCell里設置didSet判斷模型的種類(是否是emoji表情)再完成數據分發

/// 自定義表情cell
class EmoticonCell: UICollectionViewCell {
    @IBOutlet weak var iconView: UIImageView!
    @IBOutlet weak var emojiLabel: UILabel!
    
    var emoticon: Emoticon? {
        /// 賦值完成后調用
        didSet {
            if let path = emoticon?.imagePath {
                iconView.image = UIImage(contentsOfFile: path)
            } else {
                iconView.image = nil
            }
            
            emojiLabel.text = emoticon?.emoji
            
            // 是否是刪除按鈕
            if emoticon!.isDeleteButton {
                iconView.image = UIImage(named: "compose_emotion_delete_highlighted")
            }
        }
    }
}

 之后表情鍵盤就可以如圖的顯示了。

 

然后就是監聽每個按鈕表情的點擊事件。這里需要用到代理。

定義一個協議協議里有個方法點擊時把自己(表情控制器)和點中的表情模型傳過去

再在collectioView的代理方法中設置didSelected觸發

協議:

protocol EmoticonsViewControllerDelegate: NSObjectProtocol {
    /// 選中了某一個表情
    func emoticonsViewControllerDidSelectEmoticon(vc:SXEmoticonsViewController, emoticon: Emoticon)
}

 代理方法:

    /// 根據 indexPath 返回表情數據
    func emoticon(indexPath: NSIndexPath) -> Emoticon {
        return emoticonSection![indexPath.section].emoticons[indexPath.item]
    }
    
    /// cell 被選中
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        // 使用 ? 不需要判斷代理是否實現方法
        delegate?.emoticonsViewControllerDidSelectEmoticon(self, emoticon: emoticon(indexPath))
    }

 

在撰寫微博控制器里,接收到數據模型后能打印出來就證明前面的表情鍵盤都做好了。

如果你不是在董鉑然博客園看到本文,請點擊查看原文

正在整理圖文混排,有興趣的可以關注


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM