Objective-CでCSSでよく使うようなABCDEFFFのようなHex encodeされた形式の文字列からUIColorを生成する方法の紹介です。

   1  @interface UIColor (HexEncoding)
   2  + (UIColor*)colorFromString:(NSString*)string;
   3  - (NSString*)encodeToString;
   4  @end
   5  
   6  @implementation UIColor (HexEncoding)
   7  
   8  + (UIColor*)
   9  colorFromString:(NSString*)string
  10  {
  11    NSScanner *scanner = [NSScanner scannerWithString:string];
  12    NSUInteger value;
  13    [scanner scanHexInt:&value];
  14    CGFloat red   = ((value & 0xFF000000) >> 24) / 255.0f;
  15    CGFloat green = ((value & 0x00FF0000) >> 16) / 255.0f;
  16    CGFloat blue  = ((value & 0x0000FF00) >>  8) / 255.0f;
  17    CGFloat alpha = ((value & 0x000000FF) >>  0) / 255.0f;
  18    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
  19  }
  20  
  21  - (NSString*)encodeToString
  22  {
  23    const CGFloat *components = CGColorGetComponents(self.CGColor);
  24    return [NSString stringWithFormat:@"%02x%02x%02x%02x",
  25            (int)(components[0]*255 + 0.5f),
  26            (int)(components[1]*255 + 0.5f),
  27            (int)(components[2]*255 + 0.5f),
  28            (int)(components[3]*255 + 0.5f)];
  29  }
  30  
  31  @end

わかりやすいように、UIColorにメソッドカテゴリを追加しています。 encodeToStringのほうでは、0.5を足してroundをかけていますが、 状況に応じてfloorにしたりceilにしたりしてください。

また、この例ではComponentsのサイズが4である事を期待しています。 そうではない色を扱うときには問題が発生しますので、ご注意ください。

posted by Png genki on Fri 7 Nov 2008 at 12:20

Objective-Cは、Rubyのようにメソッドの定義を書き換えたりする事ができます。

   1  #import <objc/runtime.h>
   2  
   3  id (*foo_without_bar)(id, SEL);
   4  id foo_with_bar(id self, SEL selector)
   5  {
   6    /* do your work here */
   7    return foo_without_bar(self, selector);
   8  }
   9  
  10  // exchange method implementation
  11  SEL fooSelector = @selector(foo);
  12  Method method = class_getInstanceMethod(class, fooSelector);
  13  *(IMP*)&foo_without_bar =
  14    method_getImplementation(method);
  15  method_setImplementation(method, (IMP)foo_with_bar);

この例では、IMPの定義と同じプロトタイプのメソッドを書き換えてるので不要ですが、IMPの定義と異なるプロトタイプのメソッドを書き換える場合は、 IMPにキャストする必要があります。

また、戻り値が浮動小数型であったり、サイズが大きい構造体を返すメソッドの場合は、上記の例とは異なる方法を使う必要があるので、注意が必要です。(NSInvocationを使う必要があります)

See Also

posted by Png genki on Fri 7 Nov 2008 at 12:00 with 2 comments

UIScrollViewのscrollRectToVisible:animated:の挙動についてのメモです。

これは名前の通り、第一引数で指定したCGRectをViewの可視領域に 持って行くためのメソッドなのですが、 可視領域からはみ出すような大きなCGRectを指定した場合は、CGRectの下端が優先的に表示されるような挙動になるようです。 また、CGRectがemptyの場合は何もおこりません。

上端を優先して表示させたい場合は、 可視領域のCGRectを求めて、あらかじめ可視領域に収まるようにしてから呼び出せばOkです。

ところで、このメソッドはcontentInsetを意識してくれないようなので、 contentInsetを使っている場合は、contentInsetの分だけ広げたrectを指定してあげると良い感じになるようです。

posted by Png genki on Fri 7 Nov 2008 at 11:14

たいしたものではないですが、 iPhoneアプリ開発用に Linked ListとLRUCacheを実装したユーティリティライブラリを公開します。

http://github.com/genki/s21gutils/tree/master

本当はサードパーティフレームワークの形にしたかったんですが、 iPhoneでサポートされてないようなので、ソースとUnitTest用プロジェクトの形で公開します。

ヘッダファイルをコピーとかするのが面倒なので、 Gitでソースを管理してるプロジェクトで使う場合は、 以下のようにGit submoduleとして追加するとメンテナンスが楽かもです。

   1  % git submodule add http://github.com/genki/s21gutils/tree/master Classes/s21gutils

