Codec ░ Objective-C

569Layering one UIImage onto of another UIImage

Combining two images, especially useful, if the overlay image has an alpha value:

//
//  UIImage+Category.h
//  ImageOverlay
//
//  Created by Georg Tremmel on 29/04/2010.
//
 
#import <Foundation/Foundation.h>
 
 
@interface UIImage (combine)
 
- (UIImage*)overlayWith:(UIImage*)overlayImage;
 
@end

And the implementation file.

//
//  UIImage+Category.m
//  ImageOverlay
//
//  Created by Georg Tremmel on 29/04/2010.
//
 
#import "UIImage+Category.h"
 
@implementation UIImage (combine)
 
 
- (UIImage*)overlayWith:(UIImage*)overlayImage {
 
	// size is taken from the background image
	UIGraphicsBeginImageContext(self.size);
 
	[self drawAtPoint:CGPointZero];
	[overlayImage drawAtPoint:CGPointZero];
 
	/*
	// If Image Artifacts appear, replace the "overlayImage drawAtPoint" , method with the following
	// Yes, it's a workaround, yes I filed a bug report
	CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
	[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:0.999999999];
	*/
 
	UIImage *combinedImage = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
 
	return combinedImage;
}
 
@end

An update to 334 Combining Images with UIImage & CGContext – (Offscreen drawing)

(Did I say, how much I love Categories…?)

Update
I came across some strange behaviour when layering a PNG image with transparency over another image. Did not show up in the Simulator, only in iPhone 3GS (and probably also on other devices.)
The base image draws fine, but the overlay image appears to be truncated and the last pixels shifted, producing some bright green artifacts.
Changing

[overlayImage drawAtPoint:CGPointZero];

to

CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height);
[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:1.0];

did not really help; the green artifacts remainded. It was strange though, that they did not appear in the other blendmodes. Using

CGContextDrawImage(c, imageRect, [overlayImage CGImage]);

would also work, but then the images turn up upside down. Not what I really needed. (Yes, I know, there might not be a hard fix for that, but really – it should be that complicated.)

After playing a bit more with the values, I found, that setting alpha lower than 1.0 gets rid of the display artifact:

[overlayImage drawInRect:imageRect blendMode:kCGBlendModeOverlay alpha:0.9999999];

Bug filed at Apple’s Bug Report, let’s see. Or maybe am I missing something here?

Anyway here they the files are, zipped and ready for download.

Post Scriptum

Test Project, showing the visual artifact in action. Only appears on the device, NOT IN THE SIMULATOR.

581Resizing an UIImage 560#import vs #include in Objective C – A quick reminder 457Singleton Classes and Shared Resources in Objective-C 420Getting current Time with Microseconds 367Missing constants in RubyCocoa for Snow Leopard

560#import vs #include in Objective C – A quick reminder

#import is identical to #include, except that it makes sure that the same file is never included more than once. It’s therefore preferred and is used in place of #include in code examples throughout Objective-C–based documentation.

http://developer.apple.com/ mac/library/documentation/ cocoa/conceptual/ObjectiveC /Articles/ ocDefiningClasses.html

569Layering one UIImage onto of another UIImage 457Singleton Classes and Shared Resources in Objective-C 420Getting current Time with Microseconds 289Simulating Keyboard & Mouse Events. And Key-Modifier Events 275UIWebView – checking when user clicks a link

457Singleton Classes and Shared Resources in Objective-C

Resource.h

#import <Cocoa/Cocoa.h>
 
@interface Resource : NSObject {
	float myValue;
}
 
@property float scale;
 
+ (id)shared;
 
@end

 

Resource.m

#import "Resource.h"
 
@implementation Resource
 
@synthesize scale;
 
- (id)init {
	scale = 1.0f	// my default value
}
 
+ (id)shared {
	static Resource *sharedResource = nil;
	if (!sharedResource) {
		sharedResource = [[self alloc] init];
	}
	return sharedResource;
}
@end

An now it can be used like the following:

