I am writing an application for OSX in Swift. I use a NSTableView.
I created a custom class which implements NSTableViewDataSource and NSTableViewDelegate. Now I would like to mark this custom class as delegate and datasource of my TableView but, I can’t find how to do that.
The only way I found out to do that is : Create un Ojbect in the interface builder. Add it in my view put my custom class as class of the object. And finally link the object as datasource and delegate of the TableView.
This way doesn’t seem to be clean. Does someone have an idea to solve my problem ?
let myObject = MyClass()
tableView.delegate = myObject
That should do the trick. A bit cleaner than using Interface Builder.
Create an instance of your custom class that implements those protocols where you have your NSTableView. Then set the delegate and datasource properties to the instance that you created
Related
I understand how to use delegation with iOS objects that already exist. For example, if I create an instance of a UITableView, and my view controller conforms to the UITableView delegate, I can implement the various methods of the UITableView delegate. My newly create table can receive notifications, for example, when didSelectRowAtIndexPath is called.
My question is why did my table get this particular delegate callback? My understanding is that the delegate is just a list of methods with no implementation. It seems to me there must be a lot more going on. What is really going on "behind the scenes"?
Image if I were to rename all the delegate methods to the following:
- mysteryMethod1
- mysteryMethod2
- mysteryMethod3... Etc
One of these methods is responsible for setting the height of a row at a particular index. Another one these methods will be responsible for editing a particular row.
Everything I read about delegation says the delegator makes a contract with the delegate. The delegate promises to implement the methods. When it does, somehow everything is wired up correctly and everything magically works. What is the magic that I'm not seeing?
I think that in order to know how delegates actually work you should create your own custom delegate first, that way you will see that there is no magic under the hood, you probably can't see the implementation of the actual apple build in delegate methods but I assure you that there is a lot of logic implemented in those but it's just not available for privacy reasons I assume.
When you create your custom delegate let's say for example...
You have Class A and in this class, you start by creating a protocol
protocol ClassADelegate: class {
func changeBackgroundColor(_ color: UIColor?)
}
In this class you have a delegate property like this.
weak var delegate: ClassADelegate?
Let's say that this class is a Viewcontroller and you have an IBACtion on it like a UIbutton, and your goal is that when you tap that button another ViewController in your app change its background color to blue. Inside this action in Class A you do this...
func someAction() {
delegate?.changeBackgroundColor(.blue)
}
,
Let's say that the "magic" happens here in class A, by the way if you are thinking in delegates using UITableview think that UItableView is class A.
ok so now you have Class B that is where you want to change the color right?
Well now class B needs to conform to the protocol like this, just like you also conform to the protocol UITableViewDelegate etc.
class ClassB: UIViewController, ClassADelegate {
}
Now think of the word delegate for a second and think what that means, you are just delegating responsibility to somebody else, right? and yes, in this case, ClassB is going to be the delegated, for that we need to have an instance of Class A in class B just to have access to it's delegate property.
let classa = ClassA()
classa.delegate = self
the final step is just to call the method of the protocol like this..
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}
To conclude if yo see this method in your class but you don't have access to the implementation of the protocol, you will ask yourself "where does this magic color coming from??" but as you saw it just comes from another class where a protocol belongs to, hope this helps.
I m using Xamarin for iOS and I have a custom View which inherit from UIView.
I would like to add a custom delegate to that view.
So far I found that:
Delegate (not useful) example
I want my delegate to be on his own and won't inherit from any other known delegate.
There is no delegate property on UIView (see Apple docs). It does exists in some subclasses, like UITextView (and other types).
What you can do (beside using the base classes provided) is:
(with the unified API) create your own classes that implements the IUITextViewDelegate interface and assign it to the Delegate property;
Create any class that conforms to the delegate (i.e. minimally all required members), add the required [Export], and assign it to the WeakDelegate property.
Is it possible to use a delegate of superclass on subclass
Example: Class A is superclass of class B and superclass A uses the text view method example textviewDidChange. can I somehow call [super textViewDidChange] of superclass A on Subclass B even it isn't on header file of class A
if i rediclare the method on subclass B
When you specify UITextViewDelegate, you're telling the compiler that your class meets the specifications for a UITextViewDelegate. If class A has all the requirements for a UITextViewDelegate, and class B is a subclass, then it too will have all the requirements. Nothing will stop you from assigning any instance as a delegate, so you still have to be careful with that.
Yes,you can. Since class A confirms <UITextViewDelegate> protocol there is no need to redeclare them in header file. Just make sure it implements needed methods.
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?
I am writing a custom subclass of UITableView. I would need this object itself to be its own data source and delegate, and this subclass would then have its own data source and delegate. This is done primarily so I can intercept calls to the datasource and delegate and potentially augment them before sending them off to their actual datasources.
My class is defined as so.
CustomTableView : UITableView<UITableViewDelegate, UITableViewDataSource> {
...
id customDataSource;
id customDelegate;
}
The problem comes when I try to set my data source and delegate.
I would like to override uitableview's properties:
- (void)setDataSource(id<UITableViewDataSource>)ds {
[super setDataSource:self]
customDataSource = ds;
}
Basically, I would like to tell the parent class(UItableView) to set the data source to self. I would then forward any callbacks to the customDataSource, after I have modified them.
[super setDataSource:self] doesnt crash, but the datasource never gets set. Does anyone have any ideas? Thanks
I ended up not needing to use the method proposed in this question, but I did get it working. The problem was that I had accidentaly synthesized the properties that needed overriding, namely dataSource and delegate.
For people who need to do this in the future, simply override setDelegate and setDataSource in your custom subclass.
Dont assign the datasource to self. Create an intermediate object, which you contain in your CustomTableView, and set the datasource to that. Call it DataSourceInterceptor or something.
Another way to accomplish this would be to method-swizzle the datasource object that is being set.