[英]How to write init methods of a UIViewController in Swift
我無法將 init 方法添加到以下 UIViewController 類。 我需要在 init 方法中編寫一些代碼。 我必須編寫 init(coder) 方法嗎? 即使我添加了編碼器和解碼器方法,我仍然會出錯。 我也嘗試使用不帶任何參數的 init 方法,但這似乎也不起作用。
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
...
...
}
如果我不帶參數調用 super.init() 方法,則錯誤是“必須調用超類的指定初始化程序”,如果我傳遞參數 nib 和 bundle,則錯誤是“必需的初始化程序 init(coder)”。
即使我添加 init(coder) 和 init(decoder) 它也不起作用。
我用了:
convenience init() {
self.init(nibName:nil, bundle:nil)
}
有人建議:
convenience init(){
self.init()
}
但這給了你一個無限循環。
所有這些答案都是一半的答案。 有些人在相關帖子中遇到了無限循環,因為他們只是添加了convenience init()
(如果您不提供獨特的init()
方法來調用它,它會遞歸調用自己),而其他人則忽略了擴展超類。 這種格式結合了所有的解決方案來完全滿足問題。
// This allows you to initialise your custom UIViewController without a nib or bundle.
convenience init() {
self.init(nibName:nil, bundle:nil)
}
// This extends the superclass.
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
// This is also necessary when extending the superclass.
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") // or see Roman Sausarnes's answer
}
編輯:另外,如果你想初始化使用傳遞給你的任何參數類的屬性convenience init()
方法,無需全部重寫init()
方法的抱怨,那么你可以設置所有這些屬性為隱含展開自選,這是一種模式通過使用蘋果自己。
您需要覆蓋init(nibName:bundle:)
初始化程序,並提供init(coder:)
所需的初始化程序,並在兩者中初始化tap
:
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
print("init nibName style")
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
// note slightly new syntax for 2017
required init?(coder aDecoder: NSCoder) {
print("init coder style")
super.init(coder: aDecoder)
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
...
...
}
另外,請確保在調用超類初始值設定項時不要只為nibName
和bundle
傳遞nil
。 你應該放棄傳遞的任何東西。
請注意,某些答案中提到的“convenience init”方法僅在您實際“手動”初始化視圖控制器時才相關。 (很少有您會這樣做的情況。)如果您想“在正常初始化期間做某事” -例如創建手勢識別器或僅初始化一些變量-唯一可能的解決方案正是此答案中給出的解決方案.
您可以只創建一個便利初始值設定項,便利初始值設定項不會覆蓋 init() 而只是調用它使事情變得更容易。
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
convenience init(){
self.init()
tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
}
}
我想你必須添加
required init(coder aDecoder: NSCoder) {
print("init coder")
super.init(coder: aDecoder)
}
或者
convenience init() {
self.init()
}
你也必須寫init。 不要刪除它
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nil, bundle: nil)
}
希望能幫助到你
我遇到了這個你問很久的問題。 但沒有人對這個問題給出基本的答案。 這是 Swift 中的一個基本原則:- 子類必須在其超類初始化完成之前初始化其變量。
因此,正如Ankit Goel提到的崩潰:-“必須調用超類的指定初始值設定項”
因此更新的代碼將是:-
class ViewController: UIViewController {
var tap: UITapGestureRecognizer?
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
print("init nibName style")
self.tap = nil
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:")))
}
required init?(coder aDecoder: NSCoder) {
print("init coder style")
self.tap = nil
super.init(coder: aDecoder)
tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:")))
}
}
我在 Xcode 12.0 中使用 Swift 5 時遇到了同樣的問題,這是我在 2020 年的解決方案。
class Foo: UIViewController {
private var bar: Bar!
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
setupController()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupController()
}
private func setupController() {
bar = Bar()
}
}
我使用的另一種方法是在loadView
函數中進行初始化。
class Foo: UIViewController {
private var bar: Bar!
override func loadView() {
setupController()
}
private func setupController() {
bar = Bar()
}
}
正確的流程是,調用指定的初始化程序,在這種情況下是帶有 nibName 的初始化程序,
init(tap: UITapGestureRecognizer)
{
// Initialise the variables
tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:")))
// Call the designated init of ViewController
super.init(nibName: nil, bundle: nil)
// Call your viewcontroller custom methods here
setupViewControllers()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.