수업에서 프로그래밍 방식으로 스토리 보드를로드하는 방법은 무엇입니까?


183

내 문제는 스토리 보드xib를 모두 사용할 방법을 찾고 있다는 것 입니다. 그러나 프로그래밍 방식으로 스토리 보드를로드하고 표시하는 적절한 방법을 찾을 수 없습니다. 프로젝트는 xib로 개발되기 시작했으며 이제 모든 xib 파일을 스토리 보드에 중첩시키기가 매우 어렵습니다. 그래서 alloc, init, pushviewControllers 와 같이 코드에서 수행하는 방법을 찾고있었습니다 . 필자의 경우 스토리 보드에 컨트롤러가 하나 UITableViewController있습니다.이 컨텐츠에는 정적 셀이 있습니다. 큰 리팩토링없이 xib와 스토리 보드로 작업하는 적절한 방법을 알고 있다면 도움을 주셔서 감사합니다.

답변:


370

스토리 보드에서 속성 관리자로 이동하여 뷰 컨트롤러의 식별자를 설정하십시오. 그런 다음 다음 코드를 사용하여 해당 뷰 컨트롤러를 제시 할 수 있습니다.

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:@"myViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

65
[sb instantiateInitialViewController]장면의 기본 뷰 컨트롤러에서 시작하려는 경우에 편리합니다.
drewish 2012 년

제임스, 감사합니다! 스토리 보드의 뷰를 인스턴스화하는 방법을 알아 내려고 꽤 오랫동안 검색했습니다. 귀하의 답변 (및 kokoko의 질문)은 가장 상쾌합니다.
bejonbee

James Beith의 코드에서 UIViewControler * vc를 현재 뷰 컨트롤러와 앞뒤로 전환하면 재사용해야합니다. 사용자가 새보기에서 버튼을 누를 때까지 vc가 붙어서 스토리 보드 펜촉에 연결되는 어려운 방법을 발견했으며 이제이 코드의 이전 주문에서 버려진 vc와 함께 메모리 누수가 발생합니다.
SWoo

11
누구든지 앱 대리자 에서이 작업을 수행하는 방법을 알고 싶다면 [self presentViewcontroller]1) self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];2) self.window.rootViewController = vc;및 3) 순서대로 논리를 이러한 줄로 바꿉니다 [self.window makeKeyAndVisible];. modalTransitionStyle앱 대리자의 모달 전환이 아니기 때문에 줄을 제거 할 수도 있습니다 .
lewiguez

참고로, 새로운 스토리 보드를 모달 팝업 대신 "푸시"하려면 chaithraVeeresh의 답변을보십시오.
Adam Johns

76

스위프트 3

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "viewController")
self.navigationController!.pushViewController(vc, animated: true)

스위프트 2

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController")
self.navigationController!.pushViewController(vc, animated: true)

전제 조건

스토리 보드 ID 를 뷰 컨트롤러에 할당하십시오 .

스토리 보드 ID

IB> 자격 증명 관리자 표시> 자격 증명> 스토리 보드 ID

스위프트 (레거시)

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController") as? UIViewController
self.navigationController!.pushViewController(vc!, animated: true)

편집 : Swift 2는 Fred A 의 의견에서 제안했습니다 .

navigationController없이 사용하려면 다음과 같이 사용해야합니다.

    let Storyboard  = UIStoryboard(name: "Main", bundle: nil)
    let vc = Storyboard.instantiateViewController(withIdentifier: "viewController")
    present(vc , animated: true , completion: nil)

1
Swift 2에서는 "as? UIViewController"를 추가 할 필요가 없습니다. 컴파일러가 자동으로 결정합니다.
Frédéric Adda

2
또는 self.storyboardline1 & 2를 수행 하고 병합 할 수 있습니다
Honey

17

속성 관리자에서 해당 뷰 컨트롤러의 식별자를 제공하면 아래 코드가 작동합니다.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
DetailViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];

5

이 시도

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"Login"];

[[UIApplication sharedApplication].keyWindow setRootViewController:vc];

다른 답변과 같이 UINavigationController를 사용하지 않는 경우 이것을 사용하십시오.
latenitecoder

2

신속한
NavigationControllerpushController에서 대체 할 수 있습니다

present(vc, animated:true , completion: nil)

1

대한 신속한 3, 4 , 당신은이 작업을 수행 할 수 있습니다. 모범 사례는 Storyboard의 이름을 StoryboardID와 동일하게 설정하는 것입니다.

enum StoryBoardName{
   case second = "SecondViewController"
}
extension UIStoryBoard{
   class func load(_ storyboard: StoryBoardName) -> UIViewController{
      return UIStoryboard(name: storyboard.rawValue, bundle: nil).instantiateViewController(withIdentifier: storyboard.rawValue)
   }
}

그런 다음 스토리 보드를 ViewController에 다음과 같이로드 할 수 있습니다.

class MyViewController: UIViewController{
     override func viewDidLoad() {
        super.viewDidLoad()
        guard let vc = UIStoryboard.load(.second) as? SecondViewController else {return}
        self.present(vc, animated: true, completion: nil)
     }

}

새 스토리 보드를 만들 때 StoryboardID에 동일한 이름을 설정하고 열거 형 " StoryBoardName " 에 스토리 보드 이름을 추가하십시오.


0

항상 루트 컨트롤러로 바로 이동할 수 있습니다.

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

0

아래 확장은 a를로드 할 수 Storyboard있으며 관련이 UIViewController있습니다. 예 :이 경우 UIViewController이름 ModalAlertViewController과 스토리 보드는 "ModalAlert"라는 예를 들어,

let vc: ModalAlertViewController = UIViewController.loadStoryboard("ModalAlert")

모두를로드 StoryboardUIViewControllervc유형이 될 것입니다 ModalAlertViewController. 참고 스토리 보드의 스토리 보드 ID는 스토리 보드와 이름이 같으며 스토리 보드 는 초기보기 컨트롤러 로 표시되어 있다고 가정합니다 .

extension UIViewController {
    /// Loads a `UIViewController` of type `T` with storyboard. Assumes that the storyboards Storyboard ID has the same name as the storyboard and that the storyboard has been marked as Is Initial View Controller.
    /// - Parameter storyboardName: Name of the storyboard without .xib/nib suffix.
    static func loadStoryboard<T: UIViewController>(_ storyboardName: String) -> T? {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        if let vc = storyboard.instantiateViewController(withIdentifier: storyboardName) as? T {
            vc.loadViewIfNeeded() // ensures vc.view is loaded before returning
            return vc
        }
        return nil
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.