FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

UIWebViewをスクロールさせない [Xcode]

UIWebViewをスクロールさせない「小手先」の技です。

UIWebViewはヘルプの文章を書くのに便利なのでよく使ってるんですが、
画面内に収まる短い文章でも、縦にスワイプするとスクロールできてしまい
少々みっともないです。

で、スクロールさせない方法を調べたのですが、例えば UITableViewだと
 myTableView.scrollEnabled = NO;
の一行でスクロールしなくなります。
しかし UIWebViewでは、なぜかこの scrollEnabledのプロパティが無いために
この方法が使えません。


なので、userInteractionを禁止してしまいます。
myWebView.userInteractionEnabled = NO;
これによって WebViewがタッチイベントそのものを受け付けなくなるので、
必然的にスクロールもしなくなります。

ただし、WebView内のソースにリンクボタン等があっても押せなくなってしまうので、
それらがない場合にしか使えない所が「小手先」でございます。

UIColorの値をRGBやHSBで取得する、RGB - HSB変換する [Xcode]

UIColorの色の値をRGB+αやHSB+αで取得する方法と、RGB - HSB変換する方法をご紹介します。

1. RGB+αで取得


そもそも Objective-Cには getRed:green:blue:alpha: というメソッドがありまして、これでRGBαの値を取得できます。しかし、grayColorやwhiteColor等のグレースケールの色では、このメソッドがうまく働きません。
なので場合分けをして取得を行います。

CGColorGetNumberOfComponentsというメソッドで、グレースケールの色かどうかを判別できます。
グレースケールの色ではこの値が2となり、輝度(0.0が黒、1.0が白)とα値が取得できます。
グレースケール以外の色ではこの値が4となり、RGBの各値とα値が取得できます。

実際のコードは以下のようになります。
戻り値が red, green,blue,alphaの4つになるので、「参照渡し」という手法も使います。呼び出し側では引数の頭に & を付け、呼ばれた側では頭に * を付けてアクセスすることで、呼び出し側の複数の引数に値を入れることが出来ます。

- (void)getRGBA:(UIColor *)color red:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha
{
// numComponentsを取得
const int numComponents = CGColorGetNumberOfComponents(color.CGColor);
const CGFloat *components = CGColorGetComponents(color.CGColor);
// numComponents == 2 ならグレーケール RGBに同じ値と alphaを取得
if(numComponents == 2) {
*red = components[0];
*green = components[0];
*blue = components[0];
*alpha = components[1];
}
// numComponents == 4 ならRGBAを取得
else {
*red = components[0];
*green = components[1];
*blue = components[2];
*alpha = components[3];
}
}

■呼出し元
UIColor *color = [UIColor orangeColor];
CGFloat red, green ,blue, alpha;

// 参照渡しにより、red, green,blue,alphaのそれぞれに値が入る
[self getRGBA:color red:&red green:&green blue:&blue alpha:&alpha];


2. HSB+αで取得


色を「色相、彩度、明度」で表すHSBでも、getHue: saturation: brightness: alpha: というメソッドがありますが、RGBの時と同様にグレースケールでは働かないので場合分けが必要です。

- (void)getHSBA:(UIColor *)color hue:(CGFloat *)hue saturation:(CGFloat *)saturation brightness:(CGFloat *)brightness alpha:(CGFloat *)alpha
{
// numComponentsを取得
const int numComponents = CGColorGetNumberOfComponents(color.CGColor);
const CGFloat *components = CGColorGetComponents(color.CGColor);
// numComponents == 2 ならグレーケール brightnessと alphaを取得
if(numComponents == 2) {
*hue = 0.0;
*saturation = 0.0;
*brightness = components[0];
*alpha = components[1];
}
// numComponents == 4 ならHSBAを取得
else {
[color getHue:hue saturation:saturation brightness:brightness alpha:alpha];
}
}

■呼出し元
UIColor *color = [UIColor orangeColor];
CGFloat hue, saturation ,brightness, alpha;

// 参照渡しにより、hue saturation ,brightness, alphaのそれぞれに値が入る
[self getHSBA:color hue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];


3. RGB - HSB変換


上記の応用で、RGBで指定した色をHSBに変換したり、その逆もできます。

- (void)getRGBA:(UIColor *)color red:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha
{
// 上記と同じ実装...
}
- (void)getHSBA:(UIColor *)color hue:(CGFloat *)hue saturation:(CGFloat *)saturation brightness:(CGFloat *)brightness alpha:(CGFloat *)alpha
{
// 上記と同じ実装...
}

