I am trying to reorganise an early project by separating code that belongs in a UIView
from code that belongs in a UIViewController
. Answers to a popular question (found here) don’t seem to address what I need to do so let me illustrate my question with two examples.
- Example 1
Here the method setBackground:zone
changes the background colour of a view to indicate various states in the app. The method as shown below currently works and I want to relocate the code to a view where it belongs.
ViewController.h
#import <UIKit/UIKit.h>
#import "CustomView.h"
@interface ViewController : UIViewController {
}
@end
ViewController.m
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
int zone = 1; // or 2 or 3;
self.view = [[UIView alloc] initWithFrame: [UIScreen mainScreen].bounds];
[self setBackground:zone];
}
- (void)setBackground:(int)zone {
switch (zone) {
case 1:
self.view.backgroundColor = [UIColor orangeColor];
break;
case 2:
self.view.backgroundColor = [UIColor cyanColor];
break;
case 3:
self.view.backgroundColor = [UIColor greenColor];
break;
default:
break;
}
}
- Example 2
In the code below I tried initialising background colour in CustomView
by using getters and setters to reference the value of zone
in ViewController
(appropriate as ViewControllers
in the original project already get and set zone
to change background colour).
CustomView.h
#import <UIKit/UIKit.h>
@interface CustomView : UIView {
UIViewController *parent;
int selectedZone;
}
- (void)setParent:(UIViewController *)parent;
- (int)getSelectedZone;
@end
CustomView.m
#import "CustomView.h"
@implementation CustomView
- (void)setParent:(UIViewController *)theParent {
parent = theParent;
}
- (int)getSelectedZone {
return selectedZone;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:[UIScreen mainScreen].bounds];
if (self) {
NSLog(@"selectedZone in CustomView is seen as %i", [self getSelectedZone]);
int zone = [self getSelectedZone];
[self setBackground:(int) zone];
}
return self;
}
- (void)setBackground:(int)zone {
switch (zone) {
case 1:
self.view.backgroundColor = [UIColor orangeColor];
break;
case 2:
self.view.backgroundColor = [UIColor cyanColor];
break;
case 3:
self.view.backgroundColor = [UIColor greenColor];
break;
default:
break;
}
}
ViewController.h
#import <UIKit/UIKit.h>
#import "CustomView.h"
@interface ViewController : UIViewController {
int selectedZone;
}
- (void)setSelectedZone:(int)zone;
- (int)getSelectedZone;
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
int zone = 1; // or 2 or 3;
[self setSelectedZone:(int)zone];
NSLog(@"selectedZone in ViewController is now set to %i", [self getSelectedZone]);
self.view = [[UIView alloc] initWithFrame: [UIScreen mainScreen].bounds];
CustomView *cv = [[CustomView alloc]init];
[self.view addSubview:cv];
}
- (void)setSelectedZone:(int)zone {
selectedZone = zone;
}
- (int)getSelectedZone {
return selectedZone;
}
I can tell my code above does not work because getSelected:zone
in CustomView
cannot reference zone
set by setSelected:zone
in the ViewController.
But I don’t understand why.
2017-04-05 07:04:26.126 ZoneIndicator[1865:1270743] selectedZone in ViewController is now set to 1
2017-04-05 07:04:26.126 ZoneIndicator[1865:1270743] selectedZone in CustomView is seen as 0
But an article found here has even made me question whether using getters and setters is the best approach - especially this:
The biggest danger here is that by asking for data from an object, you are only getting data. You’re not getting an object—not in the large sense. Even if the thing you received from a query is an object structurally (e.g., a String) it is no longer an object semantically. It no longer has any association with its owner object. Just because you got a string whose contents was “RED”, you can’t ask the string what that means. Is it the owners last name? The color of the car? The current condition of the tachometer? An object knows these things, data does not.
So how do I pass the message from a parent UIViewController to a method in a UIView class ?