Thursday, September 16, 2010

Colored RGB sliders, without a XIB

The next step of my refactoring was to modify the Colored View sliders so that they are independent of a .xib file so that I can place them into any view.  This gives me a lot of flexibility and reduces some of the dependance of a xib in a dependent library.  
In addition I found that when I programmatically created the sliders I could change the height and make it look somewhat nicer.


I revised the creation code so that it creates 4 sliders programmatically spaced within a passed in view.  It sets up callbacks in the current routine.

When a color changes it calls a delegate with the changes.


- (void) loadView : (UIView *)viewToUse
{
    NSLog(@"In loadView for ColorEditor");
    // Don't use a nib.
    self.leftMargin=10;
    self.rightMargin=10;
    self.spacing=5;
    self.fontSize=10;
    int labelWidth=74;
    int labelHeight=21;
    
    viewToUse.backgroundColor=[UIColor cyanColor];
    
    if (currentColorSpace==nil)
        currentColorSpace = CGColorSpaceCreateDeviceRGB();
    NSArray *sliderLabels=      [NSArray arrayWithObjects:NSLocalizedString(@"Red", @"Red"), NSLocalizedString(@"Green", @"Green"), NSLocalizedString(@"Blue", @"Blue"),NSLocalizedString(@"Transparency","Transparency"), nil];
    
    
    NSLog(@"view height %f, width %f x %f, y %f",viewToUse.frame.size.height,viewToUse.frame.size.width,viewToUse.frame.origin.x,viewToUse.frame.origin.y);
    
    int sliderHeight=(viewToUse.frame.size.height)/4-spacing;
    
    NSLog(@"SliderHeight %d",sliderHeight);
    
    for (int i=0;i<4;i++)
    {
        CGRect labelFrame=CGRectMake(0, (sliderHeight+spacing)*i+sliderHeight/2-labelHeight/2, labelWidth, labelHeight);
        UILabel *label=[[UILabel alloc] initWithFrame:labelFrame];
        label.adjustsFontSizeToFitWidth=true;
        label.text=[sliderLabels objectAtIndex:i];
        [viewToUse addSubview:label];
        CGRect areaFrame=CGRectMake(leftMargin+labelWidth, (sliderHeight+spacing)*i,viewToUse.bounds.size.width-leftMargin-rightMargin-labelWidth, sliderHeight);
        
        sliders[i]=[[UISlider alloc]init];
        [sliders[i] addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
        sliders[i].tag=i;        
        sliders[i].accessibilityLabel=[sliderLabels objectAtIndex:i];
        NSLog(@"Y is %d",(sliderHeight+spacing)*i);
        sliders[i].frame=areaFrame;
        [viewToUse addSubview:sliders[i]];
        
     }    
    [self calcColors];
}

and the calc colors is:
- (void) calcColors
{
    for (int index=0;index<4;index++)
    {
        [self setSlider:sliders[index] colorIndex:index];
    }
    
    currentColor=[UIColor colorWithRed:colors[0] green:colors[1] blue:colors[2] alpha:colors[3]];

       
    for (int index=0;index<4;index++)
    {
        // numeric fields are not implemented.      
        //     textFields[index].text=[NSString stringWithFormat:@"%d",(int)  (colors[index]*255)];
    }
    if (delegate!=nil)
    {
        [delegate colorChanged:currentColor];
    }
    
}
This looks like:



Note that the sliders (the area in blue) is the only thing the code does.  The rest is a custom frame done in a .nib.  This enables me to embed the sliders in a view:

The .nib in interface builder looks like this:


Note that I have an image view under a label.  This allows me to change the label and show what it looks like under the label.

The yellow area is my current color for the slider view.  I set it to a unique color so that I can watch what is going on.

I'm allowing the font and background color to be set using the tab bar.  This is not standard behavior for a tab bar, but it is allowable in a modal dialog.   I have a 3rd tab that will eventually be used for a font choice.












The code for this is:
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];    
    colorEditor=[[ColorEditor alloc]init];
    isFont=true;
    self.view.backgroundColor=[UIColor colorWithRed:0 green:0 blue:0 alpha:0];
    
}

- (void) initColors:(UIColor*) fColor background:(UIColor*) back text:(NSString*) textValue image:(UIImage*)background {
    [colorEditor loadView:actionView];
    colorEditor.delegate=self;
    label.textColor=fColor;
    label.backgroundColor=back;
    label.text=textValue;
    [colorEditor setCurrentColor:label.textColor];
    backImage.contentMode=UIViewContentModeScaleAspectFit;
    backImage.image=background;

}
- (void) colorChanged:(UIColor*) newColor
{
    if (isFont)
        label.textColor=newColor;
    else
        label.backgroundColor=newColor;
    // Tell our delegate that we have our font colors changed.
    [delegate styleChanged:label.textColor background:label.backgroundColor];

}

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item // called when a new view is selected by the user (but not programatically)
{
    if (item==fontColor)
    {
        isFont=true;
        [colorEditor setCurrentColor:label.textColor];
         
    }
    else
    {
             isFont=false;
             [colorEditor setCurrentColor:label.backgroundColor];
    }
    if (label !=nil)
    {
        label.text=item.title;   
    }    
    }

@end

I can now change the color editor and use it to set both the background and foreground color of a font.

And the header for this defines another protocol that allows the foreground and background color to be set.

@protocol StyleChanged

- (void) styleChanged:(UIColor*) fontColor background:(UIColor*) backColor;
@end

@interface ColorEdit : UIViewController<UITabBarDelegate,ColorListener> {
    IBOutlet UILabel *label;
    IBOutlet UIView  *actionView;
    IBOutlet UIImageView *backImage;
    ColorEditor *colorEditor;
    IBOutlet UITabBarItem *fontColor;
    IBOutlet UITabBarItem *backColor;
    bool isFont;
    id<StyleChanged> delegate;
    
}
@property (nonatomic,retain) IBOutlet UIImageView *backImage;
@property (nonatomic,retain) IBOutlet UILabel *label;
@property (nonatomic,retain) IBOutlet UIView *actionView;
@property (nonatomic,retain) ColorEditor *colorEditor;
@property (nonatomic,retain) IBOutlet UITabBarItem *fontColor;
@property (nonatomic,retainIBOutlet UITabBarItem *backColor;
@property (nonatomic,retain) id delegate;
- (void) initColors : (UIColor*) fontColor background:(UIColor*) back text:(NSString*) textValue image:(UIImage*)background ;



No comments:

Post a Comment