技能 1. 關(guān)于自定義標(biāo)記
對于OC中 我們想在DEBUG狀態(tài)下做事情,但是不在 RELease中實(shí)現(xiàn)的時(shí)候,我們一般是定義宏,來實(shí)現(xiàn),一般寫在.pch文件中. 代碼如下
#ifdef DEBUG
#define LXLLog(...) NSLog(@"%s\n %@\n\n", __func__, [NSString stringWithFormat:__VA_ARGS__])
#else
#endif
對于Swift中,由于沒有了宏定義這個(gè)一個(gè)功能,我們只能自己建造標(biāo)記來定義,什么時(shí)候是 DEBUG,什么時(shí)候是RELEASE. 可以利用 方法來定義 對用的console 語句
// T指泛型,可由可無,任意類型. 此方法,可以輸出對應(yīng)的文件, 方法名, 以及行號
func LXLLog<T>(message: T, file: String = __FILE__, method: String = __FUNCTION__, line: Int = __LINE__)
{
#if LXL_DEBUG
print("\((file as NSString).lastPathComponent)[\(line)], \(method): \(message)")
#endif
}
但只是定義這么一個(gè)語句是不被使用的, 對已這個(gè)帶有標(biāo)記的語句, 要進(jìn)行再Swift中注冊說明
技能2: 關(guān)于SBRefrence 也就是 Storyboard refrence的使用
對于SBRefrence 的使用比較好, 可以很好的改變程序的結(jié)構(gòu),但是又不影響程序的正常使用.
技能3: Swift中main函數(shù)的消失
官方解釋:
In Xcode, Mac templates default to including a “main.swift” file, but for iOS apps the default for new iOS project templates is to add @UIApplicationMain to a regular Swift file. This causes the compiler to synthesize a mainentry point for your iOS app, and eliminates the need for a “main.swift” file.
Swift項(xiàng)目中添加了@UIApplicationMain 到swift文件中响委,使得編譯器合成了一個(gè)app入口麸塞,所以不需要main.swift文件
當(dāng)然我們也可以手動創(chuàng)建程序的入口 main 函數(shù):
1.注銷掉 @UIApplicationMain
2.手動創(chuàng)建名字為main的文件
import Foundation
import UIKit
UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), NSStringFromClass(AppDelegate))
`
技能4: 對于便利構(gòu)造器(比較方便的構(gòu)造器, convenience)的使用
對已一般對象的初始化, 我們經(jīng)常使用 init() 進(jìn)行初始化, 當(dāng)然有時(shí)候我們會進(jìn)行 對已經(jīng)初始化的對象 添加新的屬性, 對于 便利構(gòu)造器而言, 添加屬性可以重寫 init()方法進(jìn)行添加, 這種以 init 方法開頭的重寫方法, 在Swift中我們稱之為 便利構(gòu)造器, 它的使用必須 調(diào)用本類的指定構(gòu)造器 也就是 必須 對本類所有 屬性進(jìn)行初始化才可以使用.
Swift中 對于以 init()作為初始化的方法, 沒有返回值, 默認(rèn)返回self, OC中是有返回值得, 并且確保 已經(jīng)初始化父類屬性,才可以使用
還有一種構(gòu)造方法稱之為 中 , 內(nèi)部創(chuàng)建對象, 并且對于對象的屬性進(jìn)行初始化, 并返回對象, 起始就是 對象建立的過程, 進(jìn)行了二次封裝而已
/*
如果想給系統(tǒng)的類新增構(gòu)造方法, 那么只能新增一個(gè)便利構(gòu)造方法
如果構(gòu)造方法是以 init 開頭, 那么該構(gòu)造方法是一個(gè)指定構(gòu)造方法
如果構(gòu)造器方法的 init 前面還有 convenience, 那么這個(gè)構(gòu)造方法 就是一個(gè) 遍歷構(gòu)造方法
指定構(gòu)造器和 便利構(gòu)造 區(qū)別:
指定構(gòu)造器:
必須初始化當(dāng)前類的所有屬性
便利構(gòu)造器:
不用初始化當(dāng)前類的所有屬性, 但是它依賴于當(dāng)前類中的其他構(gòu)造方法 -- >其他構(gòu)造方法已經(jīng) 進(jìn)行了類的初始化
在開發(fā)中, 不要隨便定義便利構(gòu)造器,只有需要提供一個(gè)方法快速
*/
convenience init(imageName: String , backgroudImageName: String){
self.init()
setImage(UIImage(named: imageName), forState: .Normal)
setImage(UIImage(named: imageName + "_highlighted"), forState: .Highlighted)
setBackgroundImage(UIImage(named: backgroudImageName), forState: .Normal)
setBackgroundImage(UIImage(named: backgroudImageName + "_highlighted"), forState: .Highlighted)
sizeToFit()
}
技能4. 命名空間的使用
對于Swift中不可以根據(jù)字符串來創(chuàng)建對應(yīng)的類, 必須借助于命名空間才可以創(chuàng)建對應(yīng)的類 其中格式有: "空間名稱"+"."+"類名" 并且確定類名必須存在才可.
當(dāng)然OC中可以直接創(chuàng)建. 因?yàn)镺C沒有空間命名這么一個(gè)概念, 所有文件之間沒有聯(lián)系, 只能通過 導(dǎo)入 import 才可以使用
但是Swift中, 在同一個(gè)project中處于相同的工作空間, 具有相同的命名空間,對于新創(chuàng)建的類, 必須確定其命名空間才可以使用
這個(gè)命名空間 一般就是 自己創(chuàng)建應(yīng)用的名稱
命名空間是哪一個(gè)那? 圖例說明:
代碼中的獲取:
// 1. 獲取當(dāng)前應(yīng)用程序的命名空間
// 在info 中 查詢 對應(yīng) "CFBundleExecutable"的值,取出, 這里使用 guard 是為了解包.
guard let nsp = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as? String else{
return
}
print(nsp)
獲取到 對應(yīng)的命名空間, 就可以 建立對應(yīng)的 類的對象了, 這里并不是簡單的獲取類名而已 , 由字符串創(chuàng)建對應(yīng)的類
// 注意: 在Swift中想通過字符串創(chuàng)建類, 必須加上命名空間
guard let cls: AnyClass = NSClassFromString(nsp + "." + (childControllerName ?? "")) else{
return
}
使用類創(chuàng)建對象, 必須先進(jìn)行類的對象, 說明類的類型, 方可使用,,, as
guard let clsType = cls as? UIViewController.Type else {
return
}
// 對于這種以類型 進(jìn)行創(chuàng)建的對象, 只能使用 init() 創(chuàng)建
let childController = clsType.init()
此時(shí), 已經(jīng)創(chuàng)建對應(yīng)類型的 控制器, 可以進(jìn)行使用了
技能5: 動態(tài)加載控制器. OC Swift 都可以使用
這里所用的思想, 就是 對于控制器的加載, 不能僅僅 依靠的固定的模式, 要將其統(tǒng)一到一個(gè)可以控制器的文件中 進(jìn)行加載, 這樣我們 只要通過改變文件, 就可以改變控制器的加載, 讓程序處于不同的展示. 對于這樣的情況, 我們可以讓程序 下載對應(yīng)的控制器文件, 然后根據(jù)文件 加載對應(yīng)的控制器, 這里我們需要考慮網(wǎng)速的問題, 但是, 如果沒有網(wǎng), 我們加載個(gè)屁
我們通過 plist文件進(jìn)行加載:
這里我不在重復(fù)說明plist文件中 JSON 數(shù)組的組成 , 對于Swift創(chuàng)建空文件,內(nèi)部進(jìn)行填充數(shù)據(jù)即可.
// 1.獲取JSON文件路徑
let path = NSBundle.mainBundle().pathForResource("MainVCSettings", ofType: "json")!
// 2.加載JSON數(shù)據(jù)
let data = NSData(contentsOfFile: path)!
// 3.序列號JSON數(shù)據(jù), 這里使用try? 來捕獲異常,發(fā)生異常返回null, 使用guard,來解包,沒有解包返回else
guard let objc = try? NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) else {
addChildViewController("HomeTableViewController", title: "首頁", imageName: "tabbar_home")
addChildViewController("MessageTableViewController", title: "消息", imageName: "tabbar_message_center")
addChildViewController("NullViewController", title: "", imageName: "")
addChildViewController("DiscoverTableViewController", title: "發(fā)現(xiàn)", imageName: "tabbar_discover")
addChildViewController("ProfileTableViewController", title: "我", imageName: "tabbar_profile")
return
}
// 4. 類型確認(rèn)
guard let array = objc as? [[String: AnyObject]] else {
return
}
// 遍歷 創(chuàng)建
for dict in array {
addChildViewController(dict["vcName"] as? String, title: dict["title"] as? String, imageName: dict["imageName"] as? String
}
技能6: 對于自定義控件中的問題 code
創(chuàng)建問題
這里需要說明, 對于初始化控件, 一般都是兩種方式: 1. 純代碼, 2. xib 或者SB創(chuàng)建.
required init?(coder aDecoder: NSCoder) {
// fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
setup()
}
上述方法中 注銷的語句,指的是致命錯誤方法,, 會直接導(dǎo)致應(yīng)用的崩潰的
因?yàn)樵赟wift中, 推薦要么使用純代碼,要么使用文件進(jìn)行創(chuàng)建
一旦我注銷掉, 就意味著, 兩種方式我都可以進(jìn)行創(chuàng)建的
技能7: 核心動畫的使用. CABaseAnimation
同OC用法一致, 先設(shè)置需要 改變的屬性:
animationWithKeyPath: ""
這里有多個(gè)屬性和一進(jìn)行選擇:
transform.scale = 比例轉(zhuǎn)換
transform.scale.x = 闊的比例轉(zhuǎn)換
transform.scale.y = 高的比例轉(zhuǎn)換
transform.rotation.z = 平面圖的旋轉(zhuǎn)
opacity = 透明度
margin
zPosition
backgroundColor 背景顏色
cornerRadius 圓角
borderWidth
bounds
contents
contentsRect
cornerRadius
frame
hidden
mask
masksToBounds
opacity
position
shadowColor
shadowOffset
shadowOpacity
shadowRadius
fromValue , 起始動畫位置
toVaue: 終止動畫位置
removedOnCompletion: 動畫完成后是否回到起始狀態(tài), 也有防止動畫中斷的意思在理面
duration: 動畫時(shí)長
repeatCount: 動畫重復(fù)次數(shù)
動畫創(chuàng)建完畢后就能加入圖層了
func startAnimation() {
// 1.創(chuàng)建動畫
let anim = CABasicAnimation(keyPath: "transform.rotation")
// 2.設(shè)置動畫屬性
anim.toValue = 2 * M_PI
anim.duration = 5.0
anim.repeatCount = MAXFLOAT
// 告訴系統(tǒng)不要自動移除動畫
anim.removedOnCompletion = false
// 3.將動畫添加到圖層
imageView.layer.addAnimation(anim, forKey: nil)
}
技能8: 對于分類的建立
對于OC中 , 有專門的分類建立, Category.
但是對于Swift中, 建立分類必須自己建立獨(dú)立文件, 自己填寫繼承
因?yàn)镾wift 是全局性的文件創(chuàng)建, 命名空間,只有加入特定詞匯 private, 才能是私有屬性, 所以這里的 分類,可以說是分類, 也可以說是繼承吧, 對于此種的方法, 同分類的使用方法是一樣的.
對于一些合并類屬性, 以及一些可以封裝類屬性, 皆可以用分類組成, 也可以用自定義組成.
對于分類 和 繼承, 一個(gè)重要的區(qū)別就是, 繼承是重寫已經(jīng)有的方法, 分類是為了添加沒有的方法
技能9: 對于Swift盡量使用SB, 不要使用xib
Swift 中 要求盡量使用sb 去 圖形化創(chuàng)建界面 而不要使用xib', 這點(diǎn)從 launch由以前的 xib到現(xiàn)在的 sb 就可以看得出來
這一點(diǎn)又有一些矛盾, 對于創(chuàng)建過程 , 先找xib 在進(jìn)行純碼創(chuàng)建