■呼出し元
// RGBで色を設定
UIColor *color = [UIColor colorWithRed:0.2 green:0.5 blue:0.8 alpha:1.0];
CGFloat hue, saturation ,brightness, alpha;
// HSBを取得
[self getHSBA:color hue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];

// HSBで色を設定
color = [UIColor colorWithHue:0.6 saturation:0.2 brightness:0.6 alpha:1.0];
CGFloat red, green ,blue;
// RGBを取得
[self getRGBA:color red:&red green:&green blue:&blue alpha:&alpha];

UITableViewのスクロール中にNSTimerが停まってしまう [Xcode]

開発中のアプリで、UITableViewのテーブルの隣に NSTimerを使って時間を表示しているのですが、テーブルをスクロールすると時間表示が止まってしまうことに気づきました。
スクロールしようとテーブルをタップした瞬間から指を離すまで、時間表示がピッタリ止まってしまいます。

これはテーブルのスクロールと NSTimerが両立されないため、スクロール中は NSTimerが更新されないのが原因です。UITableViewの他に UIScrollViewでも同様だそうです。



これを回避するには、NSRunloopというのを使って NSTimerをオマジナイします。
    // NSTimer設定
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
target:selfselector:@selector(myTimerAction:) userInfo:nil repeats:YES];

// NSRunLoopのオマジナイ
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

NSRunloopが何者なのか、いまいちわかってないのですが(オイ)、これで無事スクロール中も時間表示ができるようになりました。

Xcodeの配列でハマる [Xcode]

今開発中のボードゲームのアプリで、ハマったことがありました。

アプリでは5×5のボードを表示し、画面タップでボード内のコマの数値が変わります。
またUNDO機能のためのバッファも設けました。
コード上ではボードとUNDOバッファのそれぞれに配列を用意しました。

 int board[25];    /* ボードの数値を保持 */
 int undoBuf[25];  /* UNDO用のバッファ */

そしてアプリを動作させてみると、なぜかたまにundoBufの一部が
変な値に書き変わってしまう現象が起きました。

コード上でundoBufの書き込みをしている部分をいくら調べても、おかしな所はありません。
どうやら画面をタップした際に書き変わってるようなんですが。
あれこれ悩むこと2日、ついに原因が。

実は画面タップ位置からコマ番号を割り出すルーチンに記述漏れがあり、
ボード外をタップすると「コマ番号 = 37」とかが取得されてしまっていました。
そしてその値を使って範囲外の board[37]を書き換えようとして、
メモリ上で boardの隣にある undoBufを書き換えてしまっていたのでした。

いやー、こういうのって Xcodeの警告出ないんですね。

試しにこのコードだとエラーが出ますが、
 int board[25];
 board[50] = 0;

こちらは出ません。ぬぬ。
 int board[25];
 int i = 50;
 board[i] = 0;

これは要注意ですね。
でも原因が分かってよかったです。

info.plistからプロジェクトのバージョン番号を取得する [Xcode]

プロジェクトにはバージョン番号(とビルド番号)を設定しますが、それをプログラム側で取得したいときがあります。最も多いのが、設定画面等でバージョンを表示するときだと思います。

Xcodeで PROJECT > TARGETS を見ると、Version(赤い線)とBuild(オレンジの線)の入力欄があります。ここにバージョン番号とビルド番号を入力します。
試しにそれぞれを 1.2 と 1.20000 にしてみました。



ここで入力した内容は、Info.plistに設定されます。Info.plist内では、
 "Bundle versions string, short" が バージョン番号
 "Bundle version" が ビルド番号
になります。なんだか名前と内容が一致してない気がしますが、しょうがありません。



そして、プログラムコード側でバージョン番号を取得するには、以下のコードを書けばOKです。
   NSString *version
= [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];

NSString *build
= [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];

それぞれ1行で取得出来るので便利ですね。
Appご紹介
K app designのAppをご紹介します

ねこわけ

画面中央の猫を次々に仕分けるゲームです。

あまり計算機

あまりを計算できる割算専用の計算機です。

6オクターブ ピアノ

6オクターブ鍵盤のピアノアプリです。iPad専用。

Dynamic Drum

様々な演奏法が楽しめるドラム演奏アプリです。

クイズボタン

早押しクイズのサポートをするアプリです。

クイズボタン Pro

クイズボタンに点数表示機能が付きました。

クイズボタン HD

クイズボタンのiPad専用版。回答者ボタンが8つに増量。

ベロシティ ピアノ

タップの強弱で音量が変わるピアノアプリです。

TIMERx4

4つのキッチンタイマーを同時に動作できるアプリです。

アナデジClock

アナログとデジタルが融合した時計です。
検索フォーム
最新記事
最新コメント
カテゴリ
人気ページ
月別アーカイブ
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。