프로그래밍 방식으로 segue 만들기


202

나는 UIViewController모든 UIViewsControllers공통된 작업을 재사용하기 위해 확장한다는 공통점이 있습니다.

나는이 "공통"에 UIViewController대해 다른 모든 것이 UIViewControllers상속 되도록 세구를 설정하고 싶다 .

프로그래밍 방식으로 어떻게해야합니까?

질문은 스토리 보드에 가지 않고 손으로 직접하지 않고 어떻게 segue모두를 위해 어떻게 설정할 수있을 것 같아요 UIViewControllers.

답변:


169

정의상 segue는 스토리 보드와 독립적으로 존재할 수 없습니다. 클래스 이름에도 있습니다 UIStoryboardSegue. 프로그래밍 방식으로 segue를 만들지 마십시오. 스토리 보드 런타임이 만들어집니다. 일반적으로 performSegueWithIdentifier:뷰 컨트롤러의 코드를 호출 할 수 있지만 스토리 보드에 이미 참조 용 segue가 설정되어 있어야합니다.

내가 생각하는 것은 공통 뷰 컨트롤러 (기본 클래스)에서 새 뷰 컨트롤러로 전환하고 모든 파생 클래스에서 상속되는 메서드를 만드는 방법입니다. 기본 클래스 뷰 컨트롤러에 이와 같은 메소드를 작성하여이를 수행 할 수 있습니다.

- (IBAction)pushMyNewViewController
{
    MyNewViewController *myNewVC = [[MyNewViewController alloc] init];

    // do any setup you need for myNewVC

    [self presentModalViewController:myNewVC animated:YES];
}

그런 다음 파생 클래스에서 적절한 버튼을 클릭하거나 테이블 행을 선택하거나 그 밖의 것을 선택하면 해당 메소드를 호출하십시오.


4
감사. 프로그래밍 방식으로는 불가능한 일입니다. 소스 코드의 품질을 높이는 데 도움이됩니다. 나는 당신의 제안과 함께 갈 것입니다.
Tiago Veloso

2
@ jonkroll 스위치 스위치에서 segue를 호출 / 수행 할 수 있습니까? 즉, 내가 가지고있는 인덱스를 기반으로합니까?
codejunkie

5
@ codejunkie : 예, 그렇게 할 수 있습니다. 이를 위해 UIViewController명명 된 방법 을 사용합니다 performSegueWithIdentifier:sender:.
jonkroll

2
나는 프로그래밍 방식으로 segue를 만들고 공연했습니다 (내 답변 참조). 내 코드에 문제가 있다면 대답이 맞다면?
Jean-Philippe Pellet

13
iOS 6+ 용 업데이트 : UIView의 사용 presentModalViewController:animated:이 중단되었습니다. 로부터 문서 - (. 아이폰 OS 6.0에서 사용 presentViewController을 추천하지 않습니다 : 애니메이션 : 완료 :. 대신)
사용자

346

나는 또 다른 가능성을 추가 할 것이라고 생각했다. 수행 할 수있는 작업 중 하나는 액션에 연결되지 않은 segue를 사용하여 스토리 보드에서 두 장면을 연결 한 다음 뷰 컨트롤러 내에서 segue를 프로그래밍 방식으로 트리거 할 수 있다는 것입니다. 이렇게하는 방법은 스토리 장면의 맨 아래에있는 파일의 소유자 아이콘에서 segueing scene 인 드래그하여 대상 장면으로 마우스를 끌어 야한다는 것입니다. 설명을 돕기 위해 이미지를 던질 것입니다.

여기에 이미지 설명을 입력하십시오

"Manual Segue"팝업이 나타납니다. 유형으로 푸시를 선택했습니다. 작은 사각형을 탭하고 속성 관리자에 있는지 확인하십시오. 코드에서 참조 할 때 사용할 식별자를 제공하십시오.

여기에 이미지 설명을 입력하십시오

좋아, 다음은 프로그래밍 방식의 바 버튼 항목을 사용하여 정리하겠습니다. viewDidLoad 또는 다른 곳에서 탐색 코드에 다음 코드를 사용하여 버튼 항목을 만듭니다.

UIBarButtonItem *buttonizeButton = [[UIBarButtonItem alloc] initWithTitle:@"Buttonize"
                                                                    style:UIBarButtonItemStyleDone
                                                                   target:self
                                                                   action:@selector(buttonizeButtonTap:)];
