patternMinor
Calculator ViewController
Viewed 0 times
viewcontrollercalculatorstackoverflow
Problem
Coming from Java and Android development and Objective-C still is a bit strange to me, but I just went in head first and started writing code. Before I started getting really far into it, I just want to throw some basic code here for suggestions about correct syntax, etc. I just want to make sure that my variable and function declarations are correct as well as the way I refer to UI elements is the recommended method.
I was told to make a separate
Then inside the CalculatorViewController.m file I ended up with the following code snippets:
```
// UI FUNCTIONS
// Reset all nutrion fact fields.
_fatTextField.text = @"";
_carbsTextField.text = @"";
_fiberTextField.text = @"";
_proteinTextField.text = @"";
_servingsTextField.text = @"";
// Reset food name & points label
_foodnameTextField.text = @"";
_pointsLabel.text = @"Points: 0";
// Set Fat as firstresponder
[self.fatTextField becomeFirstResponder];
}
float fatFloat = [_fatTextField.text floatValue];
float carbsFloat = [_carbsTextField.text floatValue];
float fiberFloat = [_fiberTextField.text floatValue];
float proteinFloat = [_proteinTextField.text floatValue];
float se
I was told to make a separate
ViewController class for each UI I build as below:@interface CalculatorViewController : UITableViewController
@property (weak, nonatomic) IBOutlet UITextField *fatTextField;
@property (weak, nonatomic) IBOutlet UITextField *carbsTextField;
@property (weak, nonatomic) IBOutlet UITextField *fiberTextField;
@property (weak, nonatomic) IBOutlet UITextField *proteinTextField;
@property (weak, nonatomic) IBOutlet UITextField *servingsTextField;
@property (weak, nonatomic) IBOutlet UITextField *foodnameTextField;
@property (weak, nonatomic) IBOutlet UILabel *pointsLabel;
- (IBAction)calculate:(id)sender;
- (IBAction)reset:(id)sender;
- (IBAction)addtotracker:(id)sender;
- (void)resetCalculator;
- (void)calculatePoints;Then inside the CalculatorViewController.m file I ended up with the following code snippets:
```
// UI FUNCTIONS
- (void) resetCalculator {
// Reset all nutrion fact fields.
_fatTextField.text = @"";
_carbsTextField.text = @"";
_fiberTextField.text = @"";
_proteinTextField.text = @"";
_servingsTextField.text = @"";
// Reset food name & points label
_foodnameTextField.text = @"";
_pointsLabel.text = @"Points: 0";
// Set Fat as firstresponder
[self.fatTextField becomeFirstResponder];
}
- (void) calculatePoints {
float fatFloat = [_fatTextField.text floatValue];
float carbsFloat = [_carbsTextField.text floatValue];
float fiberFloat = [_fiberTextField.text floatValue];
float proteinFloat = [_proteinTextField.text floatValue];
float se
Solution
There are a lot of takes on how to structure things in Objective-C, largely based on the age of the language. It used to require you to use x, but now it lets you use y, kind of things. I like to go with the minimalist/OOAD-purist approach.
Your Header File
Your header file (CalculatorViewController.h) is your public interface for your class. This is what every other class sees when it compiles against it and has access to. As such, I keep it light. You don't want another class to set your
Highlighted lines:
Your Implementation File, Class Extension
Now that you've removed all those properties from your public header, you're getting compiler errors and need to stick them somewhere. The right spot is in your class extension, the thing that looks like a category but isn't. Xcode should have generated it as follows at the top of CalculatorViewController.m
Just stick all your
As far as the method declarations, you don't need them. In C you need to declare functions ahead of time, but not with modern Objective-C. The only reason you need to declare them is if you're trying to expose them outside of your implementation.
Your Implementation File, Implementation
Things look good here. Just a couple things:
-
Directly accessing instance variables (ivars), e.g.
-
There's no reason to have both
-
The most important thing
No matter what style, or principles, or philosophies you adopt as an iOS developer, every other iOS developer will disagree with you, and you with them. Maybe it's the awesomeness/awfulness of the language or the tools or the platform or the status, but its a very opinionated group of developers.
Your Header File
Your header file (CalculatorViewController.h) is your public interface for your class. This is what every other class sees when it compiles against it and has access to. As such, I keep it light. You don't want another class to set your
fatTextField and if you did, you wouldn't want them to know the intimate details of how your form works so you'd pass a model object or something. I like my header to look like this:@class ImportantStuff; // 4
@protocol CalculatorViewControllerDelegate; // 5
@interface CalculatorViewController : UITableViewController
- (id)initWithImportantStuff:(ImportantStuff *)importantStuff; // 1
@property (nonatomic, weak) id delegate; // 2
@property (nonatomic, readonly) ImportantStuff *importantStuff; // 3
@end
@protocol CalculatorViewControllerDelegate // 6
- (void)calculatorViewController:(CalculatorViewController *)calculatorViewController
didFinishWithImportantStuff:(ImportantStuff *)importantStuff;
@endHighlighted lines:
- Create an initializer with everything you need to get the class started on work.
- Add a delegate or some other message passing pattern to send notifications back.
- Maybe, have some exposed properties for information that interfacing classes may want.
- As general practice, you should only reference the bare minimum number of headers in your header since it reduces circular dependencies and compile time.
@classtells the compiler that a class with that name exists and it shouldn't worry about the details.
- With delegates you often have a chicken and egg scenario. The class references the protocol and the protocol references the class. Like with
@classyou can say you'll inherit it later.
- Populate your delegate with meaningful hooks.
Your Implementation File, Class Extension
Now that you've removed all those properties from your public header, you're getting compiler errors and need to stick them somewhere. The right spot is in your class extension, the thing that looks like a category but isn't. Xcode should have generated it as follows at the top of CalculatorViewController.m
@interface CalculatorViewController ()
@endJust stick all your
@property's there.As far as the method declarations, you don't need them. In C you need to declare functions ahead of time, but not with modern Objective-C. The only reason you need to declare them is if you're trying to expose them outside of your implementation.
Your Implementation File, Implementation
Things look good here. Just a couple things:
-
Directly accessing instance variables (ivars), e.g.
_pointsLabel has gone out of fashion. There's a lot of reasons for this with potential risks associated with both doing it and not doing it, but there's even a pedantic compiler warning you can turn on to catch it. Generally, you should use ivars only in getters, setters, and initializers, places where you need direct access or want to suppress side effects.-
There's no reason to have both
-reset: and -resetCalculator. There are two interesting points here: First, somewhere in the codebase exists #define IBAction void so you can turn any void returning function into an IBAction assuming it has the right arguments. Second, controller actions support three structures: -(IBAction)myAction:sender, -(IBAction)myAction:sender event:event and -(IBAction)myAction with no arguments. You can just use -(IBAction)resetCalculator.-
addToTracker, with camel case. Probably just a typo considering everywhere else. Be aware that Interface Builder provides zero compile time checking so if you change the signature or remove a method you must edit it in Interface Builder or it will crash your app.The most important thing
No matter what style, or principles, or philosophies you adopt as an iOS developer, every other iOS developer will disagree with you, and you with them. Maybe it's the awesomeness/awfulness of the language or the tools or the platform or the status, but its a very opinionated group of developers.
Code Snippets
@class ImportantStuff; // 4
@protocol CalculatorViewControllerDelegate; // 5
@interface CalculatorViewController : UITableViewController
- (id)initWithImportantStuff:(ImportantStuff *)importantStuff; // 1
@property (nonatomic, weak) id<CalculatorViewControllerDelegate> delegate; // 2
@property (nonatomic, readonly) ImportantStuff *importantStuff; // 3
@end
@protocol CalculatorViewControllerDelegate <NSObject> // 6
- (void)calculatorViewController:(CalculatorViewController *)calculatorViewController
didFinishWithImportantStuff:(ImportantStuff *)importantStuff;
@end@interface CalculatorViewController ()
@endContext
StackExchange Code Review Q#36088, answer score: 5
Revisions (0)
No revisions yet.