iPhone UIViews - how to associate variables with UIView? - iphone

I am new to iphone and xcode. This may be a very simple question but I could not find an example code in books. I want to do the following:
Have 2 UIView on the screen
Each view will step through the color of the rainbow (red/orange/yellow/green/blue/indigo/violet) using gesture recognizer, e.g., if the current color is green, if the user swipes up the UIView changes to yellow, if the user swipes down the UIView changes to blue.
Hence, each view will need to keep the current color and respond to the swipes accordingly.
I understand how to implement the detection of swipes using gesture recognizer but I don't know how to have each view keep a separate variable for the current color. I want a generic code because there will be more than 2 UIViews in my application once I figure out how it is done.
Thanks in advance.

You can subclass UIView to include any variables that you like:
ColorSwiperView.h
#interface ColorSwiperView : UIView
{
ColorType currentColor;
}
#property (nonatomic, assign) ColorType currentColor;
#end
ColorSwiperView.m
#implementation ColorSwiperView
#synthesize currentColor;
- (id)initWithFrame:(CGRect)frameRect
{
if ((self = [super initWithFrame:frameRect]) == nil) { return nil; }
currentColor = red;
return self;
}
#end
To be used as follows:
#import "ColorSwiperView"
...
ColorSwiperView * cView = [[ColorSwiperView alloc] initWithFrame:...];
cView.currentColor = green;
Note: this assumes that you have defined an enum for the colors:
typedef enum
{
red = 0,
green = 1,
...
}
ColorType;

perhaps defining a subclass of UIView something like:
#interface RainbowView : UIView {
UIColor *currentColor;
}
#property (nonatomic, retain) UIColor *currentColor;
#end
and creating 2 (or more) views of that class in your view controller as outlets (if you're using interface builder):
#class RainbowView;
#interface RainBowViewController : UIViewController {
RainbowView *rainbowView1;
RainbowView *rainbowView2;
}
#property (nonatomic, retain) IBOutlet RainbowView *rainbowView1;
#property (nonatomic, retain) IBOutlet RainbowView *rainbowView2;
#end

Since you are going to maintain an array of colors, say colorsArray, and assign views their color from that selection. You can do this in the swipe handler.
- (void)handleSwipe:(UISwipeGestureRecognizer*)swipeGesture {
UIView *view = swipeGesture.view;
NSInteger currentColorIndex = [colorsArray indexOfObject:view.backgroundColor];
NSInteger nextColorIndex = currentColorIndex + 1;
if ( nextColorIndex == [colorsArray count] ) {
nextColorIndex = 0;
}
view.backgroundColor = [colorsArray objectAtIndex:nextColorIndex];
}
This way you don't need to subclass.
Subclassing
You can subclass UIView and add your own instance variables to it. Say,
#interface RainbowView: UIView {
NSInteger currentColorIndex;
}
#property (nonatomic, assign) NSInteger currentColorIndex;
...
#end
#implementation RainbowView
#synthesize currentColorIndex;
...
#end
In your gesture handling method,
- (void)handleSwipe:(UISwipeGestureRecognizer*)swipeGesture {
RainbowView *aView = (RainbowView*)swipeGesture.view;
// Get the next color index to aView.currentColorIndex;
aView.backgroundColor = [colorsArray objectAtIndex:nextColorIndex];
aView.currentColorIndex = nextColorIndex;
}

Related

Custom UINavigationController with button

