여러 하위 클래스에 단일 스토리 보드 uiviewcontroller를 사용하는 방법


118

UINavigationController초기 뷰 컨트롤러 를 포함하는 스토리 보드가 있다고 가정 해 보겠습니다 . 그것의 루트 뷰 컨트롤러의 서브 클래스 UITableViewControllerBasicViewController. 그것은이 IBAction탐색 표시 줄의 오른쪽 탐색 버튼에 연결되는

추가 스토리 보드를 만들 필요없이 내가 다른 뷰의 템플릿으로 스토리 보드를 사용하고 싶습니다 거기에서. 이러한 뷰는 정확히 동일한 인터페이스하지만 루트 뷰 클래스의 컨트롤러를해야합니다 말 SpecificViewController1SpecificViewController2의 하위 클래스입니다 BasicViewController.
이 2 개의 뷰 컨트롤러는 IBAction메서드를 제외하고는 동일한 기능과 인터페이스를 갖습니다 .
다음과 같습니다.

@interface BasicViewController : UITableViewController

@interface SpecificViewController1 : BasicViewController

@interface SpecificViewController2 : BasicViewController

그런 식으로 할 수 있습니까?
난 그냥의 스토리 보드를 인스턴스화 할 수 BasicViewController있지만, 서브 클래스에 루트 뷰 컨트롤러가 SpecificViewController1SpecificViewController2?

감사.


3
펜촉으로 이것을 할 수 있다는 점을 지적 할 가치가 있습니다. 하지만 스토리 보드에만있는 멋진 기능 (예 : 정적 / 프로토 타입 셀)을 원하는 저와 같으면 운이 좋지 않은 것 같습니다.
Joseph Lin

답변:


57

좋은 질문-그러나 불행히도 절름발이 대답입니다. UIStoryboard에는 초기화시 스토리 보드의 개체 세부 정보에 정의 된대로 스토리 보드와 연결된 뷰 컨트롤러를 재정의 할 수있는 이니셜 라이저가 없기 때문에 현재 제안한 작업을 수행 할 수 있다고 생각하지 않습니다. stoaryboard의 모든 UI 요소가 뷰 컨트롤러의 속성에 연결되는 것은 초기화 단계입니다.

기본적으로 스토리 보드 정의에 지정된 뷰 컨트롤러로 초기화됩니다.

스토리 보드에서 만든 UI 요소를 재사용하려는 경우에도 뷰 컨트롤러가 이벤트에 대해 "알려줄"수 있도록 뷰 컨트롤러가 사용하는 속성에 연결되거나 연결되어야합니다.

스토리 보드 레이아웃을 복사하는 것은 그다지 큰 문제가 아닙니다. 특히 3 개의 뷰에 대해 유사한 디자인 만 필요한 경우에는 그다지 중요하지 않습니다. 그러나 그렇게한다면 이전의 모든 연결이 지워 졌는지 확인해야합니다. 그렇지 않으면 시도 할 때 충돌이 발생합니다. 이전 뷰 컨트롤러와 통신합니다. 로그 출력에서 ​​KVO 오류 메시지로 인식 할 수 있습니다.

취할 수있는 몇 가지 접근 방식 :

  • xib 파일의 UIView에 UI 요소를 저장하고 기본 클래스에서 인스턴스화하고 기본보기 (일반적으로 self.view)의 하위보기로 추가합니다. 그런 다음 기본적으로 스토리 보드에서 해당 위치를 유지하지만 올바른 뷰 컨트롤러 하위 클래스가 할당 된 빈 뷰 컨트롤러가있는 스토리 보드 레이아웃을 사용합니다. 그들은 기지에서 물려 받기 때문에 그 관점을 얻게 될 것입니다.

  • 코드에서 레이아웃을 만들고 기본 뷰 컨트롤러에서 설치하십시오. 분명히이 접근 방식은 스토리 보드를 사용하는 목적을 무효화하지만 귀하의 경우에 갈 수있는 방법 일 수 있습니다. 스토리 보드 접근 방식의 이점을 얻을 수있는 앱의 다른 부분이있는 경우 적절한 경우 여기 저기에서 벗어나는 것이 좋습니다. 이 경우 위와 같이 하위 클래스가 할당 된 뱅크 뷰 컨트롤러를 사용하고 기본 뷰 컨트롤러가 UI를 설치하도록합니다.

