Xcode 7 Swift 2 impossible to instantiate UIViewController subclass of generic UITableViewController - ios

I have a generic class:
class PaginatedTableViewController
<GenericElement, Source: PaginationDataSource
where Source.PaginatedGenericElement == GenericElement>:
UITableViewController
and another that I try to instantiate from storyboard:
class CandidatesTableViewController:
PaginatedTableViewController<Match, MatchPaginationDataSource>
I can't find CandidatesTableViewController in the storyboard Custom Class dropdown menu. If I force it then cast my controller in code, app crashes at runtime complaining my controller (that should be a CandidatesTableViewController instance) is in fact a UITableViewController instance.
Unknown class _TtC21MyProjectName29CandidatesTableViewController in
Interface Builder file.
Could not cast value of type
'UITableViewController' (0x1040917f8) to
'MyProjectName.CandidatesTableViewController' (0x1013a9890).
In my project this controller is embedded in another one that's why I cast it :
tableViewController = (segue.destinationViewController as! CandidatesTableViewController)
Does any one knows how to resolve this issue ?

Unfortunately, generic Swift classes are not visible to Objective-C code and also are not supported in Interface Builder (in storyboards and xibs). I find these two points closely related.
As a solution I would suggest you to use aggregation: do not make you view controller generic, but extract some logic to another (generic) class and use it inside your view controller.

It is possible if you manually load your generic VC into Objective-C runtime manually via the load() method i.e. call. PaginatedTableViewController.load() in your app delegate's init method. Idea from https://stackoverflow.com/a/43896830/671580

Related

Don't have to cast segue destination view controller anymore?

I saw this in a codebase:
BlablaViewController *bbVC = segue.destinationViewController;
I thought this always needed to be casted to the correct type. Did something change in Objective-C recently that makes this cast no longer necessary?
since xcode 7 you have a new annotation called __kindof which allows you to point with UIViewController subclass (BlablaViewController in your case) to UIViewController. please see this example:
https://happyteamlabs.com/blog/how-to-use-__kindof-in-objective-c/

Calling functions from separate view controllers in swift

I think the solution to this is going to need to use delegation, but I'm unfamiliar with how to use them.
So in my project, I have my main viewcontroller/storyboard that contains a UIScrollView. That UIScrollview calls another storyboard (xib file) as a subview. The other storyboard (which is an xib file) is controlled with another swift file.
My question is, when I call an action inside of my other storyboard, how can I call a function from the main viewcontroller. Like say the viewdidload from the first viewcontroller.
I can't make the whole thing a global function, it needs to stay inside its class. So if I try to do ViewController.viewDidLoad() it needs (I think) an instance variable or something.
Thanks.
You can try:
Using weak variable (property) in the other class with type UIViewController
Assign the parent view controller to that property after the other view is initialized
Good reads about weak, strong, unowned references Here And Here
Firstly, if you want to call it with class name as you said above declare your method with "class". So its just like static in Java. It makes it generic to call it anywhere in your project. Make a separate extension.
class func myfunc(){
}
if you want to send data from B to A controller. You use what is called delegation. You give the work of B to A. Make a protocol above B for functions that you want to do or send with them. Call them in B. And then in A write code for those functions. So that you have the data from B to A
Else you demand something like common data. Create a singleton class and initialize properties methods there. You can use objects for that and call it in other controller to modify or make different instances.
You dont call viewDidLoad(). As the name says it loads once. If you want something that modify everytime you screen appears, use viewWillAppear

Swift 2 / XCode 7 - "EXC_BAD_ACCESS (code=2...)" when calling "ViewController().view" in another class

why is this error happening and what can i do to fix/prevent in the future? thanks!
NOTE: my other class is set up as such:
class Other {
//then all relevant funcs called
}
am i missing some basic setup information in order for this to run?
The formal explanation would be:
You're trying to access the view property before it was initialized. Another way to look at it is that you're trying to access the view property before it was loaded (in viewDidLoad).
Solution:
Depends what you're using that view for. I've never had to access another view controller's property like that. Consider exploring other strategies such as delegation, weak references to another controller, and passing variables in prepareForSegue if you need a reference from a view controller from another.

Objective-C Modifying Class Instance Superclass

I was wondering if there was a way of dynamically taking an Instance of a class, so lets say I have a UIViewController called menu.
I could take menu's superclass which in this case would be UIViewController and create a subclass of it. I would then assign this new subclass to menu, I could also then dynamically override the methods as well.
So that when menu calls a method such as "ButtonClicked:" my code in the new Class I created fires followed by the original code when I call super :).
This all has to be done at runtime for security reasons.
Runtime subclassing is totally possible. Here's an introduction: http://www.mikeash.com/pyblog/friday-qa-2010-11-19-creating-classes-at-runtime-for-fun-and-profit.html
Although I'm curious... what "security" do you think you're getting by subclassing at runtime?

Clarification around UIViewController<Delegate> *_variable; declaration in iAdSuite tabbed example (iOS)

From Apples iADSuite tabbed example there is a variable defined with delegate.
UIViewController<BannerViewContainer> *_currentController;
later it's cast as such
_currentController = (UIViewController<BannerViewContainer> *)_tabBarController.selectedViewController;
Whats the significance of using "BannerViewContainer" in the declaration, how it relates to the later cast and what's happening under the covers here?
Regards
Jim
There's nothing to do with delegates here. BannerViewContainer is a protocol. (You might be confused because delegation is often defined via protocols.)
Declaring a variable or parameter with an angle-bracketed protocol name means that anything assigned to it must be an object which conforms to that protocol: if you try to pass an instance of UIViewController or some subclass thereof, you'll get a compiler warning unless that instance is of a UIViewController subclass which declares conformance to the BannerViewContainer protocol. (That is, you can pass an instance of FooViewController if its header file reads #interface FooViewController : UIViewController <BannerViewContainer>.)
The cast you see later follows the same pattern as many casts: it's a case where the programmer knows that the object he's assigning meets the requirements for that variable, but the reference he's using doesn't have a matching declaration. That is, the tab bar controller only knows that its selected view controller is a UIViewController (or any subclass thereof), but the programmer knows that the views he put into the tab bar are all UIViewController subclasses conforming to the BannerViewContainer protocol.

Resources