how should I call a class for a timeline custom view? My project's prefix is HM.
HMTimelineView
or
HMTimeline
Shouldn't I name any view class with the suffix View? But why is it NSButton but NSImage**View**?
To me, HMTimeline sounds like it could be a model object, so I would recommend the "View" suffix, but this is a decision you'll have to make based on what you think makes your code easier to understand.
There may be naming rules regarding this that I'm not aware of, but I believe NSButton isn't called NSButtonView because a button is intrinsically a client-visible interface object--it doesn't present a specific model object and is unlikely to be confused for a model object, so it's convenient to leave off the suffix.
if it is inherited from UIView
then
HMTimelineView will be best
if it is inherited from NSObject
then
HMTimeline will be best.
u have to understand that
whenever anyone go to use urCustom objects like HMTimelineView,HMTimeline then then they will automatically come to know
"oh it would be from View" -for HMTimelineView.
"oh it would be from NSObject" -for HMTimeline.
If you object is just a view, then you can put view on the end of it. The difference in NSButton and NSImageView are because an NSButton has a view, it itself is not a just a view, it is a button :P. NSImageView is the view of the image, it has an image, but is the object to view the image.
There also isn't a "correct" way. Using HMTimeline by comparison to HMTimelineView will not break your code. Its just a way to help a developer understand what the object is.
The “View” suffix is used inconsistently in Cocoa. Generally speaking, NSControl and its public subclasses don’t use “View”, but there are some inconsistencies (like NSText). In general, a view that presents content (which I assume a “timeline view” does) should have a “View” suffix.
This highly depends on your preferences, I guess, and understandability of the whole set of class names that make up your app. Much also depends on conventions that you will simply learn by looking at how other code is written, mostly the same SDK.
I think that HMTimelineView is far more understandable than HMTimeline. You also have to think that possibly you will have a HMTimeLineViewController, so HMTimeLime would be possibly ambiguous. Think of this, if you want: views, controllers, and models play a role in a design pattern (MVC) so that it is useful to identify them with a suffix. The same can be said for delegate classes, where the suffix is also usual.
About NSButton, it certainly derives from NSView, but its direct class is NSButton; so, in a sense, I think that its "control nature" prevails on the view nature, and NSButton is far more understandable then UIButtonView.
Hope this helps.
Related
I have a custom graphic that is to be displayed to a user when an event occurs. The graphic needs to be displayed on whichever viewController is currently being displayed to the user.
The way i have programmed it so far is by adding to ALL viewcontrtollers:
1) the .h file for the custom graphic class
2) an observer for the NSNotification event that is raised
3) the method which actually draws the graphic.
This doesnt feel like a very efficient way of doing things and i was wondering if anyone has a better way of doing things?
To me it sounds like you've done it in a fairly sane way. The only other way I can think is to just add the graphic to the window which would then overlay on the current view controller and you'd only need to have one object listening for the notification. You could use the app delegate for instance. But then you would have to worry about rotation of the screen yourself when adding the graphic over the top.
What you are doing is correct .. The only thing you can improve is to mauve the drawing graphics part to the custom graphic class.. (if you are not already doing so...
just Make a UIViewController variable as a member variable to the graphics class..and then set it up to the current view displaying..after you receive the notifications..and the class will itself draw the code based on the ViewController you set it up to
The reason it doesn't feel efficient is that you're duplicating a lot of code. That's more work at the outset, and it creates a maintenance headache. You should be taking advantage of the inheritance that's built into object oriented languages, including Objective-C.
If you want all your view controllers to share some behavior, then implement that behavior in a common superclass. Derive all your other view controllers from that superclass, and they'll all automatically get the desired behavior. Your superclass's initializer can take care of registering the view controller for the notification(s) that you care about, and -dealloc can unregister it. This way, you don't have to clutter up each view controller with the same repeated code, and if you want to change the code you only have to do it in one place.
I am learning iOS programming through the Big Nerd Ranch guide by Hillegass and Conway. I’m writing an app of my own as I go through the book, and one of the questions that has been bugging me is exactly when I need to subclass UIViewController (and its ilk) and when I can just instantiate it.
For example, my app consists of generic building blocks: the interface is tabbed, and the tabs lead to a UITableView, a UINavigationController that creates UITableViews, and so on. Following the book’s instructions, I have subclassed UITableViewController to create the table views. However, in creating the UITabBarController that contains all of my app’s content, it seems sufficient to instantiate a UITabBarController and then add a bunch of views to it. (All of this is done in the application:didFinishLaunchingWithOptions: method of my app delegate. Since most of my app consists of simple combinations of basic UI parts, I’m trying to do build the UI programmatically whenever possible.)
I get the impression that what I should be doing is creating a subclass of UIViewController (or UITableViewController or whatever) for every interface in my project. This seems weird to me, since most of these classes would only ever be instantiated once. Am I just misunderstanding how OO should be used in this case? (I have a good amount of programming experience but relatively little has been with OOP.) Should I be creating a subclass for each and every screen that the user will see?
Should I be creating a subclass for each and every screen that the user will see?
If each view requires different logic, yes.
Don't shy away from creating new classes for conceptually separate things. Programmers coming from non-OOP to OOP might feel that a file with only a small amount of code is a waste. Suppress this feeling. Classes are cheap, and help enormously to organise your thinking.
So you have two types of UIViewControllers in iOS. "Container" viewControllers and "Content" viewcontrollers. Both are subclasses of UIViewController but have very different purposes.
The Container type is what the UINavigationController and UITabController are. They are rarely subclassed and typically used as is (in fact, I believe Apple doesn't allow the subclassing of UINavigationController at all). These "Containers" take care of moving "Content" view controller around for you. They do not have much content of their own, beyond adding things like a tab bar or a navigation bar.
The "Content" view controller are the ones you create most of the time. You will rarely be able to use a UIViewController as is, because it will not have any functionality. That is why you subclass them. These are meant to represent a single "screenful" of content. So in effect, every "screen" the user sees should be controlled by a UIViewController subclass.
The UITableViewController is simply a specialized sublass of UIViewController that already contains some methods for managing tables.
The way the UIKit framework was designed was for you to use subclasses of UIViewController to display content and to use out-of-the-box "Container" controllers to facilitate the management of your UIViewController subclasses.
You need a subclass of UIViewController if you want to do any of the following (not an exhaustive list, but some examples)
customize the view hierarchy when the view hierarchy is loaded (in
viewDidLoad)
provide some behaviour as the view controller's views become visible
(or not) (in viewWillAppear:, viewDidAppear:, viewWillDisappear:,
etc.)
clean up after yourself as needed in viewDidUnload
create outlets to views in the hierarchy so you can adjust them as
needed in the above lifecycle methods
My reasoning behind subclassing UIViewController, and other classes is that:
Almost always you must initialize variables and assign values to the instances of classes. You add subviews and set their frames, define actions for the UIViewController instance, etc. If this UIViewController instance is directly from the base class, its initialization should be done outside of it. If this initialization is required at different places for multiple times, you may have to deal with repeated initialization process.
So, you've compiled these processes into a method, making it reusable from wherever this UIViewController instance is used. But where do you want to put it? Don't you think it's much better to put it inside the subclass of UIViewController? Also, you don't even have to come up with specific name for this initialization method. Just override the default -(id)init from the super class.
Though you may think it's suffice to use UIViewController without subclassing it for now, as your project grows, it will be challenged to deal with reusability issues. Take some time to look at your codes. Check if there is too much repetition for such as initializing an object, or assigning values to it. If you are doing same things with an instance of a class in multiple places, compile them into a method to be reused. And as number of such methods grow, you will find the need to use subclass which will contain these relevant methods for the instance.
No matter the size of your project, using classes to distinguish different objects is important. Almost always, the basic essential classification is done by the framework, making it unnecessary to introduce new concept for a class. However, this doesn't mean the framework also knows how your project and its objects can be classified into. By using subclass, you can utilize every benefit the development framework can provide and still keeping the objects in your project to be as unique as possible, based on the purpose you've designed for them.
Well about the UITabBarController you are right. There is no reason for you to subclass anything if the default behavior is sufficient. However once you need to do some custom things you will need to subclass it..
Also, why are you trying to build the GUI programmatically? For the learning curve? There is no real reason not to use InterfaceBuilder, it saves you a lot of time.
You should subclass the UITableViewController in order to get your data in the view, that is how the MVC model works. The default implementation does not offer anything in order to get your data in the view, I don't think they will ever do that in order to make sure that nothing is wasted, their 'connection' to the model object might be different from the one you want and you would end up writing an adapter if your model object is not compatible.
I hope this will help you out a bit.
And merry x-mas.
I'm writing a program for iPhone that will first let the user take a photo, then will dynamically retrieve a colour of the place where the user taps on the image, and draw a rectangle of that colour. I have two relevant classes for this: AppViewController and AppView. The former contains all the UI elements and IBActions, the latter the position of last tap, the touches-handling methods and the drawRect (and a static method to get colour data at a given coords of an image).
What I wanted to do is to put the touch-handling (calling drawRect in touchesMoved/Ended) and the drawRect in the AppViewController. That doesn't work, since that class doesn't inherit from UIView, but from UIViewController. What's the correct way to do that?
Another way to phrase that: How to constantly change something (well, constantly as long as the user is swiping across the screen) in a class that doesn't support touch-detection methods?
(This probably doesn't explain it well. Please ask clarifying questions).
I think the delegate pattern might be helpful to you in this situation. You could call your delegate's shouldUpdateRectangle selector in touchesMoved/Ended.
There is not really a correct way to move the view's behaviors into a view controller, since that is not the way the classes are meant to be used. You should probably look at what's driving you to try to subvert the framework's design this way, because that is likely going to be easier to fix.
It's not uncommon, though, for a view to call out to a supporting class for help in this stuff. You could certainly have your view's drawRect: call methods in the view controller, though I would be careful about mixing their concerns too much, because it could get hard to figure out who's responsible for what.
I have a strong j2ee background, and I am trying to move to objective-c for some desktop/iphone programming.
I used many java web frameworks with mvc in mind, spring and struts ecc... so I am used to have servlet or controller which pass attributes to jsp pages, which is the view.
In jsp pages with jstl you can call this attribute and render to video.
In this way controller and view are (in theory) clearly separated.
With xcode, I can easily recognize the controller and the view built with IBuilder.
All the tutorial I found, shown the controller which go and change directly labels or text fields.
So my two questions:
seems to me that there's no separation between the two (controller and view), where I am wrong in that ?
is there a way for a controller to pack all objects in a kind of context in a j2ee way and have the view read that context ?
thanks
Leonardo
In most of the examples you have read you probably saw something like this:
[myTextfield setStringValue:myString];
now in this case sure the controller is updating the textfield directly, however as myTextfield is usually an IBOutlet it can be any textfield in your view, or even nil. quite possibiy it doesn't even need to know that it is an NSTextfield just that it responds to a setStringValue method. In this sense there is a seperation between the controller and view.
Now in your comments above you were concerned with seperation of responsibilities within MVC but did not mention the model much. With Cocoa bindings you can bind directly to model keypaths, in this case the model neeed not know anything at all about the view.
MVC is a bit of an ambiguous concept with no hard definition. It can mean different things to different people. For me it means that the view has knowledge of the controller ( through outlets or bindings) limited knowledge of the model(through bindings). The contoller has full knowledge of the model and limited knowledge of the view(through outlets). Finally the model has zero knowlege of the view and ideally no knowledge of the controller.
With regard to your second question, I don't use j2ee, but I think you can acheivee what you want by having your controller update a context ivar ( probably a NSDictionary) then in your view bind to this context with a keypath. However there is no real need to wrap everything up bindings are very versitile and u can bind to any property.
I do not understand your second question (I've never used J2EE), but I think I can make some headway answering your first.
Cocoa does not enforce MVC; it just strongly encourages it -- especially for larger projects. Consider an example program, one that has an NSTableView bound to an NSArrayController.
In this case, the NSTableView is clearly the view (it has the word "view" in its name) and the NSArrayController is clearly the controller (it has the word "controller" in its name).
The model is an NSArray that the NSArrayController knows about, but you probably don't interact with that model directly. You will instead ask the NSArrayController to manipulate its model by sending addObject: and removeObject: messages to the array controller (and not to the array itself).
When you do this, the NSArrayController will effect a change in the NSTableView via bindings. Again, you don't ever ask the NSTableView to do anything.
So you never talk to the view and you never talk to the model. Everything you want to happen goes through the controller.
MVC. QED.
Of course, maybe the way your project works, the view should be its own controller. The world won't end, although you might find it to be a little more difficult to go against the grain of the framework. But you should always try to use the best approach for the job at hand instead of insisting on some sort of design pattern purity.
I've a fairly complex window that is backed by a controller class that is obviously growing to meet the needs of my view window. While I believe I am sticking to proper MVC I'm still having problems managing a fairly largish controller class.
How do you breakdown your objects? Maybe use Categories? For example, one category to handle the bottom part of the window, another category to handle my NSOutlineView, another category to handle a table, and so on and so forth?
Any ideas or suggestions are welcome.
It sounds like it's a complex window controller that's growing to unmanageable proportions? This is getting to be a more common issue because of applications which, like the iApps, do most of their work in a single window.
As of Leopard, the recommended way of breaking it down is to factor out each part of the window into its own NSViewController subclass. So, for example, you'd have a view controller for your outline view, and a view controller for each of your content views, etc.
Also, I'd like to second the use of #pragma marks to divide code files up into segments, and in addition to categories, I also like to use class extensions for private methods.
It's a simple answer, but the code folding feature of the Xcode IDE can be handy for focusing your attention on sections of a class. Another little thing that might help is going to View->Code Folding and turning on Focus Follows Selection. This makes it so the background color of the scope of your current selection is white while everything else is shades of gray.
Categories are ideal for this. Create a new file for each category, and group them by functionality, as you suggested.
I've tried using Categories in situations like this and I just end up confusing myself, wondering how in the world I'm calling that method when it's "obviously" not in the class I'm looking at.
I'd recommend liberal use of #pragma mark in your source code. Makes it super-easy to browse through all your methods.