self.navigationItem.rightBarButtonItems = @[buttonizeButton];

좋아, 선택기는 buttonizeButtonTap :입니다. 따라서 해당 버튼에 대해 void 메소드를 작성하고 해당 메소드 내에서 다음과 같이 segue를 호출합니다.

-(void)buttonizeButtonTap:(id)sender{
    [self performSegueWithIdentifier:@"Associate" sender:sender];
    }

prepareForSegue가 호출 될 때 버튼을 식별하려면 sender 매개 변수가 필요합니다. PreparingForSegue는 장면을 인스턴스화하고 작업에 필요한 값을 전달하는 프레임 워크 방법입니다. 내 방법은 다음과 같습니다.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"Associate"])
    {
        TranslationQuizAssociateVC *translationQuizAssociateVC = [segue destinationViewController];
        translationQuizAssociateVC.nodeID = self.nodeID; //--pass nodeID from ViewNodeViewController
        translationQuizAssociateVC.contentID = self.contentID;
        translationQuizAssociateVC.index = self.index;
        translationQuizAssociateVC.content = self.content;
    }
}

좋아, 방금 테스트했고 작동합니다. 그것이 당신을 돕기를 바랍니다.


@MichaelRowe 이것이 어떻게 segue가 필요하지 않습니까? 내가 보는 것처럼 여전히 스토리 보드에서 대상 컨트롤러로
끌어다 놓아야합니다

@MichaelRowe 이것은 segues의 필요성을 제거하지 않습니다. 이것이하는 일은 인터페이스 빌더 대신 코드로 작성된 뷰 컨트롤러 간을 연결하는 것입니다.
Matthew

@Matt 실제로 내 앱을 설정하는 방법을 완전히 다시 생각하게 만들었습니다 ... 모든 UI를 완전히 다시 쓴 후에는 더 이상 segues를 사용하지 않습니다.
Michael Rowe

@cocoanut 나는 "응용 프로그램이 모달 액티브 컨트롤러를 제시하려고했습니다"라는 오류가 발생합니다.
Bala

1
Manual Segue "Push"는 더 이상 사용되지 않으며 "Show"를 사용하십시오. 이 답변 에는 자세한 내용이 있습니다. @smileBot 답변을 업데이트하십시오.
NAbbas

81

이 코드를 사용하여 사용자 정의 segue 서브 클래스를 인스턴스화하고 프로그래밍 방식으로 실행했습니다. 작동하는 것 같습니다. 이것에 문제가 있습니까? 나는 할 수 없다는 다른 모든 답변을 읽고 의아해합니다.

UIViewController *toViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"OtherViewControllerId"];
MyCustomSegue *segue = [[MyCustomSegue alloc] initWithIdentifier:@"" source:self destination:toViewController];
[self prepareForSegue:segue sender:sender];
[segue perform];

4
MyCustomSegue에 무엇입니까?
Victor Engel 2016 년

3
의 사용자 정의 하위 클래스입니다 UIStoryboardSegue.
Jean-Philippe Pellet

7
@MarkAmery 많은 사람들 (나 포함)은 스토리 보드 사용을 피합니다. 그것들은 병합하기 어렵고, 전달하는 ID performSegueWithIdentifier:가 스토리 보드에 실제로 정의되어 있는지 컴파일 타임 검사가 없습니다 . 내가 직접 segue를 만들면 모든 문제를 피합니다.
Jean-Philippe Pellet

3
Jean-Philippe에 동의합니다. 스토리 보드 관리는 엉덩이에 고통입니다. 물론 적은 수의 뷰를 생성하고 여기에 segue를 추가하고 여기에 segue를 추가하는 방법을 쉽게 클릭 할 수 있지만 XML로 정의 된 16 개의 segue로 6 개의 뷰를 관리하는 것은 세 명의 개발자가 모두 끔찍한 일입니다. 어쨌든 요점은 : code는 제어를 제공하지만 xcode로 생성 된 xml은 제어하지 않습니다.
Krystian

3
iOS7의 [segue perform]에서 충돌이 발생하지만 다른 사람이이 문제를 겪고 있는지 확실하지 않습니다.
Eric Chen

45

