Brian Ogden Brian Ogden - 5 months ago 13
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() {
super.viewDidLoad()

// Do any additional setup after loading the view.
}

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


This builds and runs, but when I Segue to the Swift
TestBasicTabBarSegueViewController
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;
@end

#endif /* UIViewControllerPlus_h */


It is the property
mt
which is of type MMTabBarController.

You can see in the following custom Segue that destinationController.mt 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;
destinationController.mt = 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];
}

@end


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
UIViewControllerPlus
.

But on the next line the app crashes:

enter image description here

Error:

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
UIViewControllerPlus
it is instead casting to type
UIViewController
, even though it defined as a
UIViewControllerPlus
. This only happens if it is a Swift file/class inheriting the Objective C
UIViewControllerPlus
class but the cast works if it is Objective C subclass inheriting Objective C base class
UIViewControllerPlus
:

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

-[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.

Comments