? ? ? 蘋果官方一直大力推行Swift,Swift的簡潔跟高新能得到不少人的青睞娱仔,貌似Swift將要成為ios開發(fā)的主流。那么Swift跟OC有何不同呢,或者你用OC實(shí)現(xiàn)過不少炫酷的功能墓塌,但那些功能,你能用Swift實(shí)現(xiàn)嗎奥额?答案是肯定的苫幢,只要你稍微努力一下,我覺得垫挨,你肯定可以做到韩肝。?
? ? ? 今天我分享一個(gè)Swift做的小案例,希望能給學(xué)習(xí)Swift帶來一點(diǎn)點(diǎn)九榔,一丟丟幫助哀峻。由于工作比較緊涡相,所以,這個(gè)案例我會(huì)分兩次發(fā)剩蟀。
? ? ? 首先創(chuàng)建一個(gè)Swift的項(xiàng)目催蝗,跟OC創(chuàng)建一樣,只要把下圖選為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了缰冤。因?yàn)槲覀兌际屈c(diǎn)聊天的導(dǎo)航欄跳出鍵盤犬缨,再點(diǎn)擊表情,發(fā)送表情的棉浸。所以遍尺,我們需要在view的最下面,添加一個(gè)toolBar涮拗。因?yàn)橹饕獙?shí)現(xiàn)表情發(fā)送乾戏,所以,我只建立了一個(gè)UIBarButton三热。然后點(diǎn)擊該UIBarButton鼓择,就可以彈出選擇表情的collectionCell,可以滑動(dòng)可以選擇【脱現(xiàn)在送上全部代碼呐能。只建立了三個(gè)文件:
ViewController的代碼如下:
import UIKit
class ViewController: UIViewController {
/// 懶加載一個(gè)文本輸入框
lazy var textView: UITextView = UITextView()
/// 模擬聊天,創(chuàng)建表情工具欄
lazy var toolBar: UIToolbar = UIToolbar()
/// 是否添加動(dòng)畫
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()
//監(jiān)聽系統(tǒng)的鍵盤彈出
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)
/// 創(chuàng)建表情按鈕
let button = UIButton()
button.setImage(UIImage(named: "smile_normal"), forState: .Normal)
button.setImage(UIImage(named: "smile_highlighted"), forState: .Highlighted)
/// 添加點(diǎn)擊事件
button.addTarget(self, action: "emotionKeyboard:", forControlEvents: .TouchUpInside)
// 不少新手會(huì)容易忽略這一步抑堡,少了它摆出,表情按鈕就不顯示了
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 {
}
/// 系統(tǒng)鍵盤彈出時(shí),讀取系統(tǒng)鍵盤的origin.y的值首妖,以便自定義的toolBar隨著系統(tǒng)彈起
extension ViewController {
@objc private func keyboardWillChanged(notification: NSNotification) {
if isShowAnimation == true {
//彈出鍵盤時(shí)偎漫,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()
})
}
}
/// 實(shí)現(xiàn)表情按鈕的點(diǎn)擊事件,切換系統(tǒng)鍵盤跟自定義鍵盤
@objc private func emotionKeyboard(button: UIButton) {
// 收起系統(tǒng)鍵盤
isShowAnimation = false
textView.resignFirstResponder()
isShowAnimation = true
if isEmotionKeyboard == false {
textView.inputView = emotionKeyboard
isEmotionKeyboard = true
}else {
// 切換回系統(tǒng)鍵盤
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
}()
/// 懶加載跳轉(zhuǎn)表情類型的導(dǎo)航條
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() {
/// 添加有缆,設(shè)置象踊,自動(dòng)布局子控件
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 {
//第一個(gè)cell
let firstCell = cells[0]
let firstCellIndex = emotionCollectionView.indexPathForCell(firstCell)
let firstCellOriginX = firstCell.frame.origin.x
let firstCellRegion = abs(offsetX - firstCellOriginX)
//第二個(gè)cell
let nextCell = cells[1]
let nextCellIndex = emotionCollectionView.indexPathForCell(nextCell)
let nextCellOriginX = nextCell.frame.origin.x
let nextCellRegion = abs(offsetX - nextCellOriginX)
//判斷那個(gè)cell顯示的區(qū)域大,就用那個(gè)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() {
///暫時(shí)先創(chuàng)建四個(gè)表情button
createToolBarButton("最近", tag: 0)
createToolBarButton("A號(hào)", tag: 1)
createToolBarButton("B號(hào)", tag: 2)
createToolBarButton("C號(hào)", 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)
}
}
這樣實(shí)現(xiàn)表情欄的滾動(dòng)與選擇了棚壁。效果如下圖:
下一篇杯矩,會(huì)在collectionCell里面添加表情,后續(xù)表情的添加袖外,請(qǐng)留意后續(xù)更新史隆。
現(xiàn)在代碼里飽含了幾種屬性的定義,方法的創(chuàng)建曼验,分類的添加泌射,協(xié)議的定義头镊,方法的重寫與調(diào)用,基本數(shù)據(jù)類型魄幕,數(shù)組相艇,字典的定義,希望看客們好好理解一下纯陨。細(xì)心的看客們肯定已經(jīng)發(fā)現(xiàn)坛芽,代碼里有很多“?”與“翼抠!”咙轩,這里涉及到可選值的問題,會(huì)在后面作詳細(xì)的解析阴颖。
?最后 活喊,謝謝光臨。