이 답변에 동의하고 추측하지만 몇 가지 세부 정보를 추가하고 싶습니다.

로그인 화면을 첫 번째 화면으로 표시하고 로그인이 올바른 경우 응용 프로그램을 보려고하는 문제를 해결하기 위해 수행 한 작업. login-view controller에서 root view controller까지 segue를 생성하고 "myidentifier"와 같은 식별자를 부여했습니다.

그런 다음 모든 로그인 코드를 확인한 후 로그인이 올바른지 확인하십시오.

[self performSegueWithIdentifier: @"myidentifier" sender: self];

내 가장 큰 오해는 내가 segue를 버튼에 넣고 segue가 발견되면 방해하는 것입니다.


4
다른 의견으로 썼 듯이 : 나는 프로그래밍 방식으로 사용자 정의 segues를 만들고 수행했습니다 (내 답변 참조).
Jean-Philippe Pellet

32

UIStoryboard사용중인 코드를 코드에 연결해야합니다 . 에서 YourViewController 로 이동하고 UIStoryboard주위의 테두리를 클릭 한 다음 해당 identifier필드를 NSString코드에서 호출 하는 필드로 설정 하십시오.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" 
                                                     bundle:nil];
YourViewController *yourViewController = 
 (YourViewController *)
  [storyboard instantiateViewControllerWithIdentifier:@"yourViewControllerID"];
[self.navigationController pushViewController:yourViewController animated:YES];

1
나는 이것을 얻었지만, 내가 제시하려는 viewController가 스토리 보드의 NavigationController에 내장되어 있다면 어떨까요? 내가 찾을 수있는 것부터 NavigationController를 초기화하여 포함시킬 수 있지만 스토리 보드에는 이미 제시해야 할보기에 대한 푸시 세그 설정이 있습니다.
jhilgert00

1
이것에 대해 자세히 설명해 주시겠습니까? 나는 이것이 내가 겪고있는 문제라고 생각하지만, 어떻게 / 어떻게
해야할지 모르겠다

1
이 솔루션조차도 올바른 솔루션입니다. 어쨌든 피하는 것에 관한 것이지만 질문은 segue에 관한 것입니다. 이러한 방식으로 스토리 보드에서 신호없이 두 장면을 연결하거나 전환 할 수 있습니다.
BootMaker

16

스토리 보드에있는 컨트롤러 용.

jhilgert00이 찾고 계십니까?

-(IBAction)nav_goHome:(id)sender {
UIViewController *myController = [self.storyboard instantiateViewControllerWithIdentifier:@"HomeController"];
[self.navigationController pushViewController: myController animated:YES];

}

또는...

[self performSegueWithIdentifier:@"loginMainSegue" sender:self];


3

설명을 추가하고 싶습니다 ...

사실 한동안 오해 한 일반적인 오해는 스토리 보드 segue가이 prepareForSegue:sender:방법 에 의해 유발된다는 것 입니다. 그렇지 않습니다. 스토리 보드 segue는 구현 여부에 관계없이 수행됩니다.prepareForSegue:sender: 뷰 컨트롤러에 대한 방법을 됩니다.

Paul Hegarty의 훌륭한 iTunesU 강의 에서 이것을 배웠습니다. . 사과하지만 불행히도 어떤 강의를 기억할 수 없습니다.

스토리 보드에서 두 개의보기 컨트롤러 사이에 segue를 연결하지만 prepareForSegue:sender: 메소드를 경우 segue는 여전히 대상보기 컨트롤러로 segue됩니다. 그러나 해당 뷰 컨트롤러는 준비되지 않은 상태입니다.

도움이 되었기를 바랍니다.


3

스토리 보드 Segue는 스토리 보드 외부에서 생성되지 않습니다. 단점에도 불구하고 연결해야합니다.

UIStoryboardSegue Reference는 다음과 같이 명확하게 설명합니다.

segue 객체를 직접 만들지 않습니다. 대신 스토리 보드 런타임은 두 개의 뷰 컨트롤러 사이에서 segue를 수행해야 할 때 생성합니다. 원하는 경우 UIViewController의 performSegueWithIdentifier : sender : 메소드를 사용하여 프로그래밍 방식으로 segue를 시작할 수 있습니다. 프로그래밍 방식으로 추가되어 Interface Builder에서 사용할 수없는 소스에서 segue를 시작하기 위해 그렇게 할 수 있습니다.

