用Swift实现表情发送

2016-07-24  本文已影响467人  DOU_SHA_BAO

      苹果官方一直大力推行Swift,Swift的简洁跟高新能得到不少人的青睐,貌似Swift将要成为ios开发的主流。那么Swift跟OC有何不同呢,或者你用OC实现过不少炫酷的功能,但那些功能,你能用Swift实现吗?答案是肯定的,只要你稍微努力一下,我觉得,你肯定可以做到。 

      今天我分享一个Swift做的小案例,希望能给学习Swift带来一点点,一丢丢帮助。由于工作比较紧,所以,这个案例我会分两次发。

      首先创建一个Swift的项目,跟OC创建一样,只要把下图选为Swift即可

这里演示的纯代码的方式,所以我把Main.stourboard删除了,顺带要把Info.plist的Main删除,如下图:

要在AppDelegate.swift里面添加如下代码:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

window = UIWindow(frame: UIScreen.mainScreen().bounds)

let rootViewController = ViewController()

window?.rootViewController = rootViewController

window?.makeKeyAndVisible()

return true

}

这样就可以加载到ViewController了。因为我们都是点聊天的导航栏跳出键盘,再点击表情,发送表情的。所以,我们需要在view的最下面,添加一个toolBar。因为主要实现表情发送,所以,我只建立了一个UIBarButton。然后点击该UIBarButton,就可以弹出选择表情的collectionCell,可以滑动可以选择。现在送上全部代码。只建立了三个文件:

ViewController的代码如下:

import UIKit

class ViewController: UIViewController {

/// 懒加载一个文本输入框

lazy var textView: UITextView = UITextView()

/// 模拟聊天,创建表情工具栏

lazy var toolBar: UIToolbar = UIToolbar()

/// 是否添加动画

var isShowAnimation: Bool = true

/// 表情键盘

lazy var emotionKeyboard: EmotionKeyboard = EmotionKeyboard(frame: CGRectMake(0,0,UIScreen.mainScreen().bounds.width,271))

/// 是否是自定义键盘

var isEmotionKeyboard: Bool = false

override func viewDidLoad() {

super.viewDidLoad()

view.backgroundColor = UIColor.whiteColor()

setUpUI()

//监听系统的键盘弹出

NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChanged:", name: UIKeyboardWillChangeFrameNotification, object: nil)

}

deinit {

NSNotificationCenter.defaultCenter().removeObserver(self)

}

}

extension ViewController {

func setUpUI() {

setUpUIToolBar()

setUpTextView()

}

func setUpTextView() {

view.addSubview(textView)

textView.font = UIFont.systemFontOfSize(14)

textView.backgroundColor = UIColor.greenColor()

textView.delegate = self

textView.snp_makeConstraints { (make) -> Void in

make.top.equalTo(view).offset(20)

make.left.equalTo(view)

make.right.equalTo(view)

make.bottom.equalTo(toolBar.snp_top)

}

}

func setUpUIToolBar() {

view.addSubview(toolBar)

/// 创建表情按钮

let button = UIButton()

button.setImage(UIImage(named: "smile_normal"), forState: .Normal)

button.setImage(UIImage(named: "smile_highlighted"), forState: .Highlighted)

/// 添加点击事件

button.addTarget(self, action: "emotionKeyboard:", forControlEvents: .TouchUpInside)

// 不少新手会容易忽略这一步,少了它,表情按钮就不显示了

button.sizeToFit()

let item = UIBarButtonItem(customView: button)

toolBar.items = [UIBarButtonItem]()

toolBar.items?.append(item)

toolBar.backgroundColor = UIColor.redColor()

toolBar.snp_makeConstraints { (make) -> Void in

make.height.equalTo(44)

make.bottom.equalTo(view)

make.left.equalTo(view)

make.right.equalTo(view)

}

}

}

extension ViewController: UITextViewDelegate {

}

/// 系统键盘弹出时,读取系统键盘的origin.y的值,以便自定义的toolBar随着系统弹起