I would like the NavigationBar to behave the same but would like to change the appearance of it. I've found so many ways of doing this online but I'm not sure which one is the best result for iOS 5.0. The navigation bar will look like this:
Since you are targeting iOS 5 i would definitely go for customizing UINavigationBar using the Appearance proxy. Then you can easily set your own images and they will apply to all navigation bars in your application without subclassing.
You can also customize the buttons in the navigation bar by customizing UIBarButtonItem. There are method like backButtonBackgroundImageForState:barMetrics: for the back button and backgroundImageForState:barMetrics: for the other buttons.
I had been looking for this thing for ages, too, without finding a straightforward solution! Thanks to an friend of mine, and sample codes, we made it with a custom navigation bar class that can be imported into any view controller class.
The .h file:
#import <UIKit/UIKit.h>
#interface NATitleBar : UIView {
NSInteger tag;
}
#property ( nonatomic) IBOutlet UIImageView *imageView;
#property ( nonatomic) IBOutlet UILabel *label;
#property ( nonatomic) IBOutlet UIButton *back;
#property ( nonatomic) IBOutlet UIButton *home;
/**
* Supports UIButton-style adding targets
*/
#end
The .m file:
#import "NATitleBar.h"
#implementation NATitleBar
#synthesize imageView;
#synthesize label;
#synthesize back;
#synthesize home;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
NSArray *views = [[NSBundle mainBundle] loadNibNamed:#"NATitleBar" owner:self options:nil];
[self addSubview:[views objectAtIndex:0]];
// customize the view a bit
//self.imageView.layer.borderWidth = 1.0;
//self.imageView.layer.borderColor = [UIColor colorWithWhite:0.4 alpha:0.4].CGColor;
//self.imageView.clipsToBounds = YES;
//self.imageView.layer.cornerRadius = 5.0;
}
return self;
}
#pragma mark - Overriden Setters / Getters
- (void)setTag:(NSInteger)aTag {
self.back.tag = aTag;
}
- (NSInteger)tag {
return self.back.tag;
}
#end
and then for the Nib file we have the following:
You can add or delete images in the Nib file to make the GUI as you wish.
Now you must import the class into any view controller you wish to have with custom navigation controller, and also define two methods (or one, if you don't want the 'home' button. in .h :
- (void) back;
in .m:
- (void)back {
[self.navigationController popViewControllerAnimated:YES];
}

UIViewController does not recognize method

please help me to resolve this issue
i have a view controller in a navigation stack named firstviewcontroller
FirstViewController.h
#class ImperialPickerController;
#class FractionPickerController;
#class MetricPickerController;
#interface FirstViewController : UIViewController {
UIView *pickerViewContainer;
ImperialPickerController *ImperialPickerController;
FractionPickerController *FractionPickerController;
MetricPickerController *MetricPickerController;
UIView *ImperialPickerViewContainer;
UIView *FractionPickerViewContainer;
UIView *MetricPickerViewContainer;
UISegmentedControl *segmentedControl;
NSInteger selectedUnit;
}
#property(nonatomic,retain) IBOutlet UIView *pickerViewContainer;
#property(nonatomic,retain) IBOutlet UIView *ImperialPickerViewContainer;
#property(nonatomic,retain) IBOutlet UIView *FractionPickerViewContainer;
#property(nonatomic,retain) IBOutlet UIView *MetricPickerViewContainer;
#property(nonatomic,retain) IBOutlet ImperialPickerController *ImperialPickerController;
#property(nonatomic,retain) IBOutlet FractionPickerController *FractionPickerController;
#property(nonatomic,retain) IBOutlet MetricPickerController *MetricPickerController;
#property(nonatomic,retain) IBOutlet UISegmentedControl *segmentedControl;
-(IBAction)toggleUnit;
#end
FirstViewController.m
#implementation FirstViewController
#synthesize ImperialPickerController;
#synthesize FractionPickerController;
#synthesize MetricPickerController;
#synthesize ImperialPickerViewContainer;
#synthesize FractionPickerViewContainer;
#synthesize MetricPickerViewContainer;
#synthesize pickerViewContainer;
#synthesize segmentedControl;
define METRIC_INDEX 0
define IMPERIAL_INDEX 1
define FRACTION_INDEX 2
-(IBAction)toggleUnit
{
selectedUnit = [segmentedControl selectedSegmentIndex];
if (selectedUnit == METRIC_INDEX)
{
[MetricPickerController updateLabel1];
}
}
#end
MetricPickerController.h
#interface MetricPickerController : NSObject <UIPickerViewDataSource,UIPickerViewDelegate> {
UIPickerView *pickerView;
UILabel *label;
}
#property(nonatomic,retain)UIPickerView *pickerView;
#property(nonatomic,retain)UILabel *label;
-(void)updateLabel1;
#end
MetricPickerController.m
import "MetricPickerController.h"
#implementation MetricPickerController
#synthesize pickerView;
#synthesize label;
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 10;
}
-(void)updateLabel1
{
label.text = #"test"
}
the problem is that i get an error message on compiling here in the firstviewcontroller
-(IBAction)toggleUnit
{
selectedUnit = [segmentedControl selectedSegmentIndex];
if (selectedUnit == METRIC_INDEX)
{
[MetricPickerController updateLabel1]; <<<<< (MetricPickerController might not respond to +updateLabel1)!!
also if i click the toggle in IB xcode will crash with sigbart error
}
can anyone please help and advise what i have done wrong i think i have everything hooked up properly so i guess this is to do with my method declaration somehow
i know the code is incomplete at this stage but its driving me crazy trying to get rid of this error and i hope you can appreciate that i am just a learner
}
The problem is that updateLabel1 is an instance method, and you are sending it to a class (the +updateLabel1 instead of -updateLabel1 in the error message tells you this).
Since you've named your instance variables the same as the classes, you should be able to solve this by writing
[self.MetricPickerController updateLabel1];
instead - this makes it clear to the compiler you are referring to the instance variable and not the actual class.

Can I have UIToolbar Bar Button Item States

