Shadowing a UITextview like a UITextField - objective-c

I have searched apple's documentation and other posts on Stack Overflow, but I'm still having trouble adding a shadow to the inside of a UITextView. I would like to make it look like a UITextField. Here's the code that I've tried.
CALayer *frontLayer = self.frontField.layer;
[frontLayer setBorderColor:CGColorCreate(CGColorSpaceCreateDeviceGray(), nil)];
[frontLayer setBorderWidth:1];
[frontLayer setCornerRadius:5];
[frontLayer setShadowRadius:10.0];
CGSize shadowOffset = {0.0,3.0};
[frontLayer setShadowOffset:shadowOffset];
[frontLayer setShadowOpacity:1];
self.frontField.clipsToBounds = YES;
Where am I going wrong?

Start off simple and try this:
[myTextView.layer setShadowColor:[[UIColor blackColor] CGColor]];
[myTextView.layer setShadowOffset:CGSizeMake(1.0, 1.0)];
[myTextView.layer setShadowOpacity:1.0];
[myTextView.layer setShadowRadius:0.3];
[myTextView.layer.masksToBounds = NO]; //<-- for UITextView!
to optimise performance also add:
view.layer.shadowPath = [UIBezierPath bezierPathWithRect:myTextView.bounds].CGPath;
Then you can add your other properties back in 1 by 1 and see what is causing an issue for you.

According to 25 iOS performance tips & tricks, adding shadow by setting shadowOffset is an expensive operation and affects performance.
Core Animation has to do an offscreen pass to first determine the
exact shape of your view before it can render the drop shadow, which
is a fairly expensive operation.
You can use instead:
myTextView.layer.shadowPath = [[UIBezierPath bezierPathWithRect:view.bounds] CGPath];

Related

Mavericks Style Tagging

