How to set Split View Controller Delegate from Storyboard? - ios

I have dragged out a splitViewController, and identified it as a subclass I have created MySplitViewController.
When Right-clicking the splitview storyboard I can see that I've set its Master and Detail view controllers, and furthermore that the delegate is NOT set.
I have made my subclass conform to the protocol and implemented some methods, but they are not being called (which I not understand is because the delegate is not set).
But whenever I try to ctrl+drag from the delegate option in the storyboard to my class, it won't link up. In fact, it won't link up with anything. Am I using this protocol wrong, should my subclass of UISplitViewController not be its own delegate? Then where do I define the delegate in code or otherwise?
Thank you for your time.
Edit: More info-
I tried putting self.delegate = self; in viewDidLoad, but that didn't seem to help.
The particular method I am trying to override is
splitViewControllerPreferredInterfaceOrientationForPresentation:
and I've put an NSLog in the code to notify me if it gets called, which it isn't

As far as I know, NSSplitViewControllers cannot have delegates, and their splitViews can't have their delegates reassigned since the controller acts as the delegate.
If you need access to the delegate methods, simply subclass the controller, then change the class name in Interface Builder.

Related

Not able to make ctrl-drag reference/delegate from uittabcontroller to app delegate

This has really been pissing me off for a while now, and I have no idea how to get further. I have created a tabbed application hence getting the default UITabBarController + 2 View controllers that are nested within this. Fair enough. Now I noticed the viewcontrollers viewDidLoad methods wasn't called when switching around. Ok, so I find theres a tabbar delegate for when a viewcontroller gets "tabbed." Now my problem is the delegate method which I've placed in AppDelegate, is not being called. I have tried in all ways I know of to make a reference to the given tabbarcontroller (to se the delegate programmatically) and I have tried ctrl-dragging the delegate to anywhere possible. Am I doing sth wrong? (because everywhere I look this seems to not be a problem, and people are holding reference to their tabbars).
Thanks
I used this code to get a reference to the tabbar, so I could set the delegate programmatically:
UITabBarController *tabBar = ((UITabBarController*)self.window.rootViewController).delegate = self;
Very simple, I guess I was running late night hours yesterday.
Yet the issue was clearly using storyboard and then trying to make an outlet in app delegate (I still dont think that is possible).
You have to set your view controller's class in storyboard if you want to be able to make references. Select your view controller in storyboard. On the right panel go to Identity inspector and in the Class field set the name of the class. The you should be able to make references and also viewDidLoad should be called.

tableView delegate and datasource

