Xcode12模板位置:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/iOS/Source/Cocoa Touch Class.xctemplate
1汗侵、設置導航欄為透明
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.isTranslucent = true
2间雀、bridging-header是swift剛出的時候,官方提供一種混編的方式『鳎現在cocoapods 的版本已經支持swift 了宰睡,當你在安裝pods的時候,添加下面這句話.
# Uncomment this line if you're using Swift
use_frameworks!
它在cocoa pods中已經對Swift進行了配置气筋,所以可以直接使用,不需要創(chuàng)建bridging-header拆内。
推薦swift項目學習:
U17
LBXMLYFM-Swift
3、必要構造器
我們可以通過required關鍵字來實現必要構造器宠默,子類必須實現父類的必要構造器麸恍。
class Animal {
var name: String
required init(name: String) {
self.name = name
}
}
class Dog: Animal {
var foot: Int
//在重寫父類必要構造器的時候不需要加override
required init(name: String) {
foot = 4
super.init(name: name)
}
}
Dog(name: "dog")
有一點需要注意的就是:如果子類繼承的構造器能滿足必要構造器的要求,則無須在子類中顯式提供必要構造器的實現搀矫。
class Animal {
var name: String
required init(name: String) {
self.name = name
}
}
class Dog: Animal {
var foot = 2
}
Dog(name: "dog")
在我們日常開發(fā)中抹沪,我們會經常自定義UITableViewCell的子類來實現我們定制化的需求刻肄,如果我們沒有實現required init?(coder aDecoder: NSCoder)方法的話,我們的代碼是編譯報錯的采够。查看文檔我們發(fā)現該方法為NSCoding的方法肄方,且該方法為UIView 必要構造器冰垄,所以它的子類必須實現該方法蹬癌。
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
4、訪問級別
Swift 為代碼中的實體提供了五種不同的訪問級別虹茶。這些訪問級別不僅與源文件中定義的實體相關逝薪,同時也與源文件所屬的模塊相關。
open 和 public 級別可以讓實體被同一模塊源文件中的所有實體訪問蝴罪,在模塊外也可以通過導入該模塊來訪問源文件里的所有實體董济。通常情況下,你會使用 open 或 public 級別來指定框架的外部接口要门。open 和 public 的區(qū)別在后面會提到虏肾。
internal 級別讓實體被同一模塊源文件中的任何實體訪問,但是不能被模塊外的實體訪問欢搜。通常情況下封豪,如果某個接口只在應用程序或框架內部使用,就可以將其設置為 internal 級別炒瘟。
fileprivate 限制實體只能在其定義的文件內部訪問吹埠。如果功能的部分實現細節(jié)只需要在文件內使用時,可以使用 fileprivate 來將其隱藏疮装。
private 限制實體只能在其定義的作用域缘琅,以及同一文件內的 extension 訪問。如果功能的部分細節(jié)只需要在當前作用域內使用時廓推,可以使用 private 來將其隱藏刷袍。
open 為最高訪問級別(限制最少),private 為最低訪問級別(限制最多)樊展。
open 只能作用于類和類的成員做个,它和 public 的區(qū)別主要在于 open 限定的類和成員能夠在模塊外能被繼承和重寫,在下面的 子類 這一節(jié)中有詳解滚局。將類的訪問級別顯示指定為 open
表明你已經設計好了類的代碼居暖,并且充分考慮過這個類在其他模塊中用作父類時的影響。
5藤肢、pod不重新安裝已有的庫
pod install --no-repo-update
6太闺、swift 閉包 循環(huán)引用
參考鏈接:
Swift閉包循環(huán)引用
Swift與OC真正去理解Block解決循環(huán)引用的技巧
7、Swift 5.1 - 字符串
Swift 5.1 (3) - 字符串
iOS Swift中String的常用操作以及數據轉化
8嘁圈、tableView.deselectRow(at: indexPath, animated: true) 注意事項
這里不單單取消選中省骂,還會把cell所有的子控件設置為選中或者高亮
9蟀淮、VC的便利構造方法
convenience init(type: ContentType) {
// 便利構造函數中 一定不會有super 對于屬性的賦值 一般在self.init()之后 只有self被初始化后,才能對其進行賦值, 不能使用let修飾屬性 var 并且告訴編譯器其強制解包 一定有值
self.init()
self.type = type
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
10、實現TableView下拉關閉
let cv:CGFloat = -150 //下拉關閉數值
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = tableView.contentOffset.y;
print(message: offset)
if (offset < cv) {
close()
}
}
11钞澳、關于UILabel設置AttributedString以后末尾...不出現的問題
需要重新設置一次label的lineBreakMode屬性
editLabel.attributedText = PublicTools.load_attributedString(model.editor_note.trimmingCharacters(in: .newlines), font: FMFont13, color: CFontColor8, alignment: .left, lineSpacing: kLabelSpace)
editLabel.lineBreakMode = .byTruncatingTail
12怠惶、當兩個UILabel并排顯示時,如何設置約束轧粟,讓A或者B能顯示你想要的需求策治,就需要用到下面兩個約束
ContentHuggingPriority ==> 表示當前的Label的內容不想被拉伸
playCountLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 1000), for: .vertical)
ContentCompressionResistancePriority ==> 表示當前的Label的內容不想被收縮
playCountLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000), for: .horizontal)
默認情況下: HuggingPriority == 250, CompressionResistancePriority == 750
12、@discardableResult的作用
在Swift中兰吟,當有返回值的方法未得到接收和使用時通常會出現警告
在正式編譯中不會影響編譯結果通惫,但是也妨礙代碼的美觀整潔,在方法上加上“@discardableResult”就可以取消這個警告
@discardableResult
public func handleUrl(url: String, completion:
還有一種取消警告的方法混蔼,不加@discardableResult直接加通配符接收方法返回值
_ = XX
13履腋、dynamic關鍵字
如果您有過OC的開發(fā)經驗,那一定會對OC中@dynamic關鍵字比較熟悉惭嚣,它告訴編譯器不要為屬性合成getter和setter方法遵湖。
Swift中也有dynamic關鍵字,它可以用于修飾變量或函數晚吞,它的意思也與OC完全不同延旧。它告訴編譯器使用動態(tài)分發(fā)而不是靜態(tài)分發(fā)。OC區(qū)別于其他語言的一個特點在于它的動態(tài)性载矿,任何方法調用實際上都是消息分發(fā)垄潮,而Swift則盡可能做到靜態(tài)分發(fā)。
因此闷盔,標記為dynamic的變量/函數會隱式的加上@objc關鍵字弯洗,它會使用OC的runtime機制。
雖然靜態(tài)分發(fā)在效率上可能更好逢勾,不過一些app分析統計的庫需要依賴動態(tài)分發(fā)的特性牡整,動態(tài)的添加一些統計代碼,這一點在Swift的靜態(tài)分發(fā)機制下很難完成溺拱。這種情況下逃贝,雖然使用dynamic關鍵字會犧牲因為使用靜態(tài)分發(fā)而獲得的一些性能優(yōu)化,但也依然是值得的迫摔。
使用動態(tài)分發(fā)沐扳,您可以更好的與OC中runtime的一些特性(如CoreData,KVC/KVO)進行交互句占,不過如果您不能確定變量或函數會被動態(tài)的修改沪摄、添加或使用了Method-Swizzle,那么就不應該使用dynamic關鍵字,否則有可能程序崩潰杨拐。