Update
Version 3.2 with new sample for iOS 4.2 is available here.
I just pushed some changes to github, and make MapKitDragAndDrop version 3.1:

In version 3.0, when -initWithAnnotation:resuseIdentifier: called, I create annotationView based on the availability of MKAnnotationView’s isDraggable property. If MKAnnotationView can handle isDraggable, I will return the built-in MKPinAnnotationView; if not, I create DDAnnotationView instead, and let it handle the drag/drop functionality.
But here comes one problem: though document said isDraggable only available in iOS 4 and later, iOS 3.2 does has this property (but not enabled). As result, my
self.hasBuiltInDraggingSupport = [[MKAnnotationView class] instancesRespondToSelector:NSSelectorFromString(@"isDraggable")];
will return YES on iOS 3.2, and create the non-draggble MKPinAnnotationView back.
So one of the quickest solution is to check system version number instead of using -instancesRespondToSelect: to decide if we need to use DDAnnotationView:
self.hasBuiltInDraggingSupport = [[UIDevice currentDevice] systemVersion] compare:@"4.0" options:NSNumericSearch] != NSOrderedAscending;
That’s one of the changes in version 3.1.
As for synthesized by default, I previously enabled Objective-C 2.0 Non-fragile ABI for using the “synthesized by default” feature in MapKitDragAndDrop 3.0, turns out it a pain in the butt for many developers, even Apple removed these options in latest Xcode 4 preview.
And my thoughts on ivar changed: If you really want to get rid of ivar in Objective-C, use NSManagedObject. That’s more likely to be an ideal solution to you, even though you get other messy problems. Keep using ivar is not a bad idea after all, that’s how I told myself.
So, after considering, I changed my mind, no more synthesized by default in this version, and you are allowed to use either GCC or LLVM Compiler with it now.
Source code is licensed under MIT license. You can download it from github.
Update
Version 3.2 with new sample for iOS 4.2 is available here.
With iOS 4 MapKit built-in draggable support, MapKitDragAndDrop now goes to version 3.
MapKitDragAndDrop is designed to bring drag and drop support to MapKit on iPhone platform, with just one single lightweight DDAnnotation and DDAnnotationView, users are able to drag and drop annotation pin and get the new coordinate.
For real world example, you can check out my app: QR+Emoji
In version 3, the whole project had shifted to modern runtime, using Objective-C 2.0 ABI and LLVM 1.5 compiler. So you will have smaller and faster binary that runs on both iOS 4 and ealier iPhone OS 3.1.x/3.2 at the same time.
Project file (.xcodeproj) needs to:
-Xclang here means “pass argument to the clang compiler,” and the argument is -fobjc-nonfragile-abi2. So you should add ‘-Xclang -fobjc-nonfragile-abi2’ into $OTHER_CFLAGS.
For more details, check “-Xclang -fobjc-nonfragile-abi2” is single flag with one argument.

Source code is licensed under MIT license.
You can download it from github.
Customize FBStreamDialog content style from client:
NSString *override = @"document.getElementsByClassName('caption')[0].style.fontSize = 'medium';";
if ([self isKindOfClass:NSClassFromString(@"FBStreamDialog")]) {
[_webView stringByEvaluatingJavaScriptFromString:override];
}
I haven’t had a chance to talk about my DDBadgeViewCell last week, though it’s been used in my app for a while.

There are many projects and samples trying to do the similar thing, they all want a customizable colored round view, and DDBadgeViewCell does too.
DDBadgeViewCell is an UITableViewCell subclass with one badge view on the right. That badge view is customizable. You can change colors, including text color, badge color, and badge color when cell is hightlighted. You can also change text, it can be any characters, and the badge width will update along with text length.
And my approach for creating round colored badge view is inside drawRect: with CGPath and Blending mode. the whole drawRect: can be seperated into several parts:
First, get the current graphics context from stack by calling UIGraphicsGetCurrentContext().
CGContextRef context = UIGraphicsGetCurrentContext();
And I define some colors that need to be used later.
UIColor *currentSummaryColor = [UIColor blackColor];
UIColor *currentDetailColor = [UIColor grayColor];
UIColor *currentBadgeColor = self.cell.badgeColor;
if (!currentBadgeColor) {
currentBadgeColor = [UIColor colorWithRed:0.53 green:0.6 blue:0.738 alpha:1.];
}
And update colors based on cell status, like isHighlighted or isSelected.
if (self.cell.isHighlighted || self.cell.isSelected) {
currentSummaryColor = [UIColor whiteColor];
currentDetailColor = [UIColor whiteColor];
currentBadgeColor = self.cell.badgeHighlightedColor;
if (!currentBadgeColor) {
currentBadgeColor = [UIColor whiteColor];
}
}
Calculate badge text CGSize with sizeWithFont:, and defined badge frame size with some hardcode values.
CGSize badgeTextSize = [self.cell.badgeText sizeWithFont:[UIFont boldSystemFontOfSize:13.]];
CGRect badgeViewFrame = CGRectInset(CGRectIntegral(CGRectMake(rect.size.width - badgeTextSize.width - 20,
(rect.size.height - badgeTextSize.height) / 2, badgeTextSize.width, badgeTextSize.height)), -7, -2);
Here comes the point. Save the current graphic state onto context, so we can restore it and do the blending things later.
CGContextSaveGState(context);
Set the color for filling the path later.
CGContextSetFillColorWithColor(context, currentBadgeColor.CGColor);
People usually do drawing directly on CGContext, like using CGContextAddLine() or CGContextAddArc() etc. But I prefer the other way: creating a mutable graphics path (CGPath) first, add line or arc to it, and add final path into context, then ask contect to darw it.