애플이 당신이 제안한 것을 할 수있는 방법을 생각해 냈다면 좋겠지 만, 그래픽 요소가 컨트롤러 하위 클래스와 미리 연결되어있는 문제는 여전히 문제가 될 것입니다.

새해 복 많이 받으세요 !! 잘 지내다


그것은 빠르다. 내가 생각했듯이 그것은 불가능할 것입니다. 현재 나는 BasicViewController 클래스 만 가지고 어떤 "클래스"/ "모드"로 작동 할 것인지를 나타내는 추가 속성이있는 솔루션을 생각해 냈습니다. 어쨌든 감사합니다.
verdy

2
너무 나쁘다 :( 같은 뷰 컨트롤러를 복사하여 붙여넣고 대안으로 클래스를 변경해야
한다고 생각한다

1
그리고 이것이 제가 스토리 보드를 좋아하지 않는 이유입니다 ... 표준 뷰보다 조금 더 많이하면 어떻게 든 실제로 작동하지 않습니다 ...
TheEye

당신이 그 말을 들었을 때 너무 슬프다. 나는 해결책을 찾고 있어요
Tony

2
또 다른 접근 방식이 있습니다. 다른 대리자에 사용자 지정 논리를 지정하고 prepareForSegue에서 올바른 대리자를 할당합니다. 이렇게하면 스토리 보드에 UIViewController 1 개 + UIViewController 1 개를 만들지 만 구현 버전이 여러 개 있습니다.
plam4u

45

우리가 찾고있는 라인의 코드는 다음과 같습니다 :

object_setClass(AnyObject!, AnyClass!)

Storyboard-> UIViewController 추가에서 ParentVC 클래스 이름을 지정하십시오.

class ParentVC: UIViewController {

    var type: Int?

    override func awakeFromNib() {

        if type = 0 {

            object_setClass(self, ChildVC1.self)
        }
        if type = 1 {

            object_setClass(self, ChildVC2.self)
        }  
    }

    override func viewDidLoad() {   }
}

class ChildVC1: ParentVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        println(type)
        // Console prints out 0
    }
}

class ChildVC2: ParentVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        println(type)
        // Console prints out 1
    }
}

