I am currently making an app that will have multiple timers, which are basically all the same.
I want to create a custom class that uses all of the code for the timers as well as the layout/animations, so I can have 5 identical timers that operate independently of each other.
I created the layout using IB (xcode 4.2) and all the code for the timers is currently just in the viewcontroller class.
I am having difficulty wrapping my brain around how to encapsulate everything into a custom class and then add it to the viewcontroller, any help would be much appreciated.
Well to answer conceptually, your timer should likely be a subclass of
UIViewinstead ofNSObject.To instantiate an instance of your timer in IB simply drag out a
UIViewdrop it on your view controller’s view, and set it’s class to your timer’s class name.Remember to
#importyour timer class in your view controller.Edit: for IB design (for code instantiation see revision history)
I’m not very familiar at all with storyboard, but I do know that you can construct your interface in IB using a
.xibfile which is nearly identical to using the storyboard version; You should even be able to copy & paste your views as a whole from your existing interface to the.xibfile.To test this out I created a new empty
.xibnamed “MyCustomTimerView.xib”. Then I added a view, and to that added a label and two buttons. Like So:I created a new objective-C class subclassing
UIViewnamed “MyCustomTimer”. In my.xibI set my File’s Owner class to be MyCustomTimer. Now I’m free to connect actions and outlets just like any other view/controller. The resulting.hfile looks like this:The only hurdle left to jump is getting this
.xibon myUIViewsubclass. Using a.xibdramatically cuts down the setup required. And since you’re using storyboards to load the timers we know-(id)initWithCoder:is the only initializer that will be called. So here is what the implementation file looks like:The method named
loadNibNamed:owner:options:does exactly what it sounds like it does. It loads the Nib and sets the “File’s Owner” property to self. We extract the first object in the array and that is the root view of the Nib. We add the view as a subview and Voila it’s on screen.Obviously this just changes the label’s background color when the buttons are pushed, but this example should get you well on your way.
Notes based on comments:
It is worth noting that if you are getting infinite recursion problems you probably missed the subtle trick of this solution. It’s not doing what you think it’s doing. The view that is put in the storyboard is not seen, but instead loads another view as a subview. That view it loads is the view which is defined in the nib. The “file’s owner” in the nib is that unseen view. The cool part is that this unseen view is still an Objective-C class which may be used as a view controller of sorts for the view which it brings in from the nib. For example the
IBActionmethods in theMyCustomTimerclass are something you would expect more in a view controller than in a view.As a side note, some may argue that this breaks
MVCand I agree somewhat. From my point of view it’s more closely related to a customUITableViewCell, which also sometimes has to be part controller.It is also worth noting that this answer was to provide a very specific solution; create one nib that can be instantiated multiple times on the same view as laid out on a storyboard. For example, you could easily imagine six of these timers all on an iPad screen at one time. If you only need to specify a view for a view controller that is to be used multiple times across your application then the solution provided by jyavenard to this question is almost certainly a better solution for you.