第九天
第九天我们的2个任务, 1. 基于第八天我们对表情包的封装,进行表情键盘的实现, 2. 处理发微博的图文混排 下边开始:
发布微博页面
- 首先我们在
XQWBComposeViewController
添加对应的控件/// 编辑框 @IBOutlet weak var textView: UITextView! /// 底部工具栏 @IBOutlet weak var toolbar: UIToolbar! /// 发布按钮 @IBOutlet var sendButton: UIButton! /// 标题 @IBOutlet var titleLabel: UILabel!
- 设置导航栏按钮和title
/// 设置导航栏 func setupNavigationBar() { navigationItem.leftBarButtonItem = UIBarButtonItem(title: "退出", target: self, action: #selector(close)) // 发送按钮 navigationItem.rightBarButtonItem = UIBarButtonItem(customView: sendButton) navigationItem.titleView = titleLabel }
- 给工具栏添加按钮
/// 设置工具栏 func setupToolBar() { let itemSettings = [["imageName": "compose_toolbar_picture"], ["imageName": "compose_mentionbutton_background"], ["imageName": "compose_trendbutton_background"], ["imageName": "compose_emoticonbutton_background", "actionName": "emoticonKeyboard"], ["imageName": "compose_add_background"]] var items = [UIBarButtonItem]() // 遍历数组 for s in itemSettings { guard let imageName = s["imageName"] else { continue } let image = UIImage(named: imageName) let imageHL = UIImage(named: imageName + "_highlighted") let btn = UIButton() btn.setImage(image, for: .normal) btn.setImage(imageHL, for: .highlighted) // 添加按钮 btn.sizeToFit() items.append(UIBarButtonItem(customView: btn)) items.append(UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)) } items.removeLast() toolbar.items = items }
表情键盘处理
表情键盘的处理其实就是监听
textView
的inputView
@objc private func emoticonKeyboard() {
// textView.inputView 是文本的输入视图
// 如果是系统的自带键盘,则为nil
// 1. 键盘视图
let keyboardView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
keyboardView.backgroundColor = UIColor.red
// 2. 设置键盘视图
textView.inputView = (textView.inputView == nil) ? emoticonView : nil
// 刷新键盘
textView.reloadInputViews()
}
- 创建
XQWBEmoticonInputView
的xib并且添加视图控件// collectionView @IBOutlet weak var collectionView: UICollectionView! // 工具栏 @IBOutlet weak var toolBar: XQWBEmoticonToolBar!
- 声明一个选中表情时候的闭包,并且在实例化的类方法中记录
/// 选中表情的闭包 private var selectedEmoticonCallBack: ((_ em: XQWBEmoticon?)->())? /// 加载并返回 class func input(selectedEmoticon: @escaping (_ em: XQWBEmoticon?)->()) -> XQWBEmoticonInputView { let nib = UINib(nibName: "XQWBEmoticonInputView", bundle: nil) let v = nib.instantiate(withOwner: nil, options: nil)[0] as! XQWBEmoticonInputView // 记录闭包 v.selectedEmoticonCallBack = selectedEmoticon return v }
- 实现
collectionView
的代理方法extension XQWBEmoticonInputView: UICollectionViewDataSource { // 分组数量 func numberOfSections(in collectionView: UICollectionView) -> Int { return XQWBEmoticonManager.shared.packages.count } // 每个分组的数量 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return XQWBEmoticonManager.shared.packages[section].numberOfPages } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // 1. 取cell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) as! XQWBEmoticonCell // 2. 设置cell cell.emoticons = XQWBEmoticonManager.shared.packages[indexPath.section].emoticon(page: indexPath.item) // 2.2 设置代理 cell.delegate = self // 3. 返回 return cell } }
- 实现cell选中表情的时候的代理方法
extension XQWBEmoticonInputView: XQEmoticonCellDelegate { func emoticonCellDidSelectEmoticon(cell: XQWBEmoticonCell, em: XQWBEmoticon?) { // 执行闭包 回调选中的表情 selectedEmoticonCallBack?(em) } }
处理控制器里的图文混排
- 懒加载输入视图,实现表情点击的闭包
lazy var emoticonView: XQWBEmoticonInputView = XQWBEmoticonInputView.input {[weak self] (emoticon) in self?.insertEmoticon(em: emoticon) }
- 实现图文混排
/// 插入表情符号 func insertEmoticon(em: XQWBEmoticon?) { guard let em = em else { // 1. em nil 删除文本 textView.deleteBackward() return } // 2. 添加表情 emoji if let emoji = em.emoji, let textRange = textView.selectedTextRange { textView.replace(textRange, withText: emoji) return } // 3.图片 let imageText = em.imageText(font: textView.font!) // >1 获取当前textview 的属性文本 let attrStrm = NSMutableAttributedString(attributedString: textView.attributedText) // >2 讲图像属性文本添加到光标位置 attrStrm.replaceCharacters(in: textView.selectedRange, with: imageText) // >3 重新设置文本 // >3.1 记录光标位置 let range = textView.selectedRange textView.attributedText = attrStrm // >4 回复光标位置 textView.selectedRange = NSRange(location: range.location+1, length: 0) }