5
감사합니다. 예를 들면 다음과 같습니다.class func instantiate() -> SubClass { let instance = (UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SuperClass") as? SuperClass)! object_setClass(instance, SubClass.self) return (instance as? SubClass)! }
CocoaBob

3
이게 어떻게 작동하는지 잘 모르겠어요. 부모가 자신의 클래스를 아이의 클래스로 설정하고 있습니까? 그렇다면 어떻게 여러 자녀를 가질 수 있습니까?!
user1366265

2
당신 각하, 내 일을 한
제레

2
여러분, 조금 더 자세히 설명하겠습니다. 우리는 무엇을 성취하고 싶습니까? 더 많은 클래스에 스토리 보드를 사용할 수 있도록 ParentViewController의 하위 클래스를 만들고 싶습니다. 따라서 모든 것을 수행하는 매직 라인은 내 솔루션에서 강조 표시되며 ParentVC의 awakeFromNib에서 사용해야합니다. 그러면 하위 클래스가되는 새로 설정된 ChildVC1의 모든 메서드를 사용합니다. 더 많은 ChildVC에 사용하고 싶다면? awakeFromNib .. if (type = a) {object_setClass (self, ChildVC1.self)} else {object_setClass (self.ChildVC2.self)} 행운을 빕니다.
Jiří Zahálka

10
이것을 사용할 때 매우 조심하십시오! 일반적으로 이것은 전혀 사용되지 않아야합니다 ... 이것은 단순히 주어진 포인터의 isa 포인터를 변경하고 예를 들어 다른 속성을 수용하기 위해 메모리를 재할 당하지 않습니다. 이에 대한 한 가지 지표는 포인터 self가 변경되지 않는다는 것입니다. 따라서 객체를 검사 (예 : _ivar / 속성 값 읽기) object_setClass하면 충돌이 발생할 수 있습니다.
Patrik

15

받아 들여진 답변에서 알 수 있듯이 스토리 보드로 할 수없는 것 같습니다.

내 해결책은 Nib을 사용하는 것입니다. 개발자가 스토리 보드 이전에 사용했던 것처럼 요. 재사용 가능하고 서브 클래 싱 가능한 뷰 컨트롤러 (또는 뷰)를 원한다면 Nibs를 사용하는 것이 좋습니다.

SubclassMyViewController *myViewController = [[SubclassMyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; 

MyViewController.xibNib 이로 드되어야하는 클래스를 지정하지 않고 "파일 소유자"에 모든 출력을 연결할 때 키-값 쌍을 지정하는 것입니다. " 이보기는이 인스턴스 변수 이름에 연결되어야합니다 ." [SubclassMyViewController alloc] initWithNibName:초기화 프로세스를 호출 할 때 nib에서 생성 한 뷰 를 " 제어 "하는 데 사용할 뷰 컨트롤러를 지정합니다 .


놀랍게도 ObjC 런타임 라이브러리 덕분에 스토리 보드에서 이것이 가능한 것 같습니다. 여기에 내 대답을 확인하십시오 stackoverflow.com/a/57622836/7183675
아담 Tucholski

9

스토리 보드가 사용자 정의 뷰 컨트롤러의 다른 하위 클래스를 인스턴스화하도록하는 것이 가능합니다. 약간 비 정통적인 기술인 alloc뷰 컨트롤러에 대한 메서드를 재정의해야합니다 . 커스텀 뷰 컨트롤러가 생성되면 오버라이드 된 alloc 메소드는 실제로 alloc서브 클래스 에서 실행 된 결과를 반환합니다 .

나는 다양한 시나리오에서 테스트했고 오류가 없었지만 더 복잡한 설정에 대처할 수는 없지만 작동하지 않아야 할 이유가 없다는 단서로 대답을 시작해야합니다. . 또한이 방법을 사용하여 앱을 제출하지 않았으므로 Apple의 검토 프로세스에서 거부 될 수있는 외부 기회가 있습니다 (다시 말하지만 그 이유는 알 수 없습니다).

데모 목적으로 UILabel IBOutlet 및 IBAction이있는 UIViewControllercalled 의 하위 클래스가 TestViewController있습니다. 내 스토리 보드에서 뷰 컨트롤러를 추가하고 클래스를으로 수정하고 TestViewControllerIBOutlet을 UILabel에 연결하고 IBAction을 UIButton에 연결했습니다. 앞의 viewController에서 UIButton에 의해 트리거되는 모달 segue를 통해 TestViewController를 제시합니다.

스토리 보드 이미지

어떤 클래스가 인스턴스화되는지 제어하기 위해 정적 변수와 관련 클래스 메서드를 추가 했으므로 사용할 서브 클래스를 가져 오거나 설정합니다 (어떤 서브 클래스를 인스턴스화 할 것인지 결정하는 다른 방법을 채택 할 수 있습니다).

TestViewController.m :

#import "TestViewController.h"

@interface TestViewController ()
@end

@implementation TestViewController

static NSString *_classForStoryboard;

+(NSString *)classForStoryboard {
    return [_classForStoryboard copy];
}

+(void)setClassForStoryBoard:(NSString *)classString {
    if ([NSClassFromString(classString) isSubclassOfClass:[self class]]) {
        _classForStoryboard = [classString copy];
    } else {
        NSLog(@"Warning: %@ is not a subclass of %@, reverting to base class", classString, NSStringFromClass([self class]));
        _classForStoryboard = nil;
    }
}

+(instancetype)alloc {
    if (_classForStoryboard == nil) {
        return [super alloc];
    } else {
        if (NSClassFromString(_classForStoryboard) != [self class]) {
            TestViewController *subclassedVC = [NSClassFromString(_classForStoryboard) alloc];
            return subclassedVC;
        } else {
            return [super alloc];
        }
    }
}

내 테스트를 위해 나는 두 서브 클래스가 TestViewController: RedTestViewControllerGreenTestViewController. 하위 클래스에는 각각 추가 속성이 있으며 각 재정의 viewDidLoad는 뷰의 배경색을 변경하고 UILabel IBOutlet의 텍스트를 업데이트합니다.

RedTestViewController.m :

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.view.backgroundColor = [UIColor redColor];
    self.testLabel.text = @"Set by RedTestVC";
}

GreenTestViewController.m :

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor greenColor];
    self.testLabel.text = @"Set by GreenTestVC";
}

어떤 경우에는 TestViewController자신 을 인스턴스화 RedTestViewController하거나 다른 경우에는 또는 GreenTestViewController. 앞의 뷰 컨트롤러에서 다음과 같이 무작위로 수행합니다.

NSInteger vcIndex = arc4random_uniform(4);
if (vcIndex == 0) {
    NSLog(@"Chose TestVC");
    [TestViewController setClassForStoryBoard:@"TestViewController"];
} else if (vcIndex == 1) {
    NSLog(@"Chose RedVC");
    [TestViewController setClassForStoryBoard:@"RedTestViewController"];
} else if (vcIndex == 2) {
    NSLog(@"Chose BlueVC");
    [TestViewController setClassForStoryBoard:@"BlueTestViewController"];
} else {
    NSLog(@"Chose GreenVC");
    [TestViewController setClassForStoryBoard:@"GreenTestViewController"];
}

있습니다 setClassForStoryBoard방법 검사가 어떤 혼동을 피하기 위해, 요구 된 클래스 이름이 실제로 TestViewController의 서브 클래스 있는지 확인합니다. 위의에 대한 참조 BlueTestViewController는이 기능을 테스트하기위한 것입니다.


프로젝트에서 비슷한 작업을 수행했지만 UIViewController의 alloc 메서드를 재정 의하여 모든 재정의에 대한 전체 정보를 수집하는 외부 클래스에서 하위 클래스를 가져옵니다. 완벽하게 작동합니다.
Tim

그런데 Apple이 뷰 컨트롤러에서 할당 호출을 중지하면이 메서드가 fas ar로 작동하지 않을 수 있습니다. 예를 들어 NSManagedObject 클래스는 할당 메서드를 수신하지 않습니다. 나는 애플이 코드를 다른 방법으로 복사 할 수 있다고 생각한다 : 아마도 + allocManagedObject
Tim

7

instantiateViewControllerWithIdentifier 후에 이것을 시도하십시오.

- (void)setClass:(Class)c {
    object_setClass(self, c);
}

처럼 :

SubViewController *vc = [sb instantiateViewControllerWithIdentifier:@"MainViewController"];
[vc setClass:[SubViewController class]];

코드가 수행하는 작업에 대한 유용한 설명을 추가하십시오.
codeforester

7
하위 클래스의 인스턴스 변수를 사용하면 어떻게됩니까? 그에 맞도록 할당 된 메모리가 충분하지 않기 때문에 충돌을 추측하고 있습니다. 내 테스트에서 나는을 얻었 EXC_BAD_ACCESS으므로 이것을 권장하지 않습니다.
Legoless

1
자식 클래스에 새 변수를 추가하면 작동하지 않습니다. 그리고 아이 init도 호출되지 않습니다. 이러한 제약으로 인해 모든 접근 방식을 사용할 수 없게됩니다.
Al Zonke

6

특히 nickgzzjrJiří Zahálka 답변을 바탕으로 CocoaBob 의 두 번째 답변 아래에 주석을 추가하여 OP에 필요한 작업을 정확히 수행하는 짧은 일반 방법을 준비했습니다. 스토리 보드 이름과 뷰 컨트롤러 스토리 보드 ID 만 확인하면됩니다.

class func instantiate<T: BasicViewController>(as _: T.Type) -> T? {
        let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
        guard let instance = storyboard.instantiateViewController(withIdentifier: "Identifier") as? BasicViewController else {
            return nil
        }
        object_setClass(instance, T.self)
        return instance as? T
    }

강제 풀기 (swiftlint 경고)를 방지하기 위해 옵션이 추가되었지만 메서드는 올바른 객체를 반환합니다.


5

엄격히 하위 클래스는 아니지만 다음을 수행 할 수 있습니다.

  1. option-문서 개요에서 기본 클래스 뷰 컨트롤러를 드래그하여 복사본을 만듭니다.
  2. 새 뷰 컨트롤러 사본을 스토리 보드의 별도 위치로 이동
  3. Identity Inspector에서 클래스 를 하위 클래스보기 컨트롤러로 변경 합니다.

다음은 내가 작성한 Bloc 튜토리얼 의 예 ViewController입니다 WhiskeyViewController.

위의 세 단계의 애니메이션

이를 통해 스토리 보드에서 뷰 컨트롤러 하위 클래스의 하위 클래스를 만들 수 있습니다. 그런 다음을 사용 instantiateViewControllerWithIdentifier:하여 특정 하위 클래스를 만들 수 있습니다 .

이 접근 방식은 약간 융통성이 없습니다. 스토리 보드 내에서 기본 클래스 컨트롤러에 대한 이후 수정 사항은 하위 클래스로 전파되지 않습니다. 당신이 경우 많은 서브 클래스를 당신은 다른 솔루션을 하나 더 좋을 수도 있지만,이 방법은 핀치에 할 것입니다.


11
이것은 하위 클래스 메이트가 아니며 ViewController를 복제하는 것입니다.
Ace Green

1
그건 맞지 않습니다. Class 를 하위 클래스 로 변경하면 (3 단계) 하위 클래스가 됩니다. 그런 다음 원하는 변경을 수행하고 하위 클래스의 콘센트 / 액션에 연결할 수 있습니다.
Aaron Brager 2017-04-27

6
나는 당신이 서브 클래 싱의 개념을 이해하지 못한다고 생각합니다.
Ace Green

5
"스토리 보드 내에서 나중에 기본 클래스 컨트롤러에 대한 수정 사항이 하위 클래스로 전파되지 않는 경우" "서브 클래 싱"이라고하지 않습니다. 복사 및 붙여 넣기입니다.
superarts.org

Identity Inspector에서 선택된 기본 클래스는 여전히 하위 클래스입니다. 초기화되고 비즈니스 로직을 제어하는 ​​객체는 여전히 하위 클래스입니다. 스토리 보드 파일에 XML로 저장되고를 통해 초기화 된 인코딩 된 뷰 데이터 만 initWithCoder:상속 된 관계가 없습니다. 이러한 유형의 관계는 스토리 보드 파일에서 지원되지 않습니다.
Aaron Brager jul.

4

Objc_setclass 메서드는 childvc의 인스턴스를 만들지 않습니다. 그러나 childvc에서 튀어 나오는 동안 childvc의 deinit가 호출되고 있습니다. childvc에 대해 별도로 할당 된 메모리가 없기 때문에 앱이 충돌합니다. Basecontroller에는 인스턴스가 있지만 자식 vc에는 없습니다.


2

스토리 보드에 너무 의존하지 않는 경우 컨트롤러에 대해 별도의 .xib 파일을 만들 수 있습니다.

해당 파일의 소유자 및 콘센트를 Main VC에서 MainViewController및 재정의 init(nibName:bundle:)로 설정하여 하위 항목이 동일한 Nib 및 해당 콘센트에 액세스 할 수 있도록합니다.

코드는 다음과 같아야합니다.

class MainViewController: UIViewController {
    @IBOutlet weak var button: UIButton!

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: "MainViewController", bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        button.tintColor = .red
    }
}

