- 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:
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:
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
:
**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?**