Rounded Corners with an arrow on a UIView with the iPhone SDK 3.0

This article is a follow-up to a previous article Rounded Corners on a UIView with the iPhone SDK 3.0.

In the previous post I included the code to create a UIView with rounded corners the easy way using the iPhone SDK 3.0. However the next challenge came when I wanted to also add an arrow to the edge of the rounded box.

In order to add the arrow I would be manually creating the path to draw the new type of box. I added a variables:

  • (CGFloat) pointY to specify where on the left hand edge the point starts.
  • (CGFloat) pointWidth to specify the width of the point.
  • (CGFloat) pointHeight for the height.
  • (UIColor) rectColor to set the color of the new rectangle (I actually copy the value of self.backgroundColor and set the background color to [UIColor clearColor]

I added these variables so they can be set on the view but I will leave these for you to implement however you like.

Once you have created the variables pointY, pointWidth, pointHeight and rectColor you can then use the following code.

- (void)drawRect:(CGRect)rect {
  // Drawing code

  CGContextRef context = UIGraphicsGetCurrentContext();
  CGFloat radius = self.layer.cornerRadius;

  // Make sure corner radius isn't larger than half the shorter side
  if (radius > self.bounds.size.width/2.0) radius = self.bounds.size.width/2.0;
  if (radius > self.bounds.size.height/2.0) radius = self.bounds.size.height/2.0;

  CGFloat minx = CGRectGetMinX(self.bounds) + self.pointWidth;
  CGFloat midx = CGRectGetMidX(self.bounds);
  CGFloat maxx = CGRectGetMaxX(self.bounds);
  CGFloat miny = CGRectGetMinY(self.bounds);
  CGFloat midy = CGRectGetMidY(self.bounds);
  CGFloat maxy = CGRectGetMaxY(self.bounds);

  /*
  CGContextMoveToPoint(context, minx, midy);
  CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
  CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
  CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
  CGContextAddArcToPoint(context, minx, maxy, minx, midy, radius);
  */

  CGContextMoveToPoint(context, minx, miny + pointY);
  CGContextAddArcToPoint(context, minx, miny, midx, miny, radius);
  CGContextAddArcToPoint(context, maxx, miny, maxx, midy, radius);
  CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
  CGContextAddArcToPoint(context, minx, maxy, minx, miny + pointY + pointHeight, radius);
  CGContextAddLineToPoint (context, minx, miny + pointY + pointHeight);
  CGContextAddLineToPoint (context, minx - pointWidth, miny + pointY + (pointHeight / 2));

  CGContextClosePath(context);

  [self.rectColor setFill];
  CGContextDrawPath(context, kCGPathFill);
}

Rounded Corners on a UIView with the iPhone SDK 3.0

An iPhone app with programmatically set cornerRadiusI’ve been doing a bit more iPhone development recently and one of the challenges we encountered was to control the background color of a UIView programmatically. Now this is a pretty simple thing to do until you decide you also want to round the corners of that view.

One option is of course to use an image as a background but this wouldn’t allow us to programmatically change the background color of the UIView.

After a bit of digging I finally came across the method cornerRadius delcared as the following:

@property CGFloat cornerRadius

The corner radius is a property of the layer which is a CALayer. In order to use this though you must be using iPhone SDK Version 3.0 or above and you must include QuartzCore/QuartzCore.h

Another tip was that the corner radius does not work until you set masksToBounds to true. With all of this combined the following snippet should allow you to create rounded rectangles on your UIViews.

//Includes
#import "QuartzCore/QuartzCore.h"

//To set the rounded corners
self.layer.masksToBounds = YES;
self.layer.cornerRadius = 5.0;

Using Rack::Rewrite to remove the www

Rack::Rewrite is a pretty useful tool. It allows you to change the location of a url or perform 301 or 302 redirects using rack. The real benefit of this is that the logic of your routes is contained within your app and server agnostic. Sure there is a performance hit compared to using mod-rewrite etc. in Apache, Nginx and so on but we feel its worth it in most cases. If you are using caching systems like varnish or squid the redirect can be cached too.

Using Rack::Rewrite to go NoWWW

There has been a bit of a movement for a while on the web to deprecate www. in front of domain names called no-www. As the site says the title www isn’t really of any use anymore. As well as the no-www movement having a single host can also be useful for things like analytics and cleaning up search results.  There are a couple of rails solutions to doing this including a peice of rack middleware at this site http://almosteffortless.com/2009/11/05/no-www-rack-middleware/.

If you are already using Rack::Rewrite though you may as well just use that to make the change. The following is a rule to make the no-www change using rack middleware.

r301 /.*/,  Proc.new {|path, rack_env| "http://#{rack_env['SERVER_NAME'].gsub(/www\./i, '') }#{path}" },
    :if => Proc.new {|rack_env| rack_env['SERVER_NAME'] =~ /www\./i}

Follow

Get every new post delivered to your Inbox.

Join 284 other followers