Swift에서 viewController 인스턴스화 및 표시


299

발행물

에 대한 새로운 내용 Swift을 살펴보기 시작했으며 Xcode 6데모 프로젝트 및 자습서를 시도했습니다. 이제 나는 붙어있다 :

viewController특정 스토리 보드에서 인스턴스화 및 발표

오브젝티브 -C 솔루션

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];

스위프트에서 이것을 달성하는 방법?

답변:


647

이 답변은 Swift 5.2 및 iOS 13.4 SDK 용으로 마지막으로 개정되었습니다.


그것은 모두 새로운 구문과 약간 수정 된 API의 문제입니다. UIKit의 기본 기능은 변경되지 않았습니다. 이것은 대다수의 iOS SDK 프레임 워크에 해당됩니다.

let storyboard = UIStoryboard(name: "myStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "myVCID")
self.present(vc, animated: true)

에 문제가있는 경우 EridB의 답변을init(coder:) 참조하십시오 .


3
당신은 심지어 생략 할 수 있습니다 ;! ;)에 대해 자세히 설명해 주시겠습니까 as UIViewController? 왜 필요한가요?
Sebastian Wramba

5
as키워드는 유형 변환에 사용됩니다. (UIViewController *)anObject목표 c 와 동일합니다
Garoal

1
그래, 나는 그것들을 생략 할 수 있다는 것을 알고 있지만 그것은 긴 습관의 일부입니다. : D instantiateViewControllerWithIdentifier리턴으로 AnyObject( idSwift와 동일)로 선언 vc하고 UIViewController로 타입 캐스트 AnyObject해야 UIViewController합니다.
akashivskyy 2016 년

안녕하세요 친구, 나는 다른 문제에 직면하고 있습니다.이 코드는 iOS v7.1.2가있는 ipad2가 아닌 시뮬레이터에서 실행됩니다. 마음에 들지 않으면이 문제를 해결하도록 도와주세요.
Indra

3
@akashivskyy 가장 확실하게 당신에게. 그러나 어쩌면 일부에게는 그렇지 않을 수도 있습니다.
mmc

43

@akashivskyy의 답변 을 사용하여 인스턴스화 UIViewController하고 예외가있는 사람들의 경우 :

치명적인 오류 : 클래스에 구현되지 않은 초기화 프로그램 'init (coder :)'사용

빠른 팁 :

인스턴스화하려는 required init?(coder aDecoder: NSCoder)대상에서 수동으로 구현UIViewController

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

더 자세한 설명이 필요하면 여기 에서 내 대답을 참조 하십시오


커스텀 이니시에이터를 사용하려면 super.init (nibName : nil, bundle : nil)로 super를 호출하면 whew가 제대로로드되거나 NIB 파일 이름으로 호출됩니다.
user1700737

4
@ user1700737 initWithNib가 아닌 initWithCoder를 실행하는 스토리 보드를 참조하여 viewController를 인스턴스화하고 있습니다. 이 질문을 참조하십시오. stackoverflow.com/questions/24036393/…
E-Riddie

안녕하세요 친구, 나는 다른 문제에 직면하고 있습니다.이 코드는 iOS v7.1.2가있는 ipad2가 아닌 시뮬레이터에서 실행됩니다. 마음에 들지 않으면이 문제를 해결하도록 도와주세요.
Indra

@ Indra 당신은 스택에 다른 질문을해야합니다, 나에게 당신을 도울 수있는 링크를 줘!
E-Riddie

Swift 1.2에서는 init(coder aDecoder: NSCoder!)"필수"로 만들어야 합니다. 이제 다음을 작성해야합니다.required init(coder aDecoder: NSCoder!)
Eduardo Viegas

18

이 링크에는 두 가지 구현이 있습니다.

빠른:

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)

}

15

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];

12

스위프트 4.2 업데이트 코드는

let storyboard = UIStoryboard(name: "StoryboardNameHere", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.present(controller, animated: true, completion: nil)

7
// "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에 넣을 때 잘 작동했습니다.


7

모달로 발표하려면 다음과 같은 것이 있어야합니다.

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)

5

훨씬 더 깨끗한 방법을 제안하고 싶습니다. 스토리 보드가 여러 개인 경우 유용합니다.

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

@nonobjc는 무엇입니까?
StackRunner

1
@StackRunner 이것은 목표 c에서 사용할 수 없습니다
XcodeNOOB

3

스위프트 4 :

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC

2

스토리 보드 / Xib를 사용하지 않는 Viewcontroller가있는 경우 아래 호출과 같이이 특정 VC로 푸시 할 수 있습니다.

 let vcInstance : UIViewController   = yourViewController()
 self.present(vcInstance, animated: true, completion: nil)

"액세스 가능한 이니셜 라이저가 없기 때문에 구성 할 수 없습니다"라는 메시지가 나타납니다.
Paul Bénéteau

스토리 보드에 의해 만들어진 아울렛과 다른 관계는 없어졌습니다
jose920405

2

스위프트 3 스토리 보드

let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {

})

1

나는 그것이 오래된 스레드라는 것을 알고 있지만 현재 솔루션 (주어진 뷰 컨트롤러에 대해 하드 코딩 된 문자열 식별자를 사용)은 오류가 발생하기 쉽다고 생각합니다.

빌드 타임 스크립트 ( 여기서 액세스수 있음 )를 만들었습니다.이 스크립트 는 주어진 프로젝트 내의 모든 스토리 보드에서 뷰 컨트롤러에 액세스하고 인스턴스화하기위한 컴파일러 안전한 방법을 만듭니다.

예를 들어 Main.storyboard 에서 vc1 이라는 뷰 컨트롤러 는 다음과 같이 인스턴스화됩니다.

let vc: UIViewController = R.storyboard.Main.vc1^  // where the '^' character initialize the controller

1

내가 시도한 것이 무엇이든, 그것은 나를 위해 작동하지 않을 것입니다-오류가 없지만 화면에 새로운보기 컨트롤러가 없습니다. 이유를 모르지만 시간 초과 기능으로 래핑하면 마침내 작동합니다.

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)
}

1

스위프트 5

let vc = self.storyboard!.instantiateViewController(withIdentifier: "CVIdentifier")
self.present(vc, animated: true, completion: nil)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.