Large UIImage drawinrect extremely slow on selection - iphone

I have a custom UITableView cell that sports an Image, and a headline. I used the fast scrolling example of ABTableViewCell from atebits.
It seems when I select the first row (which is my row with the largest image) it takes a considerable amoun of time to highlight the row, and then push the new view controller.
However when I select any of the other rows, with much smaller images, its almost instant.
Ive attempted to draw the picture using CGContextDrawImage and drawInRect but both yield the same results.
- (void)drawContentView:(CGRect)r highlighted:(BOOL)highlighted {
if ([type isEqualToString:#"first"]) {
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *backgroundColor = [UIColor blackColor];
UIColor *textColor = [UIColor whiteColor];
UIColor *textBackgroundColor = [[UIColor alloc] initWithWhite:0 alpha:.5];
UIColor *highlightColor;
if (highlighted) {
backgroundColor = [UIColor clearColor];
textColor = [UIColor blueColor];
highlightColor = [[UIColor alloc] initWithWhite:0 alpha:.3];
} else {
highlightColor = [UIColor clearColor];
}
[backgroundColor set];
CGContextFillRect(context, r);
[self.picture drawInRect:CGRectMake(0.0, 0.0, 320, 225)];
[textBackgroundColor set];
CGContextFillRect(context, CGRectMake(0, 170, 320, 55));
[textColor set];
[self.title drawInRect:CGRectMake(5, 170, 320, 55) withFont:firstHeadlineFont lineBreakMode:UILineBreakModeWordWrap];
[highlightColor set];
CGContextFillRect(context, r);
} else {
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *backgroundColor = [UIColor blackColor];
UIColor *textColor = [UIColor blueColor];
if (highlighted) {
backgroundColor = [UIColor clearColor];
textColor = [UIColor whiteColor];
}
[backgroundColor set];
CGContextFillRect(context, r);
CGPoint p;
p.x = 0;
p.y = 0;
[self.picture drawInRect:CGRectMake(0.0, 0.0, 44, 44)];
[textColor set];
p.x += 44 + 6; // space between words
[self.title drawAtPoint:p withFont:[UIFont systemFontOfSize:20]];
}
}
EDIT:
IS there anything I can do to speed this up? I am caching the image and reading it as well.

I realized I was using a very very large version of the image for my first row, I was able to scale it down before I pulled it from the webserver and this vastly improved performance. NOTE: double check your dimensions are not huge. IE: 2184x1456 hahah

Related

What's the fastest way to create a transparent line in UIKit?

This one:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, width, 1)];
view.backgroundColor = [UIColor whiteColor];
view.alpha = 0.1;
or this one:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, width, 1)];
view.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.1];
or is there any third alternative? Using a UIImageView with image? Doing custom drawing with CoreGraphics? What is supposed to be fastest?
The fastest way would be to create a CALayer. Using this will allow you to easily alter its color/opacity if needed.
CALayer *line = [CALayer new];
line.frame = CGRectMake(x, y, width, 1.0);
line.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.1].CGColor;
[someView.layer addSublayer:line];
If you want to draw a line right onto an existing view and have it stay there with no altering you can add the following code to the drawRect: method of the existing view:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] colorWithAlphaComponent:0.1].CGColor);
CGContextSetLineWidth(context, 1.0);
CGContextMoveToPoint(context, x, y);
CGContextAddLineToPoint(context, x + width, y);
CGContextStrokePath(context);

Adding shade to label

