Swift에서 UIViewController 하위 클래스의 사용자 지정 이니셜라이저를 만드는 방법은 무엇입니까?
이전에 질문을 받은 적이 있다면 죄송합니다. 주변을 많이 찾아봤는데 상황이 달랐던 이전 스위프트 베타에서 나온 답변이 많습니다.확실한 답을 찾을 수가 없는 것 같습니다.
서브클래스 하고싶습니다.UIViewController
코드로 쉽게 설정할 수 있도록 맞춤형 이니셜라이저를 가지고 있습니다.스위프트에서 이 일을 하는데 어려움을 겪고 있습니다.
나는.init()
내가 특정한 것을 통과하는데 사용할 수 있는 함수.NSURL
그러면 뷰 컨트롤러와 함께 사용하겠습니다.내 마음속에 그것은 어떤것처럼 보입니다.init(withImageURL: NSURL)
. 만약 내가 그 함수를 추가하면 그것은 나에게 그 함수를 추가하라고 요구합니다.init(coder: NSCoder)
기능.
슈퍼클래스에 표시되어 있기 때문이라고 생각합니다.required
키워드?그럼 서브클래스에서 해야 되는 건가요?추가합니다.
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
자 이제는 뭐죠?내 특별한 이니셜라이저는convenience
하나? 지정된 거?슈퍼 이니셜라이저를 불러야 하나요?같은 반의 이니셜라이저?
특수 이니셜라이저를 어떻게 추가할 수 있습니까?UIViewController
서브클래스?
class ViewController: UIViewController {
var imageURL: NSURL?
// this is a convenient way to create this view controller without a imageURL
convenience init() {
self.init(imageURL: nil)
}
init(imageURL: NSURL?) {
self.imageURL = imageURL
super.init(nibName: nil, bundle: nil)
}
// if this view controller is loaded from a storyboard, imageURL will be nil
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
UI를 코드로 작성하시는 분들께
class Your_ViewController : UIViewController {
let your_property : String
init(your_property: String) {
self.your_property = your_property
super.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) is not supported")
}
}
이것은 다른 대답들과 매우 비슷하지만 약간의 설명이 있습니다.승인된 답변은 해당 속성이 선택 사항이며 귀하의 답변에 대한 사실을 노출하지 않기 때문에 오해의 소지가 있습니다.init?(coder: NSCoder)
각각의 속성을 초기화해야 하며 이에 대한 유일한 해결책은fatalError()
. 궁극적으로 속성을 옵션으로 설정하면 벗어날 수 있지만 OP의 질문에 제대로 답하지는 못합니다.
// Think more of a OnlyNibOrProgrammatic_NOTStoryboardViewController
class ViewController: UIViewController {
let name: String
override func viewDidLoad() {
super.viewDidLoad()
}
// I don't have a nib. It's all through my code.
init(name: String) {
self.name = name
super.init(nibName: nil, bundle: nil)
}
// I have a nib. I'd like to use my nib and also initialze the `name` property
init(name: String, nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle? ) {
self.name = name
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
// when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
// The SYSTEM will never call this!
// it wants to call the required initializer!
init?(name: String, coder aDecoder: NSCoder) {
self.name = "name"
super.init(coder: aDecoder)
}
// when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
// The SYSTEM WILL call this!
// because this is its required initializer!
// but what are you going to do for your `name` property?!
// are you just going to do `self.name = "default Name" just to make it compile?!
// Since you can't do anything then it's just best to leave it as `fatalError()`
required init?(coder aDecoder: NSCoder) {
fatalError("I WILL NEVER instantiate through storyboard! It's impossible to initialize super.init?(coder aDecoder: NSCoder) with any other parameter")
}
}
기본적으로 스토리보드에서 로드하는 것을 포기해야 합니다. 왜죠?
왜냐하면 뷰컨트롤러를 호출할 때storyboard.instantiateViewController(withIdentifier: "viewController")
그러면 UIKit이 그 일을 하고 전화를 할 것입니다.
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
해당 호출을 다른 init 메서드로 리디렉션할 수 없습니다.
문서:
이 메서드를 사용하여 프로그래밍 방식으로 표시할 뷰 컨트롤러 개체를 만듭니다.이 메서드를 호출할 때마다 다음을 사용하여 뷰 컨트롤러의 새 인스턴스를 만듭니다.
init(coder:)
방법.
그러나 프로그래밍 방식으로 작성된 viewController 또는 nib으로 작성된 viewController의 경우 위와 같이 해당 호출을 리디렉션할 수 있습니다.
편의 이니셜라이저는 보조적인 것으로 클래스의 이니셜라이저를 지원합니다.지정된 이니셜라이저의 일부 매개변수가 기본값으로 설정된 상태에서 편의 이니셜라이저와 동일한 클래스에서 지정된 이니셜라이저를 호출하도록 편의 이니셜라이저를 정의할 수 있습니다.편의 이니셜라이저를 정의하여 특정 사용 사례 또는 입력 값 유형에 대해 해당 클래스의 인스턴스를 생성할 수도 있습니다.
여기에 문서화되어 있습니다.
예를 들어 팝오버에 사용자 지정 init가 필요한 경우 다음 방법을 사용할 수 있습니다.
nibName 및 번들과 함께 super init을 사용하는 사용자 지정 init를 만든 후 뷰 속성에 액세스하여 뷰 계층의 로드를 강제로 수행합니다.
그런 다음 viewDidLoad 기능에서 초기화 시 전달된 파라미터로 뷰를 구성할 수 있습니다.
import UIKit
struct Player {
let name: String
let age: Int
}
class VC: UIViewController {
@IBOutlet weak var playerName: UILabel!
let player: Player
init(player: Player) {
self.player = player
super.init(nibName: "VC", bundle: Bundle.main)
if let view = view, view.isHidden {}
}
override func viewDidLoad() {
super.viewDidLoad()
configure()
}
func configure() {
playerName.text = player.name + "\(player.age)"
}
}
func showPlayerVC() {
let foo = Player(name: "bar", age: 666)
let vc = VC(player: foo)
present(vc, animated: true, completion: nil)
}
언급URL : https://stackoverflow.com/questions/26923003/how-do-i-make-a-custom-initializer-for-a-uiviewcontroller-subclass-in-swift
'programing' 카테고리의 다른 글
PowerShell에서 XML용 하위 요소를 추가하는 방법 (0) | 2023.11.05 |
---|---|
ForEach-Object - Parallel에서 사용자 지정 함수를 전달하는 방법 (0) | 2023.11.05 |
Javascript/Angular JS에서 반올림하는 방법 -- 그러나 중요하지 않은 숫자를 제거하는 방법 (0) | 2023.11.05 |
$(이것은) AJAX 성공 내부에서 작동하지 않음 (0) | 2023.11.05 |
MariaDB Community Server 10.5 Alpha의 MariaDB Columnstore 1.4 (0) | 2023.11.05 |