Archive for the ‘Apple’ Category

Barebones CAEmitterLayer aka Particle Effects

Wednesday, February 24th, 2010

CAEmitterLayer: use to create particle effects. Each particle is an instance of CAEmitterCell. (10.6) – cocoadevcentral

How could you not be intrigued? Particle Effects! Well I’ve always been interested in Particle Generators, and there’s one right here in Snow Leopard. How exciting. /claps.

I recently took a look at the Fire and Fireworks sample code that Apple and was duly impressed by what Core Animation provides for so little cost both code-wise and CPU resources. So I decided to write the simplest – barebones – CAEmitterLayer code where I was only dependant on the NSView it draws on.

There’s no fancy-pants stuff going on here, just a raw, simple, single particle effect. But it gives you a great perspective on how it works and the minimal code required to have a great particle animation.

Screenshot of this project

If you’re starting afresh you’re going to need to tell your project that we want to use Core Animation so:

Looking at CAEmitterLayer briefly (and ignoring setting up Interface Builder & the Nib) in our header file we simply need a CAEmitterLayer:

IBOutlet NSView *view;
CALayer *rootLayer;
CAEmitterLayer *emitter;

Where as the implementation file is going to need a whole lot of data for the Emitter plus we need to create a CAEmitterCell for the particle itself.

//Create the emitter layer
emitter = [CAEmitterLayer layer];
emitter.emitterPosition = CGPointMake(CGRectGetMidX(rootLayer.bounds), CGRectGetMidY(rootLayer.bounds));
emitter.emitterMode = kCAEmitterLayerOutline;
emitter.emitterShape = kCAEmitterLayerCircle;
emitter.renderMode = kCAEmitterLayerAdditive;
emitter.emitterSize = CGSizeMake(50 * multiplier, 0);
 
//Create the emitter cell
CAEmitterCell* particle = [CAEmitterCell emitterCell];
particle.emissionLongitude = M_PI;
particle.birthRate = multiplier * 1000.0;
particle.lifetime = multiplier;
particle.lifetimeRange = multiplier * 0.35;
particle.velocity = 180;
particle.velocityRange = 130;
particle.emissionRange = 1.1;
particle.scaleSpeed = 0.3;
CGColorRef color = CGColorCreateGenericRGB(0.3, 0.4, 0.9, 0.10);
particle.color = color;
CGColorRelease(color);
particle.contents = (id) [self CGImageNamed:@"spark.png"];

For the complete implementation file or the complete project please feel free to grab the source code from the bitbucket project.

Font Smoothing in Snow Leopard with a 3rd Party LCD

Thursday, January 14th, 2010

Having connected a 3rd party (Polyview) 19″ LCD into the work MacBook Pro I was struck by how poor any on screen text rendered. Trying to use Terminal.app was just aweful, all jaggy and hard to read.

It turns out that font smoothing (aka sub-pixel antialiasing) on the 3rd party screen wasn’t happening and OS X was defaulting the font smoothing to CRT. Take a look at the screenshots below, bad eh?

Antialiasing for CRTs, ewwwww.

Antialiasing fixed!

How to fix the problem?

Open up terminal and paste in the following:

defaults -currentHost write -globalDomain AppleFontSmoothing -int 2

or if you find the text a little large/blurry you can try:

defaults -currentHost write -globalDomain AppleFontSmoothing -int 1

Now logout > login.

So what’s up?

The whole Snow Leopard font smoothing issue seems strange and why Apple changed the font smooth dialog is beyond me. But you can read more about it here
jjgod / blog > Snow Leopard vs. 3rd Party LCD Displays if you’d like to know a little more about the problem.

Resize UIView/UITableView when Keyboard displays

Tuesday, June 2nd, 2009

I was having a hell of a time trying to get my UITableView to resize itself after the iPhone keyboard displayed itself. After being just a little surprised that the iPhone doesn’t resize the underlying UIView for free I figured it was up to me to do resize.

Firstly add a few variables and method declares into your ViewController.h header file:

Boolean keyboardIsShowing;
CGRect keyboardBounds;
- (void)resizeViewControllerToFitScreen;

Now we need to register for the UIKeyboardWillShowNotification and the UIKeyboardWillHideNotification:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

And these notifications need somewhere to go:

