highlight a part of the cell when selected - iphone

I am trying to add a non-standard color to the cell when its highlighted. FOr this i create a view with the background color that i want and set it as the selectedBackgroundView for the cell.
All is fine.
UIView *selectionView = [[UIView alloc] init];
[selectionView setBackgroundColor:[UIColor colorWithRed:(121/255.0) green:(201/255.0) blue:(209/255.0) alpha:1.0]];
[cell setSelectedBackgroundView:selectionView];
My question, can i change the frame of the selectedBackgroundView so that it highlights only a part of the cell (to be precise, i want the selectionBackroundView to have an X-offset of 20 pixels).
is there any easy way of doing this ?
Updated code :
UIView *selectionView = [[UIView alloc] init];
[selectionView setBackgroundColor:[UIColor clearColor]];
UIView *selectionSubView = [[UIView alloc] initWithFrame:(CGRectMake(20.0f, 0.0f, 300.0f, 72.0f))];
[selectionSubView setBackgroundColor:[UIColor colorWithRed:(121/255.0) green:(201/255.0) blue:(209/255.0) alpha:1.0]];
UIView *clearView = [[UIView alloc] initWithFrame:(CGRectMake(0.0f, 0.0f, 20.0f, 72.0f))];
[clearView setBackgroundColor: [UIColor clearColor]];
[selectionView addSubview: selectionSubView];
[selectionView addSubview: clearView];
[cell setSelectedBackgroundView: selectionView];
THis doesn seem to work either. I have added this code in the 'cellForRowAtIndexPath'
Thanks in advance

You could put a smaller UIView as subview of your selectionView and change tha background color of that view.

You can do like this.
You create the separate file for UIView as below.
TestView.m
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code.
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
/* Draw a circle */
// Get the contextRef
CGContextRef contextRef = UIGraphicsGetCurrentContext();
// Set the border width
CGContextSetLineWidth(contextRef, 1.0);
// Set the circle fill color to GREEN
CGContextSetRGBFillColor(contextRef, 100.0, 255.0, 0.0, 1.0);
// Set the cicle border color to BLUE
CGContextSetRGBStrokeColor(contextRef, 0.0, 0.0, 255.0, 1.0);
// Fill the circle with the fill color
CGContextFillRect(contextRef, CGRectMake(20, 0, rect.size.width, rect.size.height));
// Draw the circle border
//CGContextStrokeRectWithWidth(contextRef, rect, 10);//(contextRef, rect);
}
And this Custom View you can use as a background View for cell selection like this.
TestView *bgView = [[TestView alloc] initWithFrame:cell.frame]; // Creating a view for the background...this seems to be required.
cell.selectedBackgroundView = bgView;
May be this help you.
Thanks,
Minesh Purohit.

Does the cell have fixed size and highlight area ?
If yes, create an image and use image view as the selectedBackgroundView

Try to set frame size for selectionView where x = 20. I am not sure about this but I guess it should work for your given scenario.

Related

UITableViewSeparator in a grouped tableView

In IB,
Style: Grouped, Single Line Etched, color white.
The background of my view is clear color.
In viewDidLoad of this ViewController, I create a dummy background view:
UIView *tableBgView = [[UIView alloc] initWithFrame:self.tableView.frame];
tableBgView.backgroundColor = [UIColor clearColor];
self.tableView.backgroundView = tableBgView;
[tableBgView release];
In cellForRowAtIndexPath I have:
UIView *bgView = [[UIView alloc] initWithFrame:cell.bounds];
bgView.backgroundColor = [UIColor clearColor];
cell.backgroundView = bgView;
[bgView release];
What I am trying to do is have a rectangle background instead of the rounded rectangle look for a grouped table and because in my cellForRowAtIndexPath I create a clearColor backgroundView to get rid of the rounded rect look, I do not have a separator anymore. Do I just add another single pixel UIView line that is at the bottom of this bgView to get my separator back? Or is there a better way? Thanks.
Here you go, this is my drawRect:, this will remove the rounded cells. This is also used in a grouped table view controller as you see.
Here is a sample image:
- (void) drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
// A left and right margin
float margin = 10.0f;
// Copy the rect and modify it's values to match the margin
CGRect _rect = rect;
_rect.size.width = _rect.size.width - (margin * 2);
_rect.origin.x = margin;
// Fill with a background color, in this case, white.
[[UIColor whiteColor] set];
CGContextFillRect(context, _rect);
// Set a line color
[[UIColor grayColor] set];
// Shift the move point to match our margin
CGContextMoveToPoint(context, margin, _rect.size.height);
// Draw the line with the same width as the cell PLUS the margin (because we shifted it).
CGContextAddLineToPoint(context, _rect.size.width + margin, _rect.size.height);
// Finish
CGContextStrokePath(context);
}

