聽說 LINE 前陣子突破三千萬用戶,這幾天推出的新版本還加入了表情圖示商店,可以讓你自掏腰包花錢買新的用。一開始抱著存疑的態度看看,不看還好,看了就覺得這屌爆了。他們這樣可能沒多久就又多了三千萬用戶吧…
(Source: line.naver.jp)
東海旅客鉄道株式会社
東海道新幹線をご利用の際、出発・到着の各駅と予定時刻を入力するだけで、沿線の風景や名物が次々に現れるアニメーションを楽しめるほか、自分の現在位置のおおよその目安にもなります。
As planned, I pushed my FrostyPlace app to GitHub this afternoon.
FrostyPlace is a RSS/Forum reader for iOS, designed for frostyplace.com. It’s one of my very first apps on App Store, and later got its 15 minutes of fame on 2009 (thanks to @iJustine). After being silent for a long time, the version 2.0 appeared on App Store eight months ago, and users are happy with it, again.
Due to my upcoming career changes, I need to close my business on App Store. On August 14th, 2011, exact one month later from now, all my apps on App Store will be removed from sale, including FrostyPlace app.
And to keep the project alive, I published the latest FrostyPlace source code to GitHub, and licensed under New BSD License, so people who wants to know more about this app can get benefits from it.
Enjoy.
Screenshot on the left is Google’s latest Google TV Remote app for iOS, and the other is Apple’s Remote app. You can easily tell the difference between Google and Apple from their user interface design.
One word, simplicity.
Problems underlying the UIDickBar are analyzed and concluded in here: Problems and the Solution for UIDickBar.
On March 31, 2011, Twitter removed the UIDickBar from their iPhone client version 3.3.3.
#dickbar, “Twitter’s mainstream consumer client experience,” now available for your iOS apps too.