I need the label as
I created one label subclass.Where I write the code as,
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
UIColor * textColor = [UIColor colorWithRed:57.0/255.0 green:100.0/255.0 blue:154.0/255.0 alpha:1.0];
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(c, 3.5);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextFillStroke);;
self.textColor = [UIColor whiteColor];
[super drawTextInRect:rect];
CGContextSetTextDrawingMode(c, kCGTextFill);
self.textColor = textColor;
// self.shadowColor = [UIColor colorWithRed:11.0/255.0 green:63.0/255.0 blue:126.0/255.0 alpha:1.0];
//self.shadowOffset = CGSizeMake(0.5, -0.5);
[super drawTextInRect:rect];
}
By this I am getting the blue color text and white outline to that text.But I need to get the dark blue color shade. How can I do this?
Please help me.
You should probably have a look at the CGContextSetShadowWithColor method.
CGContextSetShadowWithColor (
context,
shadowSize,
shadowBlur,
color
);
I found an article that could help you on this website : http://majicjungle.com/blog/191/
EDIT
The following code works:
- (void)drawRect:(CGRect)rect
{
UIColor * textColor = [UIColor colorWithRed:57.0/255.0 green:100.0/255.0 blue:154.0/255.0 alpha:1.0];
CGContextRef c = UIGraphicsGetCurrentContext();
//save the context before add shadow otherwise the shadow will appear for both stroke and fill
CGContextSaveGState(c);
//this is where I add the shadow, and it works
CGContextSetShadowWithColor(c, CGSizeMake(2, 2), 3, [[UIColor grayColor] CGColor]);
CGContextSetLineWidth(c, 3.5);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextStroke);;
self.textColor = [UIColor whiteColor];
[super drawTextInRect:rect];
//restore the context to clear the shadow
CGContextRestoreGState(c);
CGContextSetTextDrawingMode(c, kCGTextFill);
self.textColor = textColor;
[super drawTextInRect:rect];
}
Have you tried using the standard quartz properties like:
label.layer.shadowColor
label.layer.shadowOffset
(you need the QuartzCore framework in your project and to import the header).

iPhone - Draw white text on black view using CGContext

