苹果官方一直大力推行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里面添加表情,后续表情的添加,请留意后续更新。
现在代码里饱含了几种属性的定义,方法的创建,分类的添加,协议的定义,方法的重写与调用,基本数据类型,数组,字典的定义,希望看客们好好理解一下。细心的看客们肯定已经发现,代码里有很多“?”与“!”,这里涉及到可选值的问题,会在后面作详细的解析。
最后 ,谢谢光临。