Resource *r = [Resource shared];
NSLog(@"Resource Test: %f", [r myValue]);
// Resource Test: 1.000000
 
[r setMyValue:2.0];
NSLog(@"Resource Test: %f", [r myValue]);
//# Resource Test: 2.000000
 
Resource *s = [Resource shared];
[s setMyValue:2.111];
NSLog(@"Resource Test: %f", [s myValue]);
// Resource Test: 2.111000
 
NSLog(@"Resource Test: %f", [r myValue]);
//Resource Test: 2.111000

Note that the values stays constant, even if another instantionation occurs. I guess that’s what Singleton classes are all about.

Adapted from Scott Stevenson’s fantastic introduction at Cocoa Dev Central.

And more tutorials from Scott Stevenson…
Cocoa Dev Central: Learn C for Cocoa
Cocoa Dev Central: Learn Objective C

569Layering one UIImage onto of another UIImage 560#import vs #include in Objective C – A quick reminder 420Getting current Time with Microseconds 289Simulating Keyboard & Mouse Events. And Key-Modifier Events 275UIWebView – checking when user clicks a link

420Getting current Time with Microseconds

#import &lt;sys/time.h&gt;
 
struct</span> timeval tv;
gettimeofday(&tv, NULL);
int sec = tv.tv_sec;
int usec = tv.tv_usec;

The system’s notion of the current Greenwich time and the current time zone is obtained with the gettimeofday() call, and set with the ettimeofday() call. The time is expressed in seconds and microseconds since midnight (0 hour), January 1, 1970. The resolution of the system clock is hardware dependent, and the time may be updated continuously or in “ticks.” If tp is NULL and tzp is non-NULL, gettimeofday() will opulate the timezone struct in tzp. If tp is non-NULL and tzp is NULL, then only the timeval struct in tp is populated. If both tp and tzp are NULL, nothing is returned.

Check out the man page for more info.

632Inline Functions in C 569Layering one UIImage onto of another UIImage 560#import vs #include in Objective C – A quick reminder 457Singleton Classes and Shared Resources in Objective-C 452Padding with Zeros (or other characters)

289Simulating Keyboard & Mouse Events. And Key-Modifier Events

Creating and Posting a Keyboard Event:

CGEventRef sDown, sUp;
sDown = CGEventCreateKeyboardEvent (
			NULL,
			(CGKeyCode)1,
			<strong>true</strong>
);
<strong class="red">CGEventSetFlags(sDown, kCGEventFlagMaskShift);</strong>  
 
// setting flags with special function. 
<em>// Setting it via CGCreateKeyboardEvent
// would work only for the first time it's run</em>
 
CGEventPost(kCGHIDEventTap, sDown);
 
sUp = CGEventCreateKeyboardEvent (
			NULL,
			(CGKeyCode)1,
			<strong>false</strong>
);
CGEventPost(kCGHIDEventTap, sUp);
 
CFRelease(sDown);
CFRelease(sUp);

That leaves the door open for applying the same to mouse events:

CGEventRef mouseEvent;
mouseEvent = CGEventCreateMouseEvent (
			NULL,
			kCGEventMouseMoved,
			CGPointMake(100, 100),
			kCGMouseButtonLeft
);
CGEventPost(kCGHIDEventTap, mouseEvent );

Magical. Isn’t it.

Of course, in pre-10.6 days it would have looked like that:

CGPostKeyboardEvent (0,5,true);
CGPostKeyboardEvent (0,5,false);

569Layering one UIImage onto of another UIImage 560#import vs #include in Objective C – A quick reminder 457Singleton Classes and Shared Resources in Objective-C 420Getting current Time with Microseconds 275UIWebView – checking when user clicks a link

275UIWebView – checking when user clicks a link

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

// intercepting web click in the webView
NSLog(@"%@, %i", [request.URL absoluteString], navigationType);
}

Don’t forget to set <UIWebViewDelegate>

569Layering one UIImage onto of another UIImage 560#import vs #include in Objective C – A quick reminder 553CAAnimation and the Snapback Problem 532OSC to and from the iPhone with VVOSC 536Adding a custom delegate

