Brian Ogden Brian Ogden - 1 year ago 52
iOS Question

Swift class that inherits an Objective-C Base Class not casting to correct type

  • Using Xcode 7

  • Swift 2

I have been researching inheriting Objective C base class in a Swift UIViewController. I have added my Bridging header file correctly and it is correctly part of my project build settings:

enter image description here

In my SCS-Bridging-Header.h file I have the following code:

#import "UIViewControllerPlus.h"

And then I am trying to inherit the Objective C class UIViewControllerPlus in a Swift class:

import UIKit

class TestBasicTabBarSegueViewController: UIViewControllerPlus {

override func viewDidLoad() {

// Do any additional setup after loading the view.

override func didReceiveMemoryWarning() {
// Dispose of any resources that can be recreated.

This builds and runs, but when I Segue to the Swift
a property of the Objective C base class or super class is not accessible:

#ifndef UIViewControllerPlus_h
#define UIViewControllerPlus_h

#import <UIKit/UIKit.h>
#import "MMTabBarController.h"

@interface UIViewControllerPlus : UIViewController
@property MMTabBarController* mt;

#endif /* UIViewControllerPlus_h */

It is the property
which is of type MMTabBarController.

You can see in the following custom Segue that is not accessible and causes the app to crash when attempting to set:

#import "MMNavigationSegue.h"
#import "MMTabBarController.h"
#import "UIViewControllerPlus.h"

@implementation MMNavigationSegue

- (void) perform
MMTabBarController *tabBarController = (MMTabBarController *) self.sourceViewController;
UIViewControllerPlus *destinationController = (UIViewControllerPlus *) self.destinationViewController; = tabBarController; //HERE APP CRASHES

for (UIView *view in tabBarController.placeholderView.subviews)
[view removeFromSuperview];

// Add view to placeholder view
tabBarController.currentViewController = destinationController;
[tabBarController.placeholderView addSubview: destinationController.view];

// Set autoresizing
[tabBarController.placeholderView setTranslatesAutoresizingMaskIntoConstraints:NO];

UIView *childview = destinationController.view;
[childview setTranslatesAutoresizingMaskIntoConstraints: NO];

// fill horizontal
[tabBarController.placeholderView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat: @"H:|[childview]|" options: 0 metrics: nil views: NSDictionaryOfVariableBindings(childview)]];

// fill vertical
[tabBarController.placeholderView addConstraints:[ NSLayoutConstraint constraintsWithVisualFormat: @"V:|-0-[childview]-0-|" options: 0 metrics: nil views: NSDictionaryOfVariableBindings(childview)]];

[tabBarController.placeholderView layoutIfNeeded];

// notify did move
[destinationController didMoveToParentViewController: tabBarController];


Note, the above code works if the destination UIViewController Segued to is an Objective C code UIViewController implementation that inherits from the Objective C class

But on the next line the app crashes:

enter image description here


2016-06-14 21:16:39.795 SCS[49747:17004544] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIViewController setMt:]: unrecognized selector sent to instance 0x7d967080'

The destinationController is not casting to type
it is instead casting to type
, even though it defined as a
. This only happens if it is a Swift file/class inheriting the Objective C
class but the cast works if it is Objective C subclass inheriting Objective C base class

enter image description here

**Is inheriting an Objective C base class in Swift possible? I have read various conflicting statements online about this?

Is there something I might be missing in my Objective C project references/configuration?**

Answer Source

-[UIViewController setMt:]: means the view controller being instantiated is a regular view controller - not one of your subclassed "plus" type.

You probably forgot to assign the correct class to the view controller in the storyboard.