Join Simon Allardice for an in-depth discussion in this video Creating custom controller classes, part of Cocoa Essential Training.
We haven't written a lot of code yet, but what we have written, we have put all in the existing AppDelegate class just because that class was there already. I have a very simple, straightforward interface here with one-button. If I right-click the button, or use the Connections Inspector, I can see that the target of this button click is App Delegate, and the action it will perform is simpleMethod. And just jumping over into that in the AppDelegate implementation file, all that's going to do is, in NSLog message to the console, to the debug area.
So if I run it, I would expect that when I click the button, I will just have the debug area appear, and we'll get that message popping up. All right, but what I prefer is to have the AppDelegate act just as the application delegate, and I want to have a dedicated controller class where I write my code that reacts and behaves and interacts with the interface, and it is very simple to do this. So I will just stop the running program and jump back over here into my project. And here is the thing, to create a CustomController class it doesn't have to be anything special, any particular kind of subclass. Just a regular plain Objective-C class will work.
So in Xcode, I am going to go the New > File section, select Cocoa and Objective-C class, it actually wouldn't really matter if you are under Cocoa Touch, the basic Objective-C class is the same for both. Selecting that, I click Next, I will call this Class MyController. I could call it anything, the name is not important. The dropdown box beneath gives us many different classes we could inherit from, but I'm just going to select NSObject right at the top, the most basic Objectives-C class there is, and then choose to save that in my project.
So the class exists, there is nothing in it, nothing in the header, nothing in the Implementation file, and the XIB, the interface does not know about this class, there is no link between this and the MyController class, so let's make one. Here is the easiest and best way to do it. I am going to open up the Utilities panel and go to my Object Library, now I could scroll down and find the thing that I want here, but it's easier just to filter on the objects and controllers section of that Object Library. Usually, what we use the Object Library for is for dragging and dropping things like buttons and text fields and sliders, but we can also use it to represent non-visual elements, in this case an Object.
So I am going to grab this Object, blue box, but instead of dragging onto the interface, I am going to drag it over here into the Dock just right at the bottom here, and I can do this whether the Dock is expanded or collapsed. Usually, we drag on these visual UI elements, that means that any user interface element, any object we drag into this XIB will be instantiated when this program loads, but we can do this with any object, including a class we just wrote ourselves, that means I won't have to write a manual alloc and init to instantiate that MyController object. It will happen here, however, I need to do one more thing.
Dragging on the blue object is the easy part, and the next thing is easy too. But this is the important part, with Object selected, I want to go to the third inspector in my Inspector section, which is the identity inspector. Because just by dragging this on from the Object Library, it thinks it's an NSObject. Well I don't need it to be an NSObject, I need it to be a new instance of the MyController object that I had, I should be able to type in--there we go--M, and find it, and just hit Return to set that.
Now if I mouse over it, this is what I'd expect to see, MyController, and now when the main menus xip is loaded, it will create an instance of this MyController class just as it creates an instance of all the visual elements that have been dragged on. I don't need to write code to instantiate it, it'll just happen. Now I can use this to write code that interacts with this user interface, so I am going to drag on another button onto this interface here, onto the Window. Just give it a basic name change, and then give myself a bit more screen real estate so that I can open up the Assistant Editor.
Now bear in mind now that the counterpart of this XIB file could be multiple code files, so you will probably need to use the Jump bar to change to a different one, in my case I want to jump to the MyController.h, the header file here, and now I should be able to hit the Ctrl key and drag into this new class. It's going to pop up. Do you want to make an Outlet or an Action? I want to do an Action here for sure. What do I want this to be called? Well, I will also call this simpleMethod, I could actually use the same name that was in the other class, it doesn't matter, they are completely independent of each other.
Click Connect, and we get the simpleMethod declaration in the header file, but if I also a jump over into the implementation file, I'll see the method stub over there, and I will just put an NSLog message in that one too. So just to verify this, right clicking that new button will say that we are going to the target of MyController, calling the simpleMethod as an Action. And in this one, we are doing AppDelegate as a target and doing simpleMethod there as an Action. Go ahead and run this, Build Succeeded.
I can call the first one, to Call a method in AppDelegate class, and I can call the second one to run code in the new MyController class. So very easy to start to break this out, it would be very simple for me now to copy any of the methods that I might have put in AppDelegate and move them across to the new class, if I wanted to keep them separate from each other. And if it made sense, I could even add more controller classes
- Installing the tools
- Creating your first app
- Adding basic interactions
- Understanding the Cocoa application life cycle
- Creating custom controller classes
- Creating alerts
- Understanding delegation
- Working with buttons, text fields, sliders, and more
- Using layout and data views
- Adding and editing toolbars
- Using key-value coding
- Binding objects
- Debugging code
- Distributing an application
- Creating icons and full-screen apps