extension ViewController {

@objc private func keyboardWillChanged(notification: NSNotification) {

if isShowAnimation == true {

//弹出键盘时,Y的偏移量

let keyboardOriginY = (notification.userInfo!["UIKeyboardFrameEndUserInfoKey"] as! NSValue).CGRectValue().origin.y

let duration = notification.userInfo!["UIKeyboardAnimationDurationUserInfoKey"] as! NSTimeInterval

let offset = keyboardOriginY - view.bounds.size.height

toolBar.snp_updateConstraints(closure: { (make) -> Void in

make.bottom.equalTo(view).offset(offset)

})

UIView.animateWithDuration(duration, animations: { () -> Void in

self.view.layoutIfNeeded()

})

}

}

/// 实现表情按钮的点击事件,切换系统键盘跟自定义键盘

@objc private func emotionKeyboard(button: UIButton) {

// 收起系统键盘

isShowAnimation = false

textView.resignFirstResponder()

isShowAnimation = true

if isEmotionKeyboard == false {

textView.inputView = emotionKeyboard

isEmotionKeyboard = true

}else {

// 切换回系统键盘

textView.inputView = nil

isEmotionKeyboard = false

}

textView.becomeFirstResponder()

}

}

自定义的表情键盘EmotionKeyboard的代码如下

import UIKit

private let cellIdentifier = "cellIdentifier"

let labelTag = 9527

private class EmotionCellLayout: UICollectionViewFlowLayout {

override func prepareLayout() {

super.prepareLayout()

minimumInteritemSpacing = 0

minimumLineSpacing = 0

scrollDirection = .Horizontal

itemSize = CGSizeMake(UIScreen.mainScreen().bounds.width, 234)

}

}

class EmotionKeyboard: UIView {

/// 懒加载存放表情的CollectionView

lazy var emotionCollectionView: UICollectionView = {

let collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: EmotionCellLayout())

collectionView.delegate = self

collectionView.dataSource = self

collectionView.pagingEnabled = true

collectionView.showsHorizontalScrollIndicator = false

collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: cellIdentifier)

collectionView.bounces = false

return collectionView

}()

/// 懒加载跳转表情类型的导航条

lazy var toolBar: EmotionToolBar = {

let toolBar = EmotionToolBar(frame: CGRectZero)

toolBar.toolBarDelegate = self

return toolBar

}()

override init(frame: CGRect) {

super.init(frame: frame)

setUpUI()

}

required init?(coder aDecoder: NSCoder) {

fatalError("init(coder:) has not been implemented")

}

}

extension EmotionKeyboard {

func setUpUI() {

/// 添加,设置,自动布局子控件

addSubview(emotionCollectionView)

addSubview(toolBar)

backgroundColor = UIColor.orangeColor()

emotionCollectionView.snp_makeConstraints { (make) -> Void in

make.left.equalTo(self)

make.right.equalTo(self)

make.top.equalTo(self)

make.height.equalTo(234)

//make.bottom.equalTo(self.snp_bottom).offset(-42)

}

toolBar.snp_makeConstraints { (make) -> Void in

make.top.equalTo(emotionCollectionView.snp_bottom)

make.left.equalTo(self)

make.right.equalTo(self)

make.height.equalTo(37)

// make.bottom.equalTo(self.snp_bottom).offset(-50)

}

print("=============\(self.bounds)")

}

}

extension EmotionKeyboard: UICollectionViewDataSource {

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {

return 4

}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

return 4

}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath)

cell.contentView.viewWithTag(labelTag)?.removeFromSuperview()

let titleLabel = UILabel(frame: CGRectMake(20,20,300,100))

titleLabel.tag = labelTag

titleLabel.text = "我是第\(indexPath.section)组\n我是第\(indexPath.item)行"

titleLabel.numberOfLines = 0

titleLabel.font = UIFont.systemFontOfSize(25)

titleLabel.textAlignment = .Left

titleLabel.textColor = UIColor.blackColor()

cell.contentView.addSubview(titleLabel)

cell.backgroundColor = self.randomColor()

return cell

}

}

