Under the Bridge

NSDateFormatter formatting

Ever wonder just what you could put in NSDateFormatter format strings? Enough to actually go to the trouble of actually dumping specifiers and results? Nah, us neither. But somebody did, and here’s what they found:

a: AM/PM
A: 0~86399999 (Millisecond of Day)
 
c/cc: 1~7 (Day of Week)
ccc: Sun/Mon/Tue/Wed/Thu/Fri/Sat
cccc: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday
 
d: 1~31 (0 padded Day of Month)
D: 1~366 (0 padded Day of Year)
 
e: 1~7 (0 padded Day of Week)
E~EEE: Sun/Mon/Tue/Wed/Thu/Fri/Sat
EEEE: Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/Saturday
 
F: 1~5 (0 padded Week of Month, first day of week = Monday)
 
g: Julian Day Number (number of days since 4713 BC January 1)
G~GGG: BC/AD (Era Designator Abbreviated)
GGGG: Before Christ/Anno Domini
 
h: 1~12 (0 padded Hour (12hr))
H: 0~23 (0 padded Hour (24hr))
 
k: 1~24 (0 padded Hour (24hr)
K: 0~11 (0 padded Hour (12hr))
 
L/LL: 1~12 (0 padded Month)
LLL: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
LLLL: January/February/March/April/May/June/July/August/September/October/November/December
 
m: 0~59 (0 padded Minute)
M/MM: 1~12 (0 padded Month)
MMM: Jan/Feb/Mar/Apr/May/Jun/Jul/Aug/Sep/Oct/Nov/Dec
MMMM: January/February/March/April/May/June/July/August/September/October/November/December
 
q/qq: 1~4 (0 padded Quarter)
qqq: Q1/Q2/Q3/Q4
qqqq: 1st quarter/2nd quarter/3rd quarter/4th quarter
Q/QQ: 1~4 (0 padded Quarter)
QQQ: Q1/Q2/Q3/Q4
QQQQ: 1st quarter/2nd quarter/3rd quarter/4th quarter
 
s: 0~59 (0 padded Second)
S: (rounded Sub-Second)
 
u: (0 padded Year)
 
v~vvv: (General GMT Timezone Abbreviation)
vvvv: (General GMT Timezone Name)
 
w: 1~53 (0 padded Week of Year, 1st day of week = Sunday, NB: 1st week of year starts from the last Sunday of last year)
W: 1~5 (0 padded Week of Month, 1st day of week = Sunday)
 
y/yyyy: (Full Year)
yy/yyy: (2 Digits Year)
Y/YYYY: (Full Year, starting from the Sunday of the 1st week of year)
YY/YYY: (2 Digits Year, starting from the Sunday of the 1st week of year)
 
z~zzz: (Specific GMT Timezone Abbreviation)
zzzz: (Specific GMT Timezone Name)
Z: +0000 (RFC 822 Timezone)

What, their word not good enough for you? You want an iPhone program to test it out for yourself? Well, here you can download that too. That should settle your date and time formatting needs once and for all!

Continue Reading →
11

Code: UITableView multiple selection

My, we do seem to be writing a lot about UITableView recently, don’t we? But this is a particularly good one — how to implement multiple-row selection and actions:

UITableView does not support multiple selection. We will use the method tableView:didSelectRowAtIndexPath: to detect touches in rows but the selected state will need to be stored separately (we cannot rely on the UITableView‘s selection).

We will also need a background view for displaying the selection color and a UIImageView for displaying the not-selected/selected indicator. Since the UIImageView will be hidden while not editing and the label for the row needs to move left or right when it is shown or hidden, we will also need to implement some form of layout for the UITableViewCell.

Other required behaviors include switching the “Edit”/”Cancel” buttons between modes, showing/hiding the toolbar at the bottom and tracking the number of selected rows to display in the button in the toolbar…

Mighty handy stuff, that. Code can be downloaded here. And from quickly flipping around, looks like the entire CocoaWithLove blog this comes from is worth your perusal, there’s quite a number of nifty pieces of esoterica therein.

h/t: iPhoneKicks!

Continue Reading →
0

Selection FAIL

Hey, looks like we’ve starting a continuing series of FAIL for your amusement and edification. Today’s exhibit is the proper selection behavior of your UITableView. Specifically,

Your application cannot be submitted to the App Store because of a Table View issue. Applications must adhere to the iPhone Human Interface Guidelines as outlined in iPhone SDK Agreement section 3.3.5.

According to the Table Views, Text Views, and Web Views section of the iPhone Human Interface Guidelines:

“Table views provide feedback when users select list items. Specifically, when an item can be selected, the row containing the item highlights briefly when a user selects it to show that the selection has been received. Then, an immediate action occurs: Either a new view is revealed or the row displays a checkmark to indicate that the item has been selected. The row never remains highlighted, because table views do not display persistent selected state.”

In your application, tapping on an item in the Table View results in the item becoming highlighted, and a new view is displayed. However, upon returning to the Table View, the item remains highlighted. Once the action has occurred, the Table View should no longer be highlighted when the user returns.

In order for your application to be reconsidered for the App Store, please resolve this issue and upload your new binary to iTunes Connect.

Sheesh. Somehow, we had completely managed to miss that there needed to be some active intervention there, we’d just kinda assumed that normal behavior would get taken care of by default. Ah, assumptions.

So, in case you happen to be submitting your first UITableView selecting app, here’s what we did to sort this out. In the appropriate UIViewController class, override:

// deselect selected row if any -- otherwise we GET REJECTED!
- (void)viewWillAppear:(BOOL)animated
{
   (void)animated;

   NSIndexPath *selection = [self.libraryTableView indexPathForSelectedRow];
   if (selection)
   [self.libraryTableView deselectRowAtIndexPath:selection animated:YES];
}

… and then we display the same animating out the selection when returning behavior that the iPod app for instance does. We trust that’s correct behavior.

Continue Reading →
2

Icon FAIL

Well, here’s a reason we hadn’t run into before for Apple to toss your app into the FAIL bucket:

Your application cannot be submitted to the App Store because it uses a standard “Camera” button for an action which is not its intended purpose. Applications must adhere to the iPhone Human Interface Guidelines as outlined in iPhone SDK Agreement section 3.3.5.

The “Camera” button is to be used to opens an action sheet that displays a photo picker in camera mode. Implementing standard buttons to perform other tasks will lead to user confusion. We recommend using Custom button.

In order for your application to be reconsidered for the App Store, please resolve this issue and upload your new binary to iTunes Connect.

That’s rather annoying, as we’d actually gone to some trouble to find that icon in a UITabBar-usable form specifically because that tab does display a photo picker in camera mode … once you’ve picked and positioned an overlay. Apparently Apple thinks users are very easily confused if that little diversion is too much for them.

Ah well. Live and learn. Hey, it could be worse, they could have actually found some problem with the code…

Continue Reading →
3

Code: Searching UITableView

Over at iPhoneSDKArticles.com they’ve been running a series on how to work with UITableView. The latest one is definitely worth your attention; it goes into step by step detail on how to manage the entire experience of allowing the user to refine the list with a search field.

When the user begins searching by clicking the search text box, we will do the following:

  1. Set the “searching” variable to YES.
  2. Set the “letUserSelectRow” variable to NO, since we do not want the user to select a row when the search box is empty.
  3. Display a done button on the right bar.
  4. Start searching as the user starts typing, this time allowing the user to select a row.
  5. Use a different data source to bind the table, which display’s the search reults.
  6. Search results are displayed in a single list and they are not grouped.
  7. Hide the keyboard and finish searching, when the user clicks on done.

Source code link doesn’t seem to be working for us at the moment … but most of it’s in the article anyways, and the missing bits can’t be hard to fill in, we’re sure.

h/t: iPhoneKicks!

Continue Reading →
3

Code: Accordion View

One of the up and coming interface styles these days is windows, particularly inspector palettes and the like, that have their individual sections expand and collapse. Call it “accordion” view, which we prefer, or “animated outline” view, or “modular” view, or “collapsing” view, or “disclosing” view, or whatever, it’s a nifty thing to do. But it’s rather complicated to get right. As we know for a fact, from implementing a kinda-sorta version of it for the Vonage Companion SIP client a while back.

Well, there’s help now: over at espresso-served-here  you can find what looks like a very slick implementation of the idea, Core Animation cool and everything:

To make one of these views isn’t quite as easy as you first think, and you can quickly go down the wrong road in the design. The super-secret trick is to *not* use Core Animation, or more precisely: ignore the lure of NSViews conformance to theNSAnimatablePropertyContainer protocol. As of Mac OS X 10.5, a few of the properties of a view or window can be animated simply be replacing calls like [view setFrame:newFrame]; with [[view animator] setFrame:newFrame];. This is fine when you have one or two views that you want to move but it’s impossible to coordinate the movements of multiple view using this API. After using Core Animation, one would expect that after a call such as [[view animator] setFrame:newFrame]; requesting the frame from the view would return newFrame. Unfortunatley it returns the original frame of the view. Only when the animation is done, do you get newFrame. Furthermore, just try setting the delegate of theCABasicAnimation object that handles the implicit animation and getting any form of useful information back. You can’t. You’re in for a world of pain if you try.

The solution: use good-ol’ NSViewAnimation. That way you can create all the dictionaries containing the animations for all the views you want to, then instantiate one NSViewAnimation object to handle the lot and set them off at the same time. Simple.

Indeed. Although that’s a definition of “Simple.” which is not in terribly common use, wethinks.  Much, much easier to just go grab the tlanimatingview project over at Google Code, yes?

Continue Reading →
1

Class: WAImageDropShadowEffect

Here’s a nifty curved drop shadow border for presenting an image with:

dropshadow

and here is the Core Graphics code to produce that effect, Open Source courtesy of the nice folks at WideAsleep, who you might remember from our very last post about their postmortem on application design of their Fairway application, which we looked at again but is apparently still something to do with golf. That aside, it looks like their blog is probably a good one to keep tabs on!

h/t: iPhoneKicks!

Continue Reading →
1

Fairway

Here’s a good read for you; the author of Fairway which is something to do with golf apparently has posted an extensive writeup on design iteration and UI implementation during its development:

My biggest goal releasing this application wasn’t just to release a golf application that I would use. It was to release a golf application I was proud of, one I didn’t cut corners on, one that I could recommend to any golfer with an iPhone. Heck even one I could recommend to someone interested in user interface design and interaction. I highly suggest you set similarly high bars for your release. It’s not enough to release an average iPhone application, you should instead strive to push the envelope and make your application distinctive and innovative.

A standard we should all strive to live up to, indeed!

Continue Reading →
1

Class: UICCalendarPicker

So you don’t like the looks of UIDatePicker and would prefer a conventional looking calendar view instead? Well, look what we have for you here:

uiccalendarpicker

Very nice, yes? Source available here for use freely (New BSD) courtesy of one Kishikawa Katsumi. Not being fluent in written Japanese (although ordering sushi and sake, that we do practice a lot) most of that is fairly mysterious to us, but if you’re better at that, try here or here for more details. The essence of it appears fairly clear, though:

UICCalendarPicker *calendarPicker = [[UICCalendarPicker alloc] initWithSize:UICCalendarPickerSizeMedium];
[calendarPicker setDelegate:self];
[calendarPicker setSelectionMode:UICCalendarPickerSelectionModeMultiSelection];
[calendarPicker showInView:self.view animated:YES];
[calendarPicker release];

h/t: iphonesdk!

Continue Reading →
2

imageNamed is evil

So a little while back we wrote about the confusing crashes on the device that we eventually figured out were caused by [UIImage imageNamed:] running out of memory when it tried to cache lots of big images. So we apparently solved the problem by making a thumbnail-sized image set and caching those, some 2.9 meg worth, whilst loading in the full sized ones uncached and only as needed.

Well, apparently turned out to be not good enough. See, it’s a few days later and we’ve finalized the design and got everything implemented and all seems to be good … except that it gets terminated without warning sooner or later. And quite often, Springboard terminates as well. Absolutely no correlation to any action or sequence in the program, no leaks, no out of bounds memory accesses, memory usage of the program barely a pittance. Yet, somehow, look at the console and you see system memory warnings scrolling by, you see it quitting background processes, and eventually quitting Springboard and/or the active application. Whilst that active application hums merrily along in blithe ignorance of the system crashing to the ground behind its back.

So apparently not only is 2.9 meg of images cached with +imageNamed enough to bring the iPhone OS to its knees, it’s not smart enough to, you know, actually do anything about it, like oh I don’t know, empty the cache or something?

It’s not like this is hard or anything, you can replicate the caching functionality precisely by declaring yourself an  NSMutableDictionary *thumbnailCache and populating it like

- (UIImage*)thumbnailImage:(NSString*)fileName
{
   UIImage *thumbnail = [thumbnailCache objectForKey:fileName];

   if (nil == thumbnail)
   {
      NSString *thumbnailFile = [NSString stringWithFormat:@"%@/thumbnails/%@.jpg", [[NSBundle mainBundle] resourcePath], fileName];
      thumbnail = [UIImage imageWithContentsOfFile:thumbnailFile];
      [thumbnailCache setObject:thumbnail forKey:fileName];
   }
   return thumbnail;
}

and if you do get a low memory issue, just [thumbnailCache removeAllObjects] and you’re good. But you know what? After replacing the various +imageNamed calls with this … not a single quibble anywhere, the whole 2.9 meg worth of cached thumbnails go right in there and not a single problem for, literally, hours.

(Not that there were any problems after those hours, we hasten to add; simply that, you know, if you think about it, there probably really isn’t a lot of point extending testing of an iPhone application much past the lifespan of a full battery charge…)

So the moral of the story is: DO NOT USE [UIImage imageNamed] for any significant amount of images. It is EVIL. It WILL bring down your application and/or Springboard, even when your application is putting along using just barely a nibble of memory on its own. Take the handful of lines above and implement your own cache!

Continue Reading →
87
Page 91 of 106 «...6070808990919293...»