Public Domainです。無償・商用問わず自由に使ってください。 よろしくお願いします。

posted by Png genki on Sun 2 Nov 2008 at 07:55

ちょっとした時間計測に使っているマクロです。

   1  #define BM_START(name) NSDate *name##_start = [NSDate new]
   2  #define BM_END(name)   NSDate *name##_end = [NSDate new];\
   3    NSLog(@"%s interval: %f", #name, [name##_end timeIntervalSinceDate:name##_start]);\
   4    [name##_start release];[name##_end release]

iPhoneアプリを開発している場合、シミュレータ上の動作時間と 実機での動作時間は全く異なるので、 実際に実機で動かしてみた場合にどの程度の時間がかかっているかを 測定するのに使っています。

   1  BM_START(something);
   2  /* do work */
   3  BM_END(something);

こんな感じに使います。

posted by Png genki on Sat 1 Nov 2008 at 15:17

s21gブログをお使いの皆様へ。

s21gブログでは、サービスの改善に供するために Google Analyticsを使用していますが、 以下に該当するブロガーの皆様に、このブログのレポートページへの アクセス権を解放する事にいたしました。

  • 一ヶ月に一回程度以上記事を投稿している方(これから始めるという方でもOkです)
  • Googleアカウントのメールアドレスをご連絡いただける方

ご希望の方は、 @takiuchiか、 info{at}s21g{dot}com までご連絡ください。

よろしくお願いいたします。

posted by Png genki on Sat 1 Nov 2008 at 14:19

しばらく使ってなくて忘れそうになったのでメモ。

   1  int n = CGColorGetNumberOfComponents(color);
   2  float (*comps)[n] = (float(*)[n])CGColorGetComponents(color);

C99は良いなあ。

posted by Png genki on Fri 31 Oct 2008 at 15:45

半透明ステータスバーの透明度は多分 0.6

キーボードのアニメーション速度は0.3秒

UITextViewのマージンは8ピクセル。 現在のところ、UITextViewのマージンを(普通に)設定する方法は無いらしい。

posted by Png genki on Fri 31 Oct 2008 at 14:27

iPhoneのキーボードが出現するときには、slide up のアニメーションがかかりますが、このアニメーションの開始から完了までの時間間隔は、0.3秒のようです。消える時のアニメーションも同様のようです。

ドキュメントを調べても取得するAPIがわからなかったのですが、 UICatalogのサンプルアプリケーションの中で、定数が定義されていました。

キーボードの寸法については、NotificationのuserInfoの中の値から調べられます。

posted by Png genki on Mon 27 Oct 2008 at 15:38

iPhoneのツールバー(UIToolbar)の高さを取得する方法のメモです。

   1  - (CGFloat)
   2  heightForToolbar
   3  {
   4    UIToolbar *toolbar = [UIToolbar new];
   5    [toolbar sizeToFit];
   6    CGRect frame = toolbar.frame;
   7    [toolbar release];
   8    return frame.size.height;
   9  }

何かどこかに定数定義とかがあるかもしれないですが、 とりあえず sizeToFit すればあるべき高さに収まるようです。 UIStatusBarでも同様ですね。

posted by Png genki on Mon 27 Oct 2008 at 15:32
Contents
Objective-CでABCDEFFFのような文字列をparseする方法
Objective-Cでalias_method_chain
UIScrollView#scrollRectToVisible:animated:の挙動に関するメモ
iPhone用のユーティリティライブラリを公開します
Objective-Cでちょっとした性能測定を行うマクロ
ブロガー向けにGoogle Analyticsを解放いたします
配列へのポインタへのキャスト
iPhone内の各種要素の定数に関するメモ
iPhoneのキーボード出現アニメーションの時間
UIToolbarの高さを取得する方法のメモ
Comments
瀧内元気: MacOS版は以下にあります * [genki/ViMouse](https://githu... '23-1
dsjf: https://gist.github.com/6bf1bf2c3cbb5eb6e7a7 これ... '13-1
瀧内元気: おお、チェックしてみます。thx! '11-12
overisland: Reeder for iPhone もこの UI を実装していますね。 '11-12
瀧内元気: その情報は見たのですが、以下のサイトによると、現在はまた必要になってるっぽいんですよね。 ... '11-12
Services from s21g
twpro(ツイプロ)
Twitterプロフィールを快適検索
地価2009
土地の値段を調べてみよう
MyRestaurant
自分だけのレストラン手帳
Formula
ブログに数式を埋め込める数式コミュニティ