그리고 자녀 VC는 부모의 펜촉을 재사용 할 수 있습니다.

class ChildViewController: MainViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        button.tintColor = .blue
    }
}

2

여기저기서 답변을 받아이 깔끔한 솔루션을 찾았습니다.

이 함수로 부모 뷰 컨트롤러를 만듭니다.

class ParentViewController: UIViewController {


    func convert<T: ParentViewController>(to _: T.Type) {

        object_setClass(self, T.self)

    }

}

이를 통해 컴파일러는 자식 뷰 컨트롤러가 부모 뷰 컨트롤러에서 상속되는지 확인할 수 있습니다.

그런 다음 하위 클래스를 사용하여이 컨트롤러로 segue를 원할 때마다 다음을 수행 할 수 있습니다.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if let parentViewController = segue.destination as? ParentViewController {
        ParentViewController.convert(to: ChildViewController.self)
    }

}

멋진 부분은 스토리 보드 참조를 자체에 추가 한 다음 "다음"자식 뷰 컨트롤러를 계속 호출 할 수 있다는 것입니다.


1

아마도 가장 유연한 방법은 재사용 가능한 뷰를 사용하는 것입니다.

(별도의 XIB 파일에서보기를 생성하거나 Container view스토리 보드의 각 하위 클래스보기 컨트롤러 장면에 추가)