#pragma mark -
#pragma mark Keyboard Handling
 
- (void)keyboardWillShow:(NSNotification *)notification {
	NSDictionary *userInfo = [notification userInfo];
	NSValue *keyboardBoundsValue = [userInfo objectForKey:UIKeyboardBoundsUserInfoKey];
	[keyboardBoundsValue getValue:&keyboardBounds];
	keyboardIsShowing = YES;
	[self resizeViewControllerToFitScreen];
}
 
- (void)keyboardWillHide:(NSNotification *)note {
	keyboardIsShowing = NO;
	keyboardBounds = CGRectMake(0, 0, 0, 0);
	[self resizeViewControllerToFitScreen];
}

And now add the magic method to resize the view:

- (void)resizeViewControllerToFitScreen {
	// Needs adjustment for portrait orientation!
	CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
	CGRect frame = self.view.frame;
	frame.size.height = applicationFrame.size.height;
 
	if (keyboardIsShowing)
		frame.size.height -= keyboardBounds.size.height;
 
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationBeginsFromCurrentState:YES];
	[UIView setAnimationDuration:0.3f];
	self.view.frame = frame;
	[UIView commitAnimations];
}

And super importantly de-register the ViewController from those notifications.

- (void)viewWillDisappear:(BOOL)animated {
	[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
	[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

See how this all comes together?

1. We register for Notifications when the Keyboard shows/hides,
2. We react when the keyboard is shown/hidden,
3. The resizeViewControllerToFitScreen method handles our resize, including animating the underlying view so it looks pretty.

There’s a few caveats:

1. I’ve not tested on Landscape mode, I’m pretty sure this will fail.
2. UIKeyboardWillShowNotification can get fired every time you enter a textbox (as I’ve only one textbox it’s not a problem for me). So you might need to look at using …TextDidBeginEditing/…TextDidEndEditing or maintaining state differently so that the view isn’t jumping all over the place.

Geektool: Use that wasted space beside the Dock

Friday, May 22nd, 2009

One little gripe I’ve always had about in OS X is the apparent waste of space either side of the Dock (assuming you have it centred at the bottom of the screen).

Geektool to the rescue!

View the image at QuickSnapper.com

Here’s the little scripts that I use to get the weather (just change the region code ASXX0016 to your region from weather.yahoo.com. Your region code will be found in the yahoo URL):

curl --silent "http://xml.weather.yahoo.com/forecastrss?p=ASXX0016&u=c" | grep -E '(Current Conditions:|C<BR)' | sed -e 's/Current Conditions://' -e 's/<br \/>//' -e 's/<b>//' -e 's/<\/b>//' -e 's/<BR \/>//' -e 's/<description>//' -e 's/<\/description>//'
curl --silent "http://xml.weather.yahoo.com/forecastrss?p=ASXX0016&u=c" | grep -E '(High:)' | sed -e 's/<BR \/>//' -e 's/<b>//' -e 's/<\/b>//' -e 's/<BR \/>//' -e 's/<br \/>//'

And the script for Memory usage, HDD space and Uptime:

top -l 1 | awk '/PhysMem/ {print $10}' 
df -hl | grep 'disk0s2' | awk '{print $4}'
echo "Uptime: "`uptime | awk '{print "" $3 " " $4 " " $5 }' | sed -e 's/.$//g';`

You might also be interested to check out other uses of Geektool on Flickr

To Apple: Let us put Widgets on the Desktop too please (without having to use a hack).

sudo in OS X with non-admin account

Tuesday, November 25th, 2008

I try to keep my Mac nice and secure so I run my everyday account ben with non-administrator privileges and keep an admin account so when I install Apps or use Software Update I will be asked for the admin user and password. This works just fine, but when I attempt to

sudo

from the command-line: Fail.

For example I was attempting to update Rails to version 2.2;

gem update rails

this of course failed, so I tried;

sudo gem update rails

When asked for my password, the admin password would fail, and my ben password would fail too with the error “ben is not in the sudoers file”. I expected the ben everyday-user to fail, but how to get my admin user to step up to the plate and take over?

Well I found the secret from here and it worked beautifully. Simply type

su <admin username>
sudo <command>
password: <admin password>

Yipee, sudo from OS X terminal, finally.

And type

exit

to restore to your previous account prior to running su.