The good thing about using mutable path here is: you can easily create a closed round path only by calling ONE function TWICE, CGPathAddArc(), one is the left arc, and the other is the right arc. And you don’t have to fill the lines between these two arcs by yourself, it was already done when second arc was added. Sounds cool, huh?
Once path drawn to context, we restore the graphic state, back to the state we haven’t drawn the round badge path.
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddArc(path, NULL, badgeViewFrame.origin.x + badgeViewFrame.size.width - badgeViewFrame.size.height / 2,
badgeViewFrame.origin.y + badgeViewFrame.size.height / 2, badgeViewFrame.size.height / 2, M_PI / 2, M_PI * 3 / 2, YES);
CGPathAddArc(path, NULL, badgeViewFrame.origin.x + badgeViewFrame.size.height / 2,
badgeViewFrame.origin.y + badgeViewFrame.size.height / 2, badgeViewFrame.size.height / 2, M_PI * 3 / 2, M_PI / 2, YES);
CGContextAddPath(context, path);
CGContextDrawPath(context, kCGPathFill);
CFRelease(path);
CGContextRestoreGState(context);
Then we save the graphic state again, set the blending mode, and draw the text on top of the badge where we done previously. And since we use kCGBlendModeClear, the CGPath we previous drawn and filled with color will have text on top that can be seeing throguh clearly.
CGContextSaveGState(context);
CGContextSetBlendMode(context, kCGBlendModeClear);
[self.cell.badgeText drawInRect:CGRectInset(badgeViewFrame, 7, 2) withFont:[UIFont boldSystemFontOfSize:13.]];
CGContextRestoreGState(context);
And below are for the summary and detail drawning, which is much easier compare with above.
[currentSummaryColor set];
[self.cell.summary drawInRect:CGRectMake(10., 10., badgeViewFrame.origin.x - 15., 22.)
withFont:[UIFont boldSystemFontOfSize:18.] lineBreakMode:UILineBreakModeTailTruncation];
[currentDetailColor set];
[self.cell.detail drawInRect:CGRectMake(10., 32., badgeViewFrame.origin.x - 15., 18.)
withFont:[UIFont systemFontOfSize:14.] lineBreakMode:UILineBreakModeTailTruncation];
You can download DDBadgeViewCell project from my github.
DDBadgeViewCell can be used on iPhone 3.1 or later, but the sample program was created on iPhone SDK 4.
Google can try to create a Buzz Game Centre that INVITES all the Gmail users in no time, then Android MIGHT have chances be #1.
This is a quick hack for FutureTap’s InAppSettingsKit, which allows you to add a URL to be opened in application (through UIApplication’s openURL:) but hidden in Settings.app.
Add DDOpenURLSpecifier element in your Root.plist, like this:

And use the modified version of InAppSettingKit to load the settings.bundle, done.

This is how it looks like in InAppSettingsKit (left), and hidden in Settings.app (right).
DDOpenURLSpecifier is a custom element type for iPhone settings application schema. This element displays a preferences row (only in InAppSettingsKit, not Settings.app), that when tapped will ask application to open the URL. You can use this element type to open the resource at the specified URL, such as http:, https:, tel:, mailto:, or any other URL schema you want.
DDOpenURLSpecifier has same keys found in PSChildPaneSpecifier element:
Type (required), String, The value of this key is always set to DDOpenURLSpecifier. This key is required.Title (required, localized), String, The title string displayed in the preference row. This is the string the user taps to display the next page. This string is also used as the title of the screen that is subsequently displayed. This key is required. The value of this key is localizable.File (required), String, The URL (Universal Resource Locator) to open. For example, if you want your application to open Apple’s web site in Safari browser, you would assign the value http://www.apple.com to this key. This key is required.You can get the modified InAppSettingsKit from my github.
This hack had been merged back to InAppSettingsKit as IASKOpenURLSpecifier, just grab the latest version and you get this feature.
UIApplication has two notifications:
They are posted when application is “about to change” or “changed” the orientation of its interface. And the iPhone SDK also tells you, the userInfo dictionary contains an NSNumber that encapsulates a UIInterfaceOrientation value, and you can use UIApplicationStatusBarOrientationUserInfoKey to get it:
UIInterfaceOrientation theOrientation = [[notification.userInfo valueForKey:UIApplicationStatusBarOrientationUserInfoKey] integerValue];
However, the SDK didn’t tell you the value inside the userInfo dictionary is not equal to:
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
Actually, the one in UIApplicationWillChangeStatusBarOrientationNotification means:
“The orientation we will change to”
and the one in UIApplicationDidChangeStatusBarOrientationNotification means:
“The orientation we changed from”
Both of them happened to be NOT EQUAL to the current orientation of UIStatusBar, and the documentation didn’t mention this part. So, be sure to aware of the difference.
By the way, don’t try to get view bounds or frame when UIApplicationDidChangeStatusBarOrientationNotification posted, they are not changed yet.
It’s easy, Apple can’t make it ready within 60 days.
It’s curious why iPad does not come with Traditional Chinese support in its current version while it does Simplified Chinese. Perhaps it’s not yet fully localized, or perhaps the input methods are not ready yet. Curious, then—since Simplified Chinese is there, and Apple can just use the same code base that is used in iPhone and iPod touch. But on the other hand, iPhone did not come with appropriate Traditional and Simplified Chinese until OS 2.0, and a lot of other languages now available on iPhone (Korean and Hebrew, to name just two) are not supported on iPad yet.
loading…