1
비추천 할 때 댓글을 남겨주세요. 나는 그 질문에 직접 대답하지 않지만 근본 문제에 대한 해결책을 제안합니다.
DanSkeel

1

간단하고 분명하며 일상적인 해결책이 있습니다.

기존 스토리 보드 / 컨트롤러를 새로운 스토리 보드 / 컨트롤러 안에 넣으면됩니다. 컨테이너보기로서의 IE.

이것은 뷰 컨트롤러의 "서브 클래 싱"과 정확히 유사한 개념입니다.

모든 것이 서브 클래스에서와 똑같이 작동합니다.

일반적으로 뷰 하위 뷰를 다른 뷰 안에 넣는 것처럼 자연스럽게 뷰 컨트롤러를 다른 뷰 컨트롤러 안에 넣습니다 .

어떻게 할 수 있습니까?

"subview"개념만큼이나 단순한 iOS의 기본 부분입니다.

이것은 간단합니다 ...

/*

Search screen is just a modification of our List screen.

*/

import UIKit

class Search: UIViewController {
    
    var list: List!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        list = (_sb("List") as! List
        addChild(list)
        view.addSubview(list.view)
        list.view.bindEdgesToSuperview()
        list.didMove(toParent: self)
    }
}

이제 당신은 분명히 list당신이 원하는 것을해야합니다.