I can't achieve drawing some white text on a black view using CGContext in a drawRect method.
I do :
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 1.0);
CGContextSelectFont(context, "Helvetica", 20, kCGEncodingMacRoman);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGPoint center = self.center;
And then...
Impossible to find the correct method.
I've tried this :
UIFont* font = [UIFont fontWithName:#"Geneva" size:12.0];
[#"Some text" drawAtPoint:center withFont:font];
But it does not work.
I don't find any CGContext method for that. Where is it hidden ?
How may I draw that text in white ?
Ok after a couple of hours and reading the Quartz 2D programming guide I discovered that you also have to set the FILL color, not just the STROKE color. So the follow code works.
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
I needed to show chart labels on a darkGray border. Now the labels appear in white.
This will draw a string in white in a black rectangle
NSString *text = #"Some text";
CGPoint center = CGPointMake(100, 200);
UIFont *font = [UIFont systemFontOfSize:14];
CGSize stringSize = [text sizeWithFont:font];
CGRect stringRect = CGRectMake(center.x-stringSize.width/2, center.y-stringSize.height/2, stringSize.width, stringSize.height);
[[UIColor blackColor] set];
CGContextFillRect(context, stringRect);
[[UIColor whiteColor] set];
[text drawInRect:stringRect withFont:font];
On shorter example try using [[UIColor whiteColor] set] before the drawAtPoint: call.
Works with :
CGContextShowTextAtPoint (context, center.x, center.y, "Some text", strlen("Some text"));
But still need some transformations to be displayed not mirrored :-)
This will work with this code :
NSString *text = #"Some text";
UIFont *font = [UIFont systemFontOfSize:14];
[ text drawAtPoint:CGPointMake( 0, 0 ) withAttributes:#{ NSFontAttributeName:font, NSForegroundColorAttributeName : UIColor.redColor } ];

Shadow on UILabel does not appear

I want to add a little shadow to my UILabel, but it is not showing up.
companyLabel.textAlignment = UITextAlignmentLeft;
companyLabel.font = [UIFont fontWithName:#"Arial" size:13];
companyLabel.adjustsFontSizeToFitWidth = YES;
companyLabel.minimumFontSize = 10.0;
companyLabel.backgroundColor = [UIColor clearColor];
companyLabel.textColor = [UIColor colorWithRed:103.0/255.0 green:103.0/255.0 blue:103.0/255.0 alpha:1.0];
companyLabel.layer.shadowColor = [[UIColor colorWithRed:241.0/255.0 green:241.0/255.0 blue:241.0/255.0 alpha:1.0] CGColor];
companyLabel.layer.shadowOffset = CGSizeMake(0.0, -1.0);
companyLabel.highlightedTextColor = [UIColor whiteColor];
You're not setting shadowOpacity, which defaults to 0.0. You need to set that to something else to make the shadow show up. However, there's no reason to even touch CALayer right now because UILabel has its own shadowColor and shadowOffset properties.
companyLabel.shadowColor = [UIColor colorWithRed:241.0/255.0 green:241.0/255.0 blue:241.0/255.0 alpha:1.0];
companyLabel.shadowOffset = CGSizeMake(0.0, -1.0);

UISegmentedControl tint color on touch

I have a UISegmentedControl in my app (see code below) :
// --------------- SETTING NAVIGATION BAR RIGHT BUTTONS
NSArray *segControlItems = [NSArray arrayWithObjects:[UIImage imageNamed:#"up.png"],[UIImage imageNamed:#"down.png"], nil];
segControl = [[UISegmentedControl alloc] initWithItems:segControlItems];
segControl.segmentedControlStyle = UISegmentedControlStyleBar;
segControl.momentary = YES;
segControl.frame = CGRectMake(25.0, 7, 65.0, 30.0);
segControl.tintColor = [UIColor blackColor];
[segControl addTarget:self action:#selector(segAction:) forControlEvents:UIControlEventValueChanged];
if (current == 0) [segControl setEnabled:NO forSegmentAtIndex:0];
if (current == ([news count]-1)) [segControl setEnabled:NO forSegmentAtIndex:1];
// ---------------
But I can't make it to show something when you click on it ...
It functionnally works perfectly but I would like it to tint to gray when you click on it (but just when you click) ... would that be possible ?
Thank you,
Gotye.
Seems as if the selected segment's tint color is made darker than original tint. Therefore if your tint is black then the selected segment's tint color doesn't change since there isn't anything darker than that.
I've looked around and haven't found any nice way to control the selected segment's tint color for this control.
A recipe to create own segmented controls, which (I guess) can be configured as you want:
idevrecipes custom segmented control
BTW: A very very interesting website!
Try this. It works if you use segment titles, you may need to modify it if you use images.
segControl.segmentedControlStyle = UISegmentedControlStyleBar;
[segControl addTarget:self action:#selector(changeColors:) forControlEvents:UIControlEventValueChanged];
-(IBAction)changeColors:(UISegmentedControl *)sc{
for (int i=0; i<sc.numberOfSegments; i++) {
// reset all the titles in the segmented control
[sc setTitle:[NSString stringWithFormat:#"%i", i] forSegmentAtIndex:i];
}
if (sc.selectedSegmentIndex < 0 || sc.selectedSegmentIndex >= sc.numberOfSegments) {
return;
}
CGFloat width = sc.frame.size.width / sc.numberOfSegments - 1;
CGRect rect = CGRectMake(0, 0, width, sc.frame.size.height - 2);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
// background gradient
UIColor *colorOne = [UIColor colorWithWhite:0.6 alpha:1.0]; //top of gradient
UIColor *colorTwo = [UIColor colorWithWhite:0.4 alpha:1.0]; //bottom of gradient
NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, (id)colorTwo.CGColor, nil];
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);
CGContextDrawLinearGradient(ctx, gradient, CGPointMake(0,0), CGPointMake(0,rect.size.height), 0);
// black shadow at the top
colors = [NSArray arrayWithObjects:(id)[UIColor colorWithWhite:0.0 alpha:0.3].CGColor, (id)[UIColor clearColor].CGColor, nil];
gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)colors, NULL);
CGContextDrawLinearGradient(ctx, gradient, CGPointMake(0,0), CGPointMake(0,2.0), 0);
UILabel * title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, sc.frame.size.height - 4)];
title.text = [sc titleForSegmentAtIndex:sc.selectedSegmentIndex];
title.font = [UIFont fontWithName:#"Helvetica-Bold" size:12.0];
title.textAlignment = UITextAlignmentCenter;
title.textColor = [UIColor whiteColor];
title.backgroundColor = [UIColor clearColor];
title.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.5];
title.shadowOffset = CGSizeMake(0, -0.5);
[title.layer renderInContext:ctx];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[sc setImage:img forSegmentAtIndex:sc.selectedSegmentIndex];
}