extension EmotionKeyboard: UICollectionViewDelegate {

func scrollViewDidScroll(scrollView: UIScrollView) {

let offsetX = scrollView.contentOffset.x

var indexPath = NSIndexPath(forItem: 0, inSection: 0)

let cells = emotionCollectionView.visibleCells()

if cells.count > 1 {

//第一个cell

let firstCell = cells[0]

let firstCellIndex = emotionCollectionView.indexPathForCell(firstCell)

let firstCellOriginX = firstCell.frame.origin.x

let firstCellRegion = abs(offsetX - firstCellOriginX)

//第二个cell

let nextCell = cells[1]

let nextCellIndex = emotionCollectionView.indexPathForCell(nextCell)

let nextCellOriginX = nextCell.frame.origin.x

let nextCellRegion = abs(offsetX - nextCellOriginX)

//判断那个cell显示的区域大,就用那个cell的section

indexPath = (firstCellRegion > nextCellRegion ? nextCellIndex : firstCellIndex)!

toolBar.selectedIndex = indexPath.section

}

}

}

extension EmotionKeyboard: EmotionToolBarDelegate {

func changEmotionKeyboardType(buttonIndex: Int) {

let indexPath = NSIndexPath(forItem: 0, inSection: buttonIndex)

emotionCollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .CenteredHorizontally, animated: false)

}

}

extension EmotionKeyboard {

func randomColor() -> UIColor {

let r = CGFloat(random() % 255)

let g = CGFloat(random() % 255)

let b = CGFloat(random() % 255)

let color = UIColor(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: 1.0)

return color

}

}

自定义的EmotionToolBar的代码如下:

import UIKit

protocol EmotionToolBarDelegate: NSObjectProtocol {

func changEmotionKeyboardType(buttonIndex: Int)

}

class EmotionToolBar: UIStackView {

weak var toolBarDelegate: EmotionToolBarDelegate?

var selectedButton: UIButton?

var selectedIndex: Int = 0 {

didSet {

selectedButton?.selected = false

let button = viewWithTag(selectedIndex+labelTag) as! UIButton

button.selected = true

print(selectedIndex)

selectedButton = button

}

}

override init(frame: CGRect) {

super.init(frame: frame)

axis = .Horizontal

distribution = .FillEqually

setUpUI()

}

required init?(coder aDecoder: NSCoder) {

fatalError("init(coder:) has not been implemented")

}

}

extension EmotionToolBar {

func setUpUI() {

///暂时先创建四个表情button

createToolBarButton("最近", tag: 0)

createToolBarButton("A号", tag: 1)

createToolBarButton("B号", tag: 2)

createToolBarButton("C号", tag: 3)

}

func createToolBarButton (title: String, tag: Int ) {

let button = UIButton()

button.setTitle(title, forState: .Normal)

button.backgroundImageForState(.Normal)

button.setTitleColor(UIColor.whiteColor(), forState: .Normal)

button.setTitleColor(UIColor.blackColor(), forState: .Selected)

button.addTarget(self, action: "changEmotionType:", forControlEvents: .TouchUpInside)

button.tag = tag+labelTag

addArrangedSubview(button)

if tag == 0  {

button.selected = true

selectedButton = button

}

}

}

extension EmotionToolBar {

@objc private func changEmotionType(button:UIButton) {

selectedButton?.selected = false

button.selected = true

selectedButton = button

toolBarDelegate?.changEmotionKeyboardType(button.tag-labelTag)

}

}

这样实现表情栏的滚动与选择了。效果如下图:

下一篇,会在collectionCell里面添加表情,后续表情的添加,请留意后续更新。

现在代码里饱含了几种属性的定义,方法的创建,分类的添加,协议的定义,方法的重写与调用,基本数据类型,数组,字典的定义,希望看客们好好理解一下。细心的看客们肯定已经发现,代码里有很多“?”与“!”,这里涉及到可选值的问题,会在后面作详细的解析。

 最后 ,谢谢光临。

上一篇 下一篇

猜你喜欢

热点阅读