list.mode = .blah
list.tableview.reloadData()
list.heading = 'Search!'
list.searchBar.isHidden = false

기타 등등.

컨테이너 뷰는 "하위 뷰"가 "동일한"서브 클래 싱과 같은 방식으로 "동일한"서브 클래 싱입니다.

당연히 "레이아웃을 훼손"할 수는 없습니다. 그게 무슨 의미일까요?

( "서브 클래 싱"은 OO 소프트웨어와 관련이 있으며 "레이아웃"과는 관련이 없습니다.)

분명히 뷰를 재사용하고 싶을 때 다른 뷰 안에서 하위 뷰만하면됩니다.

컨트롤러 레이아웃을 재사용하려면 다른 컨트롤러 내에서 컨테이너보기 만하면됩니다.

이것은 iOS의 가장 기본적인 메커니즘입니다 !!


참고-수년 동안 다른 뷰 컨트롤러를 컨테이너 뷰로 동적으로로드하는 것은 사소한 일이었습니다. 마지막 섹션에서 설명 : https://stackoverflow.com/a/23403979/294884

참고- "_sb"는 입력을 저장하는 데 사용하는 명백한 매크로입니다.

func _sb(_ s: String)->UIViewController {
    // by convention, for a screen "SomeScreen.storyboard" the
    // storyboardID must be SomeScreenID
    return UIStoryboard(name: s, bundle: nil)
       .instantiateViewController(withIdentifier: s + "ID")
}

1

@ Jiří Zahálka의 영감을주는 답변에 감사드립니다. 4 년 전에 여기에 내 솔루션에 답장 했지만 @Sayka가 답변으로 게시 할 것을 제안 했으므로 여기에 있습니다.

내 프로젝트에서 일반적으로 UIViewController 하위 클래스에 Storyboard를 사용하는 경우 항상 instantiate()해당 하위 클래스에서 호출되는 정적 메서드를 준비하여 Storyboard에서 인스턴스를 쉽게 만들 수 있습니다. 따라서 solve OP의 질문에 대해 서로 다른 하위 클래스에 대해 동일한 Storyboard를 공유하려면 setClass()해당 인스턴스를 반환하기 전에 간단히 해당 인스턴스로 이동할 수 있습니다 .

class func instantiate() -> SubClass {
    let instance = (UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SuperClass") as? SuperClass)!
    object_setClass(instance, SubClass.self)
    return (instance as? SubClass)!
}

0

Jiří Zahálka 답변의 Cocoabob의 의견은이 솔루션을 얻는 데 도움이되었으며 잘 작동했습니다.

func openChildA() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil);
    let parentController = storyboard
        .instantiateViewController(withIdentifier: "ParentStoryboardID") 
        as! ParentClass;
    object_setClass(parentController, ChildA.self)
    self.present(parentController, animated: true, completion: nil);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.