This project got lots of attentions since this morning (thanks, @justin), and here are some great retweets:
And UIDickBar becomes the #1 trending repos within 24 hours, also the #1 featured repos on github.com.
Thanks again for all the warm welcome!
For those who want to create custom notification view, any forms of design similar to this are really bad idea, really, no kidding.
Because notification is a kind of interruption, it breaks the continuity. Unlike UIAlertView, UIDickBar uses disrupting way to interrupt information, and users feel confused when dealing with two different information flows at the same time. If you want to know more details about problems underlying the UIDickBar, read this.
Please think for your users before using it.
You simply init UIDickBar with title, badge and an action block:
UIDickBar *dickBar = [[UIDickBar alloc] initWithDickTitle:@"#DickBar" dickBadge:@"Stupid" actionBlock:^{
// Anything you want to do after UIDickBar tapped
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://digdog.tumblr.com"]];
}];
[dickBar showInView:self.view];
[dickBar release];
Then you call -showInView: to display UIDickBar that originates from the specified view.
UIDickBar is available on github.
UIDickBar is released under MIT License.
If you’re an iOS developer, and love the sitcom The Big Bang Theory, then you have to watch season 4 episode 12: The Bus Pants Utilization (original air date is January 6, 2011.)
In this episode, Leonard comes up with an idea for his iOS app and derails his friendship with Sheldon.
It’s a handwriting-recognition based equation solver, or in Sheldon’s way: “The Surprisingly Helpful Equation-Linked Differential Optimized Numerator.” The idea behind this is to use iPhone’s camera to take a picture of the equation, and scan it with handwriting recognition, then run it through a symbolic evaluation engine, and bam.
During the episode, they show several actual Objective-C code snippets and interesting design sketches on white boards, here are some of them:
They have a CRecognition object holds an UIImage instance variable, and sadly they name it _Photo (with underline as prefix), it’s not the naming convention Apple suggested.
The next morning, Sheldon starts his own design, if you look closer, it’s much more considered than Leonard’s.
For example, since this is an utility app, Sheldon comes up with a flip view design that similar to built-in Camera/Stocks app. A full screen SPhotoView with a snapshot button in the middle, and on the other side, it’s SEquationView and a UITableView at the bottom with some buttons.
In here, you can see more details. A UITableView holds the scanned equations, and supports rotation for landscape full screen detail view and portrait detail view. On the right side, Sheldon shows better understanding about UIViewController’s view hierarchy design concept.
Later, Leonard’s team is doing some reference counting. Instead of accessing instance variable directly in -initWithPhoto: and -dealloc, they decide to use retain property self.photo, with class method to return a autoreleased CRecognition object, and claim there’s no leaks.
What a mess, you should always use instance variable directly in -initWithPhoto: and -dealloc when creating/releasing instance object.
Here you see Leonard’s app class hierarchy, mostly MFC-ish (thanks, @lukhnos.) style naming convention for the class names, almost everything starts with letter “C” (is for “Class” I think), CAppDelegate, CMainView, CCameraView, CSymbolicView, etc. They should use prescribed prefix like “LRH,” which means Leonard, Rajesh and Howard.
The beautiful Penny is next to Sheldon, and there’s Facebook API on the white board.
In the end, Penny’s shoes app project. There’re many of them on the AppStore already, and the UI design for this one looks kinda lame.
And Sheldon is working on this project… (for customer from hell?)
I love and enjoy this episode a lot, and the TBBT crew does a great job for all these minor details, they look very convincing to me.
But, they should use Mac when doing the coding, I only saw Raj’s MacBook Pro, and rest of them are using PCs. That’s not right, you can’t run Xcode on PC, well, unless they all use Hackintoshes…
Also, If you want to hire someone for your iOS app project, I highly recommend Sheldon Cooper.
I asked the other day on Twitter if I should expire beta app, and people are saying yes. So I made a quick solution for my beta:
The iOS app will show an UIAlertView two weeks after built, then
exit(0);itself after user dismissed the alert view.
First, I add following code snippet into my main view controller:
#ifdef BETA_EXPIRATION
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"MMM d yyyy"];
NSLocale *localeUS = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];
[dateFormatter setLocale:localeUS];
NSDate *compileDate = [dateFormatter dateFromString:[NSString stringWithUTF8String:__DATE__]];
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSWeekCalendarUnit
fromDate:compileDate
toDate:[NSDate date]
options:0];
// Expired after 2 weeks
if ([components week] > 1) {
UIAlertView *expirationAlert = [[UIAlertView alloc] initWithTitle:@"Beta Expired"
message:@"Thanks for testing beta for these two weeks"
delegate:self
cancelButtonTitle:@"Terminate Now"
otherButtonTitles:nil];
[expirationAlert show];
[expirationAlert release];
}
}
#pragma mark UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
exit(0);
}
#endif
The __DATE__ preprocessor constant represents the date that source code compiled, it will be replaced with a string literal in following form during compile time:
“mmm dd yyyy”
We can prepare a NSDateFormatter to translate __DATE__ string into NSDate, represent the time we compiled app.
Later, use NSDateComponents to compare compile date and current date with calendrical unit flag NSWeekCalendarUnit, so that we can know how many weeks had passed since the app was built. I use week for example here, but you can change to other units, like NSHourCalendarUnit, NSDayCalendarUnit, NSQuarterCalendarUnit etc.
Also, in this code snippet, the first seven days are calculated as “week zero,” following the next seven days for “week one.”
So, once users launch the app two weeks later, I will show them a UIAlertView, and terminate the app once they click the button.
I use #ifdef BETA_EXPIRATION ... #endif to limit the section of code to be built for AdHoc version only.
The easiest way to do that, is opening your Xcode project file, add value for “Preprocessor Macros” that in your target settings:

There’s no sample for this, the code snippet above is all you need.
Feel free you use it.
BTW, this can be easily hacked, so use with caution if you’re delivering some top secret apps for testing.
Last month, I wrote “How I add background image to UINavigationBar.” By using CALayer’s contents property, you can easily add a CGImage to your UINavigationBar.
And this time, I’m going to show you, how I add background image into UIViewController and to support both landscape and portrait mode.
For iPhone and iPod touch, you need a 480 by 480 pixels image (also a 960 by 960 pixels for retina display); and for iPad user, you need one 1024 by 1024 pixels image. So that you can use it as background image for both landscape and portrait mode:

Then you can set CGImage into UIViewController’s self.view.layer.contents, and use contentsRect to change the the sub-rectangle of contents that we should draw:
#import <QuartzCore/QuartzCore.h>
- (void)viewDidLoad {
self.view.layers.contents = (id)[UIImage imageNamed:@"myBackground"].CGImage;
if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
self.view.layer.contentsRect = CGRectMake(0.0, 0.0, 1.0, 320.0/480.0);
} else {
self.view.layer.contentsRect = CGRectMake(0.0, 0.0, 320.0/480.0, 1.0);
}
}
If want to support rotations, you will need to change contentRects again in - (void)didRotateFromInterfaceOrientation:.
P.S. If you want to prevent background image resized when UIToolbar shows up, you can change self.view.layer.contentsGravity from default kCAGravityResize to kCAGravityBottom.
@drunknbass wonder why not using +colorWithPatternImage: instead?
My concern here is memory, if I use +colorWithPatternImage: with a single large image, it will cost lots of memory than the way I used above. I’m not sure why this happened, but @drunknbass promised he will dig into this when he is lazy (enough).
loading…