Swift에서 viewController 인스턴스화 및 표시
쟁점.
그래서 제가 한번 살펴봤는데요.Swift Programming Language
, 그리고 어쩐지, 나는 의 초기화를 올바르게 입력할 수 없다.UIViewController
특정 항목에서UIStoryboard
.
인Objective-C
간단히 말하면 다음과 같습니다.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"StoryboardName" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"ViewControllerID"];
[self presentViewController:viewController animated:YES completion:nil];
Swift에서 어떻게 이걸 할 수 있는지 누가 도와줄 수 있나요?
이 답변은 Swift 5.4 및 iOS 14.5 SDK에서 마지막으로 수정되었습니다.
이것은 모두 새로운 구문과 약간 수정된 API의 문제입니다.UIKit의 기본 기능은 변경되지 않았습니다.이는 대부분의 iOS SDK 프레임워크에 해당됩니다.
let storyboard = UIStoryboard(name: "myStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "myVCID")
self.present(vc, animated: true)
반드시 설정해 주세요.myVCID
"Storyboard ID" 아래에 있는 스토리보드 안에 있습니다.
@akashivsky의 답변을 인스턴스화하기 위해 사용하는 사용자용UIViewController
다음과 같은 예외가 있습니다.
치명적 오류: 클래스에 구현되지 않은 이니셜라이저 'init(코더:)' 사용
간단한 힌트:
수동 실장required init?(coder aDecoder: NSCoder)
목적지에UIViewController
이 모든 것을 인스턴스화하려고 하는 것
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
자세한 것은, 이쪽의 답변을 참조해 주세요.
신속:
let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)
목표 C
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"];
이 링크에는 동일한 스토리보드에서 뷰 컨트롤러를 시작하는 코드가 있습니다.
/*
Helper to Switch the View based on StoryBoard
@param StoryBoard ID as String
*/
func switchToViewController(identifier: String) {
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(identifier) as! UIViewController
self.navigationController?.setViewControllers([viewController], animated: false)
}
akashivskyy의 대답은 잘 들어맞는다!그러나 표시된 뷰 컨트롤러에서 복귀하는 데 문제가 있는 경우 이 대체 방법이 도움이 될 수 있습니다.나한텐 효과가 있었어!
신속:
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
// Alternative way to present the new view controller
self.navigationController?.showViewController(vc, sender: nil)
Obj-C:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
[self.navigationController showViewController:vc sender:nil];
Swift 4.2 업데이트 코드는
let storyboard = UIStoryboard(name: "StoryboardNameHere", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.present(controller, animated: true, completion: nil)
// "Main" is name of .storybord file "
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// "MiniGameView" is the ID given to the ViewController in the interfacebuilder
// MiniGameViewController is the CLASS name of the ViewController.swift file acosiated to the ViewController
var setViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MiniGameView") as MiniGameViewController
var rootViewController = self.window!.rootViewController
rootViewController?.presentViewController(setViewController, animated: false, completion: nil)
AppDelegate에 넣었을 때 잘 작동했습니다.
모듈식으로 표현하려면 다음과 같은 것이 필요합니다.
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)
저는 좀 더 깨끗한 방법을 제안하고 싶습니다.스토리보드가 여러 개 있을 때 유용합니다.
1. 모든 스토리보드를 사용하여 구조를 만듭니다.
struct Storyboard {
static let main = "Main"
static let login = "login"
static let profile = "profile"
static let home = "home"
}
2. 이렇게 UIStoryboard 확장을 만듭니다.
extension UIStoryboard {
@nonobjc class var main: UIStoryboard {
return UIStoryboard(name: Storyboard.main, bundle: nil)
}
@nonobjc class var journey: UIStoryboard {
return UIStoryboard(name: Storyboard.login, bundle: nil)
}
@nonobjc class var quiz: UIStoryboard {
return UIStoryboard(name: Storyboard.profile, bundle: nil)
}
@nonobjc class var home: UIStoryboard {
return UIStoryboard(name: Storyboard.home, bundle: nil)
}
}
스토리보드 식별자를 클래스 이름으로 지정하고 다음 코드를 사용하여 인스턴스화합니다.
let loginVc = UIStoryboard.login.instantiateViewController(withIdentifier: "\(LoginViewController.self)") as! LoginViewController
아무리 노력해도 잘 되지 않습니다.오류도 없고, 화면에 새로운 뷰 컨트롤러도 표시되지 않습니다.이유는 알 수 없지만 타임아웃 함수로 마무리하여 작동하게 되었습니다.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.0) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "TabletViewController")
self.present(controller, animated: true, completion: nil)
}
스위프트 3
let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {
})
Swift 4:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
스토리보드/Xib를 사용하지 않는 View컨트롤러가 있는 경우 다음과 같이 특정 VC에 푸시할 수 있습니다.
let vcInstance : UIViewController = yourViewController()
self.present(vcInstance, animated: true, completion: nil)
오래된 스레드인 것은 알지만 현재 솔루션(특정 뷰 컨트롤러에 하드코드 문자열 식별자를 사용)은 오류가 발생하기 쉽다고 생각합니다.
빌드 타임 스크립트(여기서 액세스 가능)를 작성했습니다.이 스크립트는 특정 프로젝트 내의 모든 스토리보드에서 뷰 컨트롤러에 액세스하여 인스턴스화하는 안전한 컴파일러 방법을 만듭니다.
예를 들어 Main.storyboard의 vc1이라는 이름의 뷰 컨트롤러는 다음과 같이 인스턴스화됩니다.
let vc: UIViewController = R.storyboard.Main.vc1^ // where the '^' character initialize the controller
스위프트 5
let vc = self.storyboard!.instantiateViewController(withIdentifier: "CVIdentifier")
self.present(vc, animated: true, completion: nil)
보다 나은 구문과 함께 이 문제를 보다 쉽게 처리할 수 있는 라이브러리를 만들었습니다.
https://github.com/Jasperav/Storyboardable
Storyboard하여 Storyboard.swift로 .ViewControllers
Storyboardable
.
guard let vc = storyboard?.instantiateViewController(withIdentifier: "add") else { return }
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)
if let destinationVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DestinationVC") as? DestinationVC{
let nav = self.navigationController
//presenting
nav?.present(destinationVC, animated: true, completion: {
})
//push
nav?.pushViewController(destinationVC, animated: true)
}
다음 도우미를 사용합니다.
struct Storyboard<T: UIViewController> {
static var storyboardName: String {
return String(describing: T.self)
}
static var viewController: T {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let vc = storyboard.instantiateViewController(withIdentifier: Self.storyboardName) as? T else {
fatalError("Could not get controller from Storyboard: \(Self.storyboardName)")
}
return vc
}
}
사용방법(스토리보드 ID는 UIViewController 클래스 이름과 일치해야 합니다)
let myVC = Storyboard.viewController as MyViewController
언급URL : https://stackoverflow.com/questions/24035984/instantiate-and-present-a-viewcontroller-in-swift
'source' 카테고리의 다른 글
Azure 함수에서 설정 읽기 (0) | 2023.04.22 |
---|---|
WPF의 디자인 타임 전용 배경색? (0) | 2023.04.22 |
- SelectRowAtIndexPath: 호출되지 않음 (0) | 2023.04.22 |
원래 GitHub 저장소에서 분기된 GitHub 저장소로 새 업데이트를 가져옵니다. (0) | 2023.04.22 |
지정된 이름의 도커 컨테이너가 존재하지 않는 경우에만 Bash 명령을 실행하는 방법 (0) | 2023.04.22 |