프로그래밍 방식으로 스토리 보드에 segue 사용 presentModalViewController:또는 pushViewController:animated:호출을 사용하여 뷰 컨트롤러를 표시하도록 지시 할 수 있지만 스토리 보드 인스턴스가 필요합니다.

전화해도됩니다 UIStoryboards class 메소드를 하여 기본 번들에 대해 번들 nil이있는 명명 된 스토리 보드를 얻을 .

storyboardWithName:bundle:


2

먼저 스토리 보드에 서로 다른 두 가지보기가 있고 한 화면에서 다른 화면으로 이동하려고한다고 가정하면 다음 단계를 수행하십시오.

1). ID 관리자에서 클래스 파일과 스토리 보드 ID를 사용하여 모든 뷰를 정의하십시오.

2). 탐색 컨트롤러를 첫 번째보기에 추가해야합니다. 스토리 보드에서 선택한 다음 편집기> 내장> 탐색 컨트롤러

삼). 첫 번째 클래스에서 "secondClass.h"를 가져옵니다.

#import "ViewController.h
#import "secondController.h"

4). segue를 수행해야하는 IBAction에이 명령을 추가하십시오.

secondController *next=[self.storyboard instantiateViewControllerWithIdentifier:@"second"];
[self.navigationController pushViewController:next animated:YES];

5). @"second"secondview 컨트롤러 클래스, 스토리 보드 ID입니다.


self.storyboard해야한다 :UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
masipcat

@masipcat 내가 사용 있도록 스토리 보드 이름은 "Main.storyboard"이었다 광산에서, 당신은 당신의 Xcode 프로젝트를 설정하는 방법에 따라 수storyboardWithName:@"Main"
ammianus

첫 번째 컨트롤러는 네비게이션 컨트롤러에 포함되지 않은 경우 @ sanket - 차우은 또한 사용하여 다음보기를 표시 할 수 있습니다 [self showDetailViewController:next sender:self];또는[self showViewController:next sender:self];
ammianus

1

나는 리버스 엔지니어링하고 UIStoryboard의 segues의 오픈 소스 (재) 구현을 만들었습니다 : https://github.com/acoomans/Segway

해당 라이브러리를 사용하면 스토리 보드없이 프로그래밍 방식으로 segue를 정의 할 수 있습니다.

그것이 도움이되기를 바랍니다.


0

실제로 몇 가지 문제가 있습니다.

먼저, 우리를 위해 업로드 한 프로젝트에서 segue는 "segue1"식별자를 갖지 않습니다.

식별자 없음

해당 식별자를 아직 입력하지 않은 경우 입력해야합니다.

둘째, 테이블보기에서 테이블보기로 푸시 할 때 initWithNibName을 호출하여보기 컨트롤러를 만듭니다. 실제로 instantiateViewControllerWithIdentifier를 사용하고 싶습니다.


0

다음에 대한 코드 샘플이 있습니다 Creating a segue programmatically.

class ViewController: UIViewController {
    ...
    // 1. Define the Segue
    private var commonSegue: UIStoryboardSegue!
    ...
    override func viewDidLoad() {
        ...
        // 2. Initialize the Segue
        self.commonSegue = UIStoryboardSegue(identifier: "CommonSegue", source: ..., destination: ...) {
            self.commonSegue.source.showDetailViewController(self.commonSegue.destination, sender: self)
        }
        ...
    }
    ...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // 4. Prepare to perform the Segue
        if self.commonSegue == segue {
            ...
        }
        ...
    }
    ...
    func actionFunction() {
        // 3. Perform the Segue
        self.prepare(for: self.commonSegue, sender: self)
        self.commonSegue.perform()
    }
    ...
}

당신은 self.prepare(for: self.commonSegue, sender: self)당신의 행동 방법에서 전화 하고 있습니다. 그런 비교의 시점 무엇 if self.commonSegue == segue {...}prepare(for:sender)방법은?
nayem

@nayem : prepare(for:sender:)에서 대상보기 컨트롤러를 표시하기 전에 구성 할 수 있습니다. 물론에서 할 수도 있습니다 actionFunction.
jqgsninimo

@ nayem : 내가 이것을하는 이유는 다른 segue의 처리와 일관성을 유지하려고하기 때문입니다.
jqgsninimo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.