269Caching on Objective-C with NSURLCache

A quick reminder on how caching works in Objective-C.

Initially there is one cache, NSURLCache administrates it.

Get the object:

NSURLCache *cache = [NSURLCache sharedURLCache]
 
[cache memoryCapacity];
[cache setMemoryCapacity: 1024*1024*1]; // in byte
[cache currentMemoryUsage];

Don’t worry about the disk aka the flash memory in iPhone, it’s not accessible.

A bit of strange behaviour, either a bug in the software or in my brain:
When changing ViewControllers the memoryCapacity seems to reset itself to 0, although previous caches remain intact. Re-setting the memoryCapacity back to the original level seems to solve this. (The cache is not overwritten.)

Using the Cache
The whole point of using the cache is to not download online material over again. The following steps make for a happy cache:

//URLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:theURL
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];

The delegate response would allow you to alter the about-to-be-cached-data, leaving it in is not necessary:

- (NSCachedURLResponse *)connection:(NSURLConnection *)c
willCacheResponse:(NSCachedURLResponse *)response {
	NSLog(@"willCacheResponse");
	return response;
}

All in all, not that much to take it. Finding out, that the memoryCapacity gets reset was the most time-consuming bit.
For another example, of how to roll your own cache, look at URLCache example.

569Layering one UIImage onto of another UIImage 560#import vs #include in Objective C – A quick reminder 457Singleton Classes and Shared Resources in Objective-C 420Getting current Time with Microseconds 289Simulating Keyboard & Mouse Events. And Key-Modifier Events

265Like explode(), only componentsSeparatedByString:

PHP
explode(“, ” , “One, Two, Three”);

Objective-C
NSArray *listItems = [@"One, Two, Three" componentsSeparatedByString:@", "];

569Layering one UIImage onto of another UIImage 565Stripping Characters from an NSString 560#import vs #include in Objective C – A quick reminder 457Singleton Classes and Shared Resources in Objective-C 420Getting current Time with Microseconds

259The mystery of self.* – resolved?

self
If you want to access a property of self using accessor methods, you must explicitly call out self as illustrated in this example:

self.age = 10;

If you do not use self., you access the instance variable directly. In the following example, the set
accessor method for the age property is not invoked:

age = 10;

p57, The Objective-C 2.0 Programming Language Language (v2008-06-09)
p22, The Objective-C 2.0 Programming Language Language (v2009-10-19)

So basically it’s a shortcut to:

int* a = [self age];
[self setAge:12];

(providing there is a setter/getter for age.)

569Layering one UIImage onto of another UIImage 560#import vs #include in Objective C – A quick reminder 457Singleton Classes and Shared Resources in Objective-C 420Getting current Time with Microseconds 289Simulating Keyboard & Mouse Events. And Key-Modifier Events

243Stepping over an Array (or Dictionary)

NSArray *paths = [[NSFileManager defaultManager] 
	directoryContentsAtPath: NSHomeDirectory()];
<del datetime="2010-04-01T02:49:15+00:00">
// either like that...
NSEnumerator *e = [paths objectEnumerator];
for (NSString *p in e) {
	NSLog(@"path: %@", p);
}
 
// or like that.
for (NSString *p in [paths objectEnumerator]) {
	NSLog(@"path: %@", p);
}

NSDictionary has both [myDict objectEnumerator] and [myDict keyEnumerator].

Fast Enumberation is a feature in Objective-C 2.0, it allows you to step over arrays and dictionaries in a fast, consice, and secure (guarded against mutations) manner.

for (NSString *p in paths) {
	NSLog(@"path: %@", p);
}
 
// or
 
NSString *p;
for (p in paths) {
	NSLog(@"path: %@", p);
}

Sometimes things are really as simple as they should be.

576NSDictionary and NSArray plist examples 569Layering one UIImage onto of another UIImage 560#import vs #include in Objective C – A quick reminder 457Singleton Classes and Shared Resources in Objective-C 420Getting current Time with Microseconds