Make intersection transparent using multiple subviews

Please check below image. i have added scrollview in "BLACK" color and added subview in "GREY" color. now i want to make subview transparent which is define as "WHITE" color.
Please refer the below code. Let me know how to make button transparent with particular frame or let me know if you have any alternative for that.
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 40.0, self.frame.size.width, 300.0)];
self.scrollView.contentSize = CGSizeMake(self.bounds.size.width,ViewHeight);
self.scrollView.autoresizingMask=UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.scrollView.delegate = self;
self.scrollView.backgroundColor =[UIColor blackColor];
[self.view addSubview:self.scrollView
UIButton *butApp = [UIButton buttonWithType:UIButtonTypeCustom];
[butApp setFrame:CGRectMake(x, y , w, h)];
[butApp setBackgroundColor:[UIColor greyColor]];
[self.scrollView addSubview:butApp];
UIButton* gapButton = [UIButton buttonWithType:UIButtonTypeCustom];
[gapButton setFrame:CGRectMake(x+3, y+10, w-6, 10)];
[gapButton setBackgroundColor:[UIColor whiteColor]];
[self.scrollView addSubview:gapButton];
Instead of this gapButton i need transparent portion in grey color so user can see black color in that portion.
Try this, I suggested it in comments. Other answer requires subclassing UIButton, which you suggested was not ideal in your situation.
UIButton *butApp = [UIButton buttonWithType:UIButtonTypeCustom];
[butApp setFrame:CGRectMake(x, y , w, h)];
//[butApp setBackgroundColor:[UIColor greyColor]]; //replace this...
[butApp setBackgroundImage:[UIImage imageNamed:#"greyWithHoleInCenter.png"]
forState:UIControlStateNormal]; //...with this
[self.scrollView addSubview:butApp];
I created a crude .png file to represent the kind of backgroundImage you might be looking for. Note that the center is clear, not white. Therefore, it should show whatever image is behind it:
Ok. Funny question. In my opinion you have to override drawRect: + drawInContext: methods by subclassing UIView class.
You also need to set the container view (the gray view) + button bg to clearColor
-(void)drawRect:(CGRect)r
{
// Let this method blank will cause drawLayer:InContext to be called
}
-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context
{
// Fill the bg with gray
CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor);
CGContextFillRect(context, self.bounds);
// I clear the subview frames
for (UIView * v in [self subviews]) // I do it for all subviews
{
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextFillRect(context, v.frame);
}
}

Issue in adding a shadow to view layer

In one of my view I am adding shadow to a view. Thing is that the shadow shows white spaces on left & right edges. I want to remove these spaces.
Here is my code:
UIView *myView = [[ISTView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 35)];
myView.backgroundColor = [UIColor greyColor];
[myView.layer setShadowOffset:CGSizeMake(0.0, 5.0)];
[myView.layer setShadowOpacity:0.8];
[myView.layer setShadowRadius:2.0];
[myView.layer setShadowColor:[UIColor blackColor].CGColor];
[self.view addSubview:myView];
[myView release];
Here is my view's o/p:
If you want homogenous shadow without side effects you can draw it in graphics editor, save to png and place UIImageView with stretchable image on your view. And don't forget to set clipToBounds to NO.
UIView *myView = [[ISTView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 35)];
myView.backgroundColor = [UIColor greyColor];
myView.clipToBounds = NO;
UIImageView *shadowView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 35, 320, 10)];
shadowView.image = [UIImage imageWithName:#"my-shadow.png"];
[myView addSubview:shadowView];
[shadowView release];
[self.view addSubview:myView];
[myView release];
It would be cheaper for system to draw cached existing image above view hierarcy than calculate layer's shadow.
Use shadowPath to make the shadow larger then the view
view.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, view.frame.size.width+30, view.frame.size.height)].CGPath;
One solution I could think of and is working also is to adjust the view's frame by 2 pixels in X position and width:
UIView *myView = [[ISTView alloc] initWithFrame:CGRectMake(-2.0, 0.0, 324.0, 35)];
But this is not a cleaner approach of doing this. If anyone has better solution, please guide.
Try this, remove the code:
[myView.layer setShadowRadius:2.0];