I'm quite new to cocoa and I'm trying to find out how I can create something similar to the new tagging UI in Mavericks:
I assume, I'll have to overwrite NSTokenFieldCell to get the coloured dots or an icon on the tags. But how does this popup list work?
Thanks for your help!
Sadly, you'll have to roll your own. Almost all of the drawing taking place in NSTokenFieldCell is private, so adding any kind of ornamental elements would have to be done by you. If I remember correctly, NSTokenFieldCell uses an NSTokenTextView instead of the window's standard field editor. I'm not sure what's different about it, but I think it's mostly to deal with the specialized nature of "tokenizing" attributed strings. I think they just use NSAttachmentCell objects for the graphical tokens, and when the cell receives a -mouseDown: event, they show the menu.
The menu part would actually be pretty easy because you can add images to menu items like so:
NSMenuItem *redItem = [[NSMenuItem alloc] initWithTitle:#"Red"
action:#selector(chooseColorMenuItem:)
keyEquivalent:#""];
// You could add an image from your app's Resources folder:
NSImage *redSwatchImage = [NSImage imageNamed:#"red-menu-item-swatch"];
// ----- or -----
// You could dynamically draw a color swatch and use that as its image:
NSImage *redSwatchImage = [NSImage imageWithSize:NSMakeSize(16.0, 16.0)
flipped:NO
drawingHandler:^BOOL(NSRect dstRect) {
NSRect pathRect = NSInsetRect(dstRect, 0.5, 0.5); // Aligns border to integral values
NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:pathRect];
NSColor *fillColor = [NSColor redColor];
NSColor *strokeColor = [fillColor shadowWithLevel:0.5];
[fillColor setFill];
[path fill];
[strokeColor setStroke];
[path stroke];
return YES;
}];
redItem.image = redImage;
With respect to the token drawing stuff, take my info with a grain of salt because Apple's documentation on this stuff is pretty lacking, so everything I'm telling you is from personal struggles, cursing, and head-banging. Anyway, I'm sorry I couldn't bring you better news, but I guess, it is what it is. Good luck.

Creating a dropshadow for UITableView

Would somebody please explain how to create a one or two pixel drop shadow ONLY on the the very last cell (in other words, I don't want a shadow around the entire tableview, just the bottom cell. An image of what I'm talking about:
Solved. Use the following code to produce a very nice, subtle shadow to the bottom of your UITableViewCell. Makes it look like it's raised slightly out of the page :)
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(3, 49, cell.frame.size.width-26, 3)];/// change size as you need.
separatorLineView.backgroundColor = shadowColor;// you can also put image here
UIBezierPath *roundedShadow = [UIBezierPath bezierPathWithRoundedRect:separatorLineView.bounds byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(8.0f, 8.0f)];
CAShapeLayer *newSeparatorShape = [[CAShapeLayer alloc] init];
[newSeparatorShape setPath:roundedShadow.CGPath];
separatorLineView.layer.mask = newSeparatorShape;
[cell.contentView addSubview:separatorLineView];
Also, don't forget to put this at the top of your .m file #import <QuartzCore/QuartzCore.h>
You could, in tableView:cellForIndexPath: set the cell's background image to one that includes the rounded corners with the shadow.

Objective-C Performance Optimization while using layer.shadow

I'm building news feed list table using UITableView. For each row I'm creating rectangle cell with shadow using QuartzCore layer.shadow
Sample code inside custom UITableViewCell class:
-(void)drawRect:(CGRect)rect
{
UIView *bgView = [[UIView alloc] initWithFrame:self.bounds];
bgView.backgroundColor = [UIColor whiteColor];
bgView.layer.shadowColor = [UIColor blackColor].CGColor;
bgView.layer.shadowOffset = CGSizeMake(0, 1);
bgView.layer.shadowOpacity = 0.2;
bgView.layer.shadowRadius = 1;
self.backgroundView = bgView;
[bgView release];
}
When I test app, scroll UITableView, the scrolling performance is bad! If I remove shadow, performance is good!
I need your advices. What kind of optimizations I can do in order to get best performance?
Your problem isn't Objective-C but the shadow! Since iOS 3.2 you can define a CGPathRef for the shadow, you should build one which includes just the outline of your view to reduce rendering time and increase performance. You could also have the shadow rasterize to avoid redrawing it all the time (set the shouldRasterize property of your layer to YES. Depending on what you want to do with the layer, this might not be the best looking option. And its also a memory/performance trade off, keep that in mind!).
The most easiest way to create the needed shadow path should be via the UIBezierPath class which has a lot of useful class methods to build various formed CGPathRef objects, but depending on the shape of your view, you might have to fall back to build your own path by hand.
how do you implement the UITableView delegate?
Have you created the UITableViewCell using reuse, such like:
-[UITableView dequeueReusableCellWithIdentifier:]
Please check it.

how to add shadow to only the bottom and right side of a uiview?

I am thinking about adding drop shadow to the bottom and right side of UIView, but I found all the solutions out there are adding shadows for four sides a view. Is there a way to work around that?
You can use CAGradientLayer like so,
CAGradientLayer *shadow = [CAGradientLayer layer];
shadow.frame = CGRectMake(-10, 0, 10, myView.frame.size.height);
shadow.startPoint = CGPointMake(1.0, 0.5);
shadow.endPoint = CGPointMake(0, 0.5);
shadow.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:0.0 alpha:0.4f] CGColor], (id)[[UIColor clearColor] CGColor], nil];
[myView.layer addSublayer:shadow];
You'll have to change the frame to suit your needs. This example displays a shadow along the height of a view on the left. You can also change the start and end point to control the direction of the shadow.
I may do it by adding two UIImageViews with stretched shadow image on bottom and right side of the view. You don't have to cover all the view with those UIImageViews, you just clip as much as you need. Take a look at the color blended layers of twitter on the iPhone, I believe those beautiful shadows are created by using UIImageViews. And that saves system resources. Of course you can use CALayer to create shadow, but I think it consumes more system resources to render the shadow, so CALayer is second choice for me.
UIBezierPath *shadowPath = [UIBezierPath
bezierPathWithRect:self.yourViewObj.bounds];
self.yourViewObj.layer.masksToBounds = NO;
self.yourViewObj.layer.shadowColor = [UIColor blackColor].CGColor;//*** color you want for shadow
self.yourViewObj.layer.shadowOffset = CGSizeMake(5.0f, 5.0f);
self.yourViewObj.layer.shadowOpacity = 0.7f;
self.yourViewObj.layer.shadowPath = shadowPath.CGPath;

How the Shadow in Twitter for Mac when change tab is done?

When changing a tab in Twitter for mac , the old view slide to left, and the new view become center. both of old and new view has a shadow behind it.
I'v tried :
viewController.view.layer.masksToBounds = NO;
viewController.view.layer.shadowRadius = 50.0;
viewController.view.layer.shadowColor = [TUIColor blackColor].CGColor;
viewController.view.layer.shadowOpacity = 0.4;
and used viewController.view.layer.shouldRasterize = YES; trying to speed it up.
But still feel lag then twitter for mac.
What's the best performance way to add those shadow?
Have a look at CALayer's shadowPath attribute. Typically if you are willing to tell the layer exactly how the shadow should be drawn then it will be faster than the default, where it tries to calculate a shadow based on the full view alpha channel.
For example:
CGPathRef shadow = CGPathCreateWithRect(CGRectInset(self.bounds, -3, 1), NULL);
[self.layer setShadowPath:shadow];
[self.layer setShadowColor:[[UIColor colorWithWhite:0 alpha:0.5f] CGColor]];
[self.layer setShadowOpacity:0];
[self.layer setShadowRadius:8];
CFRelease(shadow);
(this is iOS code but I believe the only thing you'll need to change is the UIColor reference).