I'm learning Swift. Sometimes I see that Main.Storyboard is used to set up the tableView delegate and dataSource (ctrl+click and so on). Sometimes I see that it's done through coding instead like so:
// create the variable for the tableview
IBOutlet weak var someTableView : UITableView!
// setup delegate and datasource
sefl.someTableView.delegate = self
self.someTableView.datasource = self
I do understand how it works with second way. But it's difficult to realize how it works through Main.Storyboard with no IBOutlet setup.
Thank you for your responses!
It works exactly the same way :)
Let me refresh the principle:
You have a class, provided by Apple in this case, that has to work for a lot of scenario. Apple decided to use a kind of inversion of control, called delegation, where the workflow is inverted (hence the name) : instead of the view controller giving order to the tableView by calling methods on it, it is the tableView that goes and fetch its orders from the controller by calling methods on it.
In order to achieve this kind of IoC (inversion of control), the TableView MUST know the "address" of the object it has to ask for its order. Like you have to know your boss' email address to ask him stuff. So, the UITableView class as a property called dataSource that means to store that address.
Now as a ViewController programmer, you have to set this property to be the address of the view controller that will give the order to that tableview.
2 ways of doing it :
in code : in the view controller, you have a property pointing to the tableview (if linked from the storyboard, it is called indeed an IBOutlet, but doesn't have to be) and you set it's delegate property to self. (meaning 'hey tableView, your boss is myself)
Or you do it in the storyboard, because the graphic template for the tableView let you ctrl+drag from the tableView to the ViewController and set the datasource connection. In this case it will be the storyboard who will have to find the address of the tableView (since it is the one creating it, it's kinda easy) and setting it's delegate property to be the address of the view controller (meaning hey tableView, your boss will be this guy)
Either way, the viewController has to be ready to answer all the question from the TableView, so conforming to the UITableViewDataSource protocol.
the delegate scenario is the same.
It is important to understand how the loading of views works in iOS. Your xib will be translated into the hierarchy of views and they are loaded onto the memory. When you make an IBOutlet of those views, you'll have a reference of that loaded view in your code. If you do not create an IBOutlet, it doesn't mean that the view isn't there. It is there and it is in the memory.
When you set the delegate and the dataSource of a tableView and when the tableView is loaded onto the memory, it sets the delegate and the dataSource of the loaded tableView to the class as specified by you. It doesn't matter if you do not have a reference to it.

When to use viewDidLoad and when to use awakeFromNib

I've gotten pretty comfortable using the viewDidLoad method to execute things I want done at the beginning of a view, but reading one of Apple's tutorials they set the data controller for the class in the awakeFromNib method and did nothing in the awakeFromNib. I swapped it and it seemingly worked identically in my app, but I'm not sure if it was better to have it in awakeFromNib or viewDidLoad.
When should I use either one?
awakeFromNib is called when the associated nib file with a class is loaded . Any class that can own a nib can use it. viewDidLoad is used only by view controllers. It is usually called when loading from nib as well but it can also be called by a view created in memory (very rare circumstance.). If you are using controllers, then I would suggest you to use viewDidLoad
For more Refer this Answer
viewDidLoad is associated with the view controller. If you need to initialize another control unarchived from the nib (e.g. UITableViewCell prototype) you cannot overload viewDidLoad, you need to overload awakeFromNib.

Xcode: Assigning an Object as a UITableView datasource/delegate in Interface Builder

I'm relatively new to Xcode.
I am trying to do this in Xcode's Interface Builder as much as possible. Because I am working with legacy code, Storyboards are not an option.
I'm working with a XIB I'll call DualTVController. It is based on a simple UIViewContoller.
In this XIB I have two UITableViews, the LeftTV and the RightTV. In IB, I am able to assign the delegate/datasource of the LeftTV to the File's Owner, which is the class representation of the XIB. This works fine.
I want to assign the delegate/datasource of the RightTV in IB. So far, I've successfully been able to use the LeftTV for this, but that's just confusing.
Instead, I have created a UITableViewController subclass called RightDelegate, and assigned it as the class of a simple Object I create through the IB. I made it follow the UITableViewDataSource and UITableViewDelegate protocols. This allows me to hook up the delegate/datasource of RightTV to it in IB, but when I try to run it, I get a BAD_ACCESS error.
I have the same delegate code in RightDelegate as I do in LeftTV (which works). Can anyone suggest the problem? Am I responsible for instantiating RightDelegate in code?
Thanks for any help.
note: I know you want to do this in IB, but in this case this is probably best handled in code. setting delegates for a single tableview in IB is simple, but eaisly overlooked. Since the delegates are so important, I usually keep them in code so there less mistakes.
when you are going to use more than one tableview there are a couple of ways to manage the delegates.
a) manage both delegates in your view controller with logic on each delegate callback to determine which tableview is asking (ends up messy)
b) split delegates by leaving one in your vc and putting the other in its own separate controller (somewhat confusing)
c) split delegates by using a separate tableview controller instance for each tableview. This is probably the best choice but it does require 3 controllers - your initial view controller that will init the xib file and then two separate tableview controllers - leftTable, rightTable.
in your main view controller, make sure you setup a property for each tableview:
then include your view controllers
then initialize the tableview controllers and set the delegates
//Example
self.rtv = [[rightTableViewController alloc] init]; //create a strong property for this
self.rtv.delegate = self; //let it talk back to you if needed
self.ltv = [[leftTableViewController alloc] init];
self.ltv.delegate = self;
self.rightTableView.delegate = rtv;
self.rightTableView.datasource = rtv;
self.leftTableView.delegate = ltv;
self.leftTableView.datasource = ltv;
Then just add code in each tableview controller to manage the tableviews.
If you need the tableview controller to call your main view controller then use delegate callbacks.
hope this helps, best of luck.

Merge two viewcontroller's code using addsubview in IOS

I want to break my code into 3 files and them up via addsubview. For ex. i have a masterview, mastreview contains a currentView. CurrentView contains 1 webview and 1 tableview.
Now, i have written all code in one file and it works like a charm. But i want to make it abstract and loosely coupled . So i need a separate file ex. webviewController to implement its delegate and function related to it AND tableviewController to implement its delegate and functions related to it. And add both by addsubview, alloc init in masterview file.
I did it my way,though i was able to addsubview on CurrentView, the problem was my delegate functions are not working properly.
Also, i am confused about tableviewController should inherit UIViewController or UIView or UITableView.
it would be good if anyone can guide or send some link related to it, any example...???
Actually you should have the app crashing if the delegates are not retained somewhere.
If you do link the object with view controller to be it's delegate at Interface Builder, the view controller will be destroyed after it's outlets so you don't care. If you are creating separate class for the delegate, you should care about it's lifecycle, standard classes do not retain their delegates so you have to retain it on the same level where you are retaining the delegated object. Like if you are creating a UITableView subview and you have MyTVDelegate class, you should create the delegate instance, assign it to tableView.delegate and retain as viewController var so that viewController will dealloc both subviews and their delegates when needed.
For the second question, UITableviewController inherits UIViewController as you can see at header files (command+click on UITableviewController), and UITableView inherits UIView. Every viewcontroller should have the root view of UIView and I believe UITableviewController has UITableView as it's root view.

Resources