How to tint an image/show a colour?

2 things i want to do, which are related:
Show a block of any colour. So i could change that colour to something else at any time.
Tint a UIImage to be a different colour. An overlay of colour with alpha turned down could work here, but say it was an image which had a transparent background and didn't take up the full square of the image.
Any ideas?
Another option, would be to use category methods on UIImage like this...
// Tint the image, default to half transparency if given an opaque colour.
- (UIImage *)imageWithTint:(UIColor *)tintColor {
CGFloat white, alpha;
[tintColor getWhite:&white alpha:&alpha];
return [self imageWithTint:tintColor alpha:(alpha == 1.0 ? 0.5f : alpha)];
}
// Tint the image
- (UIImage *)imageWithTint:(UIColor *)tintColor alpha:(CGFloat)alpha {
// Begin drawing
CGRect aRect = CGRectMake(0.f, 0.f, self.size.width, self.size.height);
UIGraphicsBeginImageContext(aRect.size);
// Get the graphic context
CGContextRef c = UIGraphicsGetCurrentContext();
// Converting a UIImage to a CGImage flips the image,
// so apply a upside-down translation
CGContextTranslateCTM(c, 0, self.size.height);
CGContextScaleCTM(c, 1.0, -1.0);
// Draw the image
[self drawInRect:aRect];
// Set the fill color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextSetFillColorSpace(c, colorSpace);
// Set the mask to only tint non-transparent pixels
CGContextClipToMask(c, aRect, self.CGImage);
// Set the fill color
CGContextSetFillColorWithColor(c, [tintColor colorWithAlphaComponent:alpha].CGColor);
UIRectFillUsingBlendMode(aRect, kCGBlendModeColor);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Release memory
CGColorSpaceRelease(colorSpace);
return img;
}
The first one is easy. Make a new UIView and set its background color to whatever color you’d like.
The second is more difficult. As you mentioned, you can put a new view on top of it with transparency turned down, but to get it to clip in the same places, you’d want to use a mask. Something like this:
UIImage *myImage = [UIImage imageNamed:#"foo.png"];
UIImageView *originalImageView = [[UIImageView alloc] initWithImage:myImage];
[originalImageView setFrame:CGRectMake(0.0f, 0.0f, 100.0f, 100.0f)];
[parentView addSubview:originalImageView];
UIView *overlay = [[UIView alloc] initWithFrame:[originalImageView frame]];
UIImageView *maskImageView = [[UIImageView alloc] initWithImage:myImage];
[maskImageView setFrame:[overlay bounds]];
[[overlay layer] setMask:[maskImageView layer]];
[overlay setBackgroundColor:[UIColor redColor]];
[parentView addSubview:overlay];
Keep in mind you’ll have to #import <QuartzCore/QuartzCore.h> in the implementation file.
Here is another way to implement image tinting, especially if you are already using QuartzCore for something else.
Import QuartzCore:
#import <QuartzCore/QuartzCore.h>
Create transparent CALayer and add it as a sublayer for the image you want to tint:
CALayer *sublayer = [CALayer layer];
[sublayer setBackgroundColor:[UIColor whiteColor].CGColor];
[sublayer setOpacity:0.3];
[sublayer setFrame:toBeTintedImage.frame];
[toBeTintedImage.layer addSublayer:sublayer];
Add QuartzCore to your projects Framework list (if it isn't already there), otherwise you'll get compiler errors like this:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_CALayer"
An easy way to achieve 1 is to create a UILabel or even a UIView and change the backgroundColor as you like.
There is a way to multiply colours instead of just overlaying them, and that should work for 2. See this tutorial.
Try this
- (void)viewDidLoad
{
[super viewDidLoad];
UIView* maskedView = [self filledViewForPNG:[UIImage imageNamed:#"mask_effect.png"]
mask:[UIImage imageNamed:#"mask_image.png"]
maskColor:[UIColor colorWithRed:.6 green:.2 blue:.7 alpha:1]];
[self.view addSubview:maskedView];
}
-(UIView*)filledViewForPNG:(UIImage*)image mask:(UIImage*)maskImage maskColor:(UIColor*)maskColor
{
UIImageView *pngImageView = [[UIImageView alloc] initWithImage:image];
UIImageView *maskImageView = [[UIImageView alloc] initWithImage:maskImage];
CGRect bounds;
if (image) {
bounds = pngImageView.bounds;
}
else
{
bounds = maskImageView.bounds;
}
UIView* parentView = [[UIView alloc]initWithFrame:bounds];
[parentView setAutoresizesSubviews:YES];
[parentView setClipsToBounds:YES];
UIView *overlay = [[UIView alloc] initWithFrame:bounds];
[[overlay layer] setMask:[maskImageView layer]];
[overlay setBackgroundColor:maskColor];
[parentView addSubview:overlay];
[parentView addSubview:pngImageView];
return parentView;
}

How do I make UITableViewCellAccessoryDisclosureIndicator visible in orange color instead of gray color?

without Creating any of the uibutton(custom button with background image)in tableview cell.
I want to change the accessory indicator color from gray to orange.What should i do for that...
plz reply as soon as possible(plz answer me clearly or else i can't understand)...
i'm waiting for ur reply...
Thank u...
There's a much easier solution to this:
cell.accessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"theimage.png"]] autorelease];
You'll need to create a new UIView with a UIImageView inside it and then set that as the Accessory for the cell. So you'll need to create a image just like the default accessory but in the colour you want.
UIView* accessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 24, 50)];
UIImageView* accessoryViewImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"NEWIMAGE.png"]];
accessoryViewImage.center = CGPointMake(12, 25);
[accessoryView addSubview:accessoryViewImage];
[cell setAccessoryView:accessoryView];
[accessoryViewImage release];
[accessoryView release];
For others who are still stumbling upon this question, here's how to do it programmatically.
Create a UIView subclass, and override drawRect: with the following:
#define PADDING 4.f //give the canvas some padding so the ends and joints of the lines can be drawn with a mitered joint
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
CGContextSetLineWidth(context, 3.f);
CGContextSetLineJoin(context, kCGLineJoinMiter);
CGContextMoveToPoint(context, PADDING, PADDING);
CGContextAddLineToPoint(context, self.frame.size.width - PADDING, self.frame.size.height/2);
CGContextAddLineToPoint(context, PADDING, self.frame.size.height - PADDING);
CGContextStrokePath(context);
}
This draws a stock indicator arrow. From here you can change the color, line width, etc.
To add the indicator view to your cell:
#define ACCESSORY_WIDTH 13.f
#define ACCESSORY_HEIGHT 18.f
cell.accessoryView = [[AccessoryIndicatorView alloc] initWithFrame:CGRectMake(self.frame.size.width - ACCESSORY_WIDTH - CELL_PADDING, self.frame.size.height/2 - ACCESSORY_HEIGHT/2, ACCESSORY_WIDTH, ACCESSORY_HEIGHT)];