source

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

lovecheck 2023. 4. 22. 09:43
반응형

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.storyboardvc1이라는 이름의 뷰 컨트롤러는 다음과 같이 인스턴스화됩니다.

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로 .ViewControllersStoryboardable.

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

반응형