Is there an easy way to have an on state and an off state for the UIBarButtonItems, with different images for each?
Thanks
There isn't a built-in way, but I can think of a few approaches (depending on your needs):
Bind the button to a method that toggles whatever the button is meant to toggle, and then changes the button's image property accordingly
Create your own subclass of UIBarButtonItem that looks something like this:
#interface ToggleBarButtonItem : UIBarButtonItem {
BOOL _state;
UIImage * onImage;
UIImage * offImage;
}
- (BOOL)toggleState;
#property (nonatomic, retain) UIImage * onImage;
#property (nonatomic, retain) UIImage * offImage;
#end
#implementation ToggleBarButtonItem
- (BOOL)toggleState {
if (_state) {
// Switch to Off state
self.image = offImage;
}
else {
// Switch to On state
self.image = onImage;
}
return _state = !_state;
}
#end

How do I add a custom view to iPhone app's UI?

I'm diving into iPad development and I'm still learning how everything works together. I understand how to add standard view (i.e. buttons, tableviews, datepicker, etc.) to my UI using both Xcode and Interface Builder, but now I'm trying to add a custom calendar control (TapkuLibrary) to the left window in my UISplitView application which doesn't involve Interface Builder, right? So if I have a custom view (in this case, the TKCalendarMonthView), how do I programmatically add it to one of the views in my UI (in this case, the RootViewController)? Below are some relevant code snippets from my project...
RootViewController interface
#interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
DetailViewController *detailViewController;
NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;
}
#property (nonatomic, retain) IBOutlet DetailViewController *detailViewController;
#property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
- (void)insertNewObject:(id)sender;
TKCalendarMonthView interface
#class TKMonthGridView,TKCalendarDayView;
#protocol TKCalendarMonthViewDelegate, TKCalendarMonthViewDataSource;
#interface TKCalendarMonthView : UIView {
id <TKCalendarMonthViewDelegate> delegate;
id <TKCalendarMonthViewDataSource> dataSource;
NSDate *currentMonth;
NSDate *selectedMonth;
NSMutableArray *deck;
UIButton *left;
NSString *monthYear;
UIButton *right;
UIImageView *shadow;
UIScrollView *scrollView;
}
#property (readonly,nonatomic) NSString *monthYear;
#property (readonly,nonatomic) NSDate *monthDate;
#property (assign,nonatomic) id <TKCalendarMonthViewDataSource> dataSource;
#property (assign,nonatomic) id <TKCalendarMonthViewDelegate> delegate;
- (id) init;
- (void) reload;
- (void) selectDate:(NSDate *)date;
Thanks in advance for all your help! I still have a ton to learn, so I apologize if the question is absurd in any way. I'm going to continue researching this question right now!
Assuming you have initialized the custom UIView, you need to add it as a subview of the viewController's view.
- (void)addSubview:(UIView *)view
So an example would be if you have a plain viewController called myVC, which has simply a blank white UIView as its view, you would say this:
CGRect customViewsFrame = CGRectMake(10, 30, 5, 2);
MyCustomView *myView = [[MyCustomView alloc] initWithFrame:customViewsFrame];
[[myVC view] addSubview:myView];
[myView release]; //Since you called "alloc" on this, you have to release it too
Then it will show up in the viewController's view, taking up the space indicated by the CGRect.
The CGRect's coordinates specify a location in the local coordinate system of the superview you are adding to, if I'm not mistaken.
CGRect CGRectMake (CGFloat x, CGFloat y, CGFloat width, CGFloat height);
I'm not booted into Mac OS X so I can't verify this completely, but this is your general pattern:
RootViewController.h:
...
#interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate>
{
...
TKCalendarMonthView* calendarView;
...
}
...
#property (nonatomic, retain) TKCalendarMonthView* calendarView;
...
RootViewController.m:
...
#synthesize calendarView;
...
- (void)dealloc
{
...
[calendarView release];
...
}
...
- (void)viewDidLoad
{
...
TKCalendarMonthView* aCalendarView = [[TKCalendarMonthView alloc] init]; // <-- possibly initWithFrame here
self.calendarView = aCalendarView;
[aCalendarView release];
[self addSubview:self.calendarView];
...
}

Objective -c properties - Can't change a subview's color with a declared property

I have a view with a subview whose alpha and backgroundcolor I would like to change through the use of declared properties. I have written some code as below and it works fine to change the alpha, but the background color is not changed when the property is set to a new value. Any help would be appreciated please.
#interface MyView : UIView {
float viewAlpha;
UIColor *viewColor;
}
#property (nonatomic, assign, readwrite) float viewAlpha;
#property (nonatomic, retain, readwrite) UIColor *viewColor;
#implementation MyView
#synthesize viewAlpha, viewColor;
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.viewAlpha = 1.0;
self.viewColor = [UIColor whiteColor];
UIView *infoView = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,50)];
infoView.alpha = self.viewAlpha;
infoView.backgroundColor = self.viewColor;
[self addSubview:infoView];
[infoView release];
}
return self;
}
You might need to write a custom setter and flag that your view needs to redraw when it changes. It'd be a good idea to do this for both the alpha and the color.