タップ認識
1、「閉じる」ボタンを置いたUIViewがあります。
2、このViewを「表示」ボタンを置いたViewControllerがあります。
3、UIViewをViewControllerにaddして、setHidden:YESにしておきます。
4、「表示」ボタンを押すとViewをsetHidden:NOにします。
5、表示されたViewにある「閉じる」ボタンを押すと、setHidden:YESにして隠します。
ボタン以外のところに触れてもsetHidden:YESにしたいです。
6、というわけでUIGestureRecognizerをUIviewに追加します。これでタップイベントが拾えます。
7、すると、タップイベントは拾えるようになったのですが、ボタンが押せなくなってしまいました...orz
こんなときの解決法は以下。
--------------------------------------------------------------------------------
UIGestureRecognizerをUIViewに組みこむと、ほかのタッチイベントが無効になります。
それを避けるには、UIGestureRecognizerのプロパティ「cancelsTouchesInView」をNOにします。
--------------------------------------------------------------------------------
今回はGestureRecognizerをxibで付加してみたので、
その場合、xib画面でGestureRecognizerを選択して、
GestureRecognizerの設定(画面右側のやつです)の
「Events: Canceled in View」のチェックを外すと
このプロパティ指定ができます。
※例えばこのViewの下にScrollViewとかはさんじゃうとダメぽ(ω・`))キョロ(( ´・ω)
Scrollviewはタッチイベントを奪ってしまうので..
このへんはまだまだ勉強が必要!
いろんな学び①〜数字まわり編!〜
最近いろいろなことを知ることがあったので
まとめれるうちにまとめとかないと忘れちゃいそうなのでメモ!
-------------------------------------------------------------------------------------
◎NSNumber型のメリット
今回CoreDataを使ったプログラムを作っていて
managedObjectに使うことになりました。
でもNSNumber型って扱いにくくて嫌いだったので、
なんでもかんでもNSString型でいーや、どーせJSONでやりとりするし!
て思っていたのです。
が、このNSNumber型、メリットもあるらしい。
1、コンパクトサイズ
なにやら、ローカルに保存するときに、
String型よりもInteger32(32bit?)であるNSNumberで保存すると
容量がちっさくて済むとのこと。
2、数字の役割もちゃんとある
NSString型で足し算ってできないですよね。
(やるとしたら一回intValueして〜とか)
これがNSNumber型だと出来ちゃうとかいう噂。
※あくまでも私はまだ使ったことない。
-------------------------------------------------------------------------------------
◎Let's変換
【NSString→NSNumber】
1、まずはint型に変換しましょう(忘れがち)
2、そのintをNSNumberに変換するだけ あら簡単!
(例)NSString* str = @"123";
NSNumber* number = [NSNumber numberWithInt: [str intValue]];
とかでOKね。
これをさらに簡略化できるそうな!!
NSNumber* number = @( [str intValue] ); ←これ @( )!!
では逆はというと。
【NSNumber→NSString】
NSString* str = [@(123) stringValue];
これでできるそうな。
(何も知らずこれだけ見たらなんじゃこれって感じの世界やなーと改めて思ったわ。)
-------------------------------------------------------------------------------------
まだまだメモりたいことたくさん!では!
再びiTunesSearchAPIで、AppStoreからアプリのscreenshotを取得する!!
前回のアプリではiTunesから楽曲情報を取得してたのですが、
このAPIのベースは先輩が作ってくれたものだったので、
データを取りに行く肝心な部分はノータッチでした。\( ^ヮ゜)>
で、今回のアプリでも
AppStoreからアプリの情報を取りに行って、
スクリーンショットの画像を表示させたい!
というマストな山が!
まずはGoogle先生に聞いてみました。
「スクリーンショット AppStore 取得 JSON」
なんか登録の方法やら指定のサイズやらは出てくるけど
取得の方法がヒットせず。
英語でも「get screenshot appstore how(howとか必死感うける)」とか入れても
同じような結果..。
むむむ。
前回のアプリでは、iTunesから楽曲情報を取得する際に、
という2つのデータベースを利用していたのですね。
で、とりあえずiTunes RSS(http://itunes.apple.com/jp/rss/generator/)
で条件指定して検索してみたものの、
JSON叩いて中身を見ても"screenshot"らしき値が無いのですよ(ω・`)
iconの画像らしきものはあるのに。
で、サーバ側の先輩に聞いてみると、
「APIはみた?」と言われ、
公式サイト(http://bit.ly/bGaJt4)見ても意味わからんよね、あれ!
ってことでけっこう流し読みしかしてなかったんやけど、←
よーく読むと、下のほうに
●Search Examples
●Lookup Examples
ていうのがありますね?
これ結構ポイントだったようで、どうやら検索の方法は2種類あるらしい。
http://www.wakatta-blog.com/itune_api.html[参考]
つまり、単語で検索するかidで検索するかってことみたい。
idがわかっている場合はlookup方式で検索すると
早くて情報量もいっぺんにとれて便利みたいです!
というわけで道はなんとなく開けた。
つまり前回の楽曲検索ではSearch方式で検索してたけど、
今回のやつではLookup方式を使ったほうが良さげだな。
(しかもLookup方式のほうが簡単そうだしよかった)
さてさてLookup Exampleの中に
●Look up Yelp Software application by iTunes ID:
https://itunes.apple.com/lookup?id=284910350
ていう項目があって、これを叩くとこのアプリにまつわる情報がだーっと見れます。
ほほー、つまりこの284910350っていうのがアプリidなわけだな。
ていうことで、自社でリリースしてるアプリidをiTunesConnectから検索して、
そのidをid=のあとに入れて叩くと...
検索結果:0 ...?
えーーーーーーー?(°□°)なんで?
iTunes上にはあるのに。
で他のアプリidも入れてみたところ、
出るやつと出ないやつがある。
登録した順番(古いやつは出ない)とかか?って思ったけど
そんなんやったらそもそもおかしいし(笑)、
再びGoogle先生にきいてみたら、
こちらhttp://www.antun.net/tips/api/itunes.htmlにありました。
真ん中あたり、
公式ドキュメントには明示されていませんが、lookup は search と 同じ引数指定ができるようで、逆に言えば指定をしないと 米国版の情報を取りに行ってしまいます。 例えば、太鼓の達人 の情報を取ろうとして、 http://itunes.apple.com/lookup?id=366956158 と指定しても国内でしか提供されていないこのアプリの情報は取れません。 そのため、 http://itunes.apple.com/lookup?country=JP&id=366956158 と引数 country を指定すれば 情報が取れるようになります。
なるほど!
というわけで、「ありません」って言われちゃったアプリに関しては、
countryを指定したらとれるようになるんですね。
これでスクショがゲットできるはず!
さーやってみよー!
カスタムボタンの落とし穴
最近ちょっとずつカスタムクラスの作成に慣れてきましたヽ(´ω)ノ
はじめは、カスタムクラスって何..こわい..(gkbr)
って思ってたけど、
要は「拡張機能(オリジナル機能)をつけたいなあヽ(´ω)ノ」
ってだけなんで、
そんなにわちゃわちゃいちから自分で作成しなくても
ちょろっとのメソッドを書き足すだけで成り立つもんなんだなあと
最近は実感しております。
で、今日はUIButtonを継承したカスタムボタンを作ってハマったのでメモ。
構成としては、
ViewController
∟カスタムView
∟カスタムButton(そいつのimageにアイコン画像をセットする)
てことがやりたかった。
カスタムボタン自体はカスタムViewにaddしていたので
今回はViewの中でボタンの呼び出しを行ったけど、
別にViewControllerの中で呼び出すとしてもやり方は一緒ね。
◇カスタムボタン(呼び出される側)のメソッド
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//初期化
_imageStore = [[ImageStorealloc]initWithDelegate:self];
self = [UIButtonbuttonWithType:UIButtonTypeCustom];
}
returnself;
}
//アイコンセット
-(void)loadIconImage:(NSString*)url
{
[_imageStore getImage:url];
}
#pragma mark -ImageStore Delegate
- (void)imageStoreDidGetNewImage:(ImageStore*)sender url:(NSString*)url
{
UIImage* imagePre = [sender getImage:url];
//ここでRetina対応の64x64px画像に成形
UIGraphicsBeginImageContextWithOptions(CGSizeMake(64, 64), NO, 0.0);
[imagePre drawInRect:CGRectMake(0, 0, 64, 64)];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[selfsetImage:image forState:UIControlStateNormal];
}
はい。これがカスタムボタンに書いた全メソッドです。
ここですでにミスったことに気づいた方はさすがです。
_imageStoreっていうのは非同期でURLから画像を生成してくれるライブラリです。
成功するとdelegateくんがdidGetNewImageメソッドをcallBackしてくれるので、
そこで自分自身のimageに生成したアイコンをセットしています。
◇カスタムView(呼び出す側)
-(void)createIcons
{
//NSLog(@"ロード self.urlsの中身%@",self.urls);
if (0 <[self.urls count]) {
for (int i = 0; i < [self.urls count]; i++) {
IconButton* btn = [[IconButton alloc]initWithFrame:CGRectMake(10+i*74, (self.frame.size.height-64)/2, 64, 64)];
NSString* url = [self.urls objectAtIndex:i];
[btn loadIconImage:url];//画像ロードさせる
btn.tag = i;//タグ付け
[btn addTarget:selfaction:@selector(selectItem:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
[btn release];
}
}
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//初期化
_imageStore = [[ImageStore alloc]initWithDelegate:self];
//self = [UIButton buttonWithType:UIButtonTypeCustom];
}
return self;
}
NSLogを簡単に消しましょ!(マクロ定義)
.pch ファイルに以下のマクロを定義します。
#if DEBUG
#if !defined(NSLog)
#define NSLog( m, args... ) NSLog( m, ##args )
#endif
#else
#if !defined(NSLog)
#define NSLog( m, args... )
#endif
#endif
ログを出したくないときは
Build Settings
> PROJECT
> Apple LLVM compiler 4.2 -Preprocessing
> Preprocessor Macros
の値を、DEBUG=0 にします。
これでリリース版のものはデフォルトで0にしておくと
ログを消せて安心\(^o^)/
***
上のやつはちなみに
#ifdef ではなくて
#ifを使っているけど、
ifdef文は開発時に使うとかなり便利!
「テスト中だけ仮でこの値入れておきたいなー」とか
「テスト中だけこのメソッドよびたいなー」とか
そういうときに
#ifdef DEBUG(=デバッグ版だったら)
ほにゃらら
#endif
と書くと、DEBUG版だけそこを通ってくれます。
逆に
本番では絶対こっち通ってほしいなーとかっていうときは
#ifndef DEBUG(=デバッグ版じゃなければ)
ほにゃらら
#endif
とかって使ったりします。
でも基本はリリース版を前提に、
#ifdef DEBUG で使うことの方が多い。
libxml2をXcodeに組み込むとき
BuildPhase から
libxml2.dylibを追加したにも関わらず、エラーが消えない!
というときは
BuileSetting > Search Path > Header Search Pathに
${SDKROOT}/usr/include/libxml2
を書かないとエラーが消えませんのでご注意。
NavigationBarの戻るボタン
●ボタン自体表示させたくないとき(表示させたくないViewController内で)
[self.navigationItem setHidesBackButton:YES];
●ボタンの 中の文字を変更させたいとき(変更したい1こ前のViewontroller内で)
UIBarButtonItem *backItem = [[UIBarButtonItemalloc] init];
backItem.title = @"戻る";
self.navigationItem.backButtonItem = backItem;
[backItem release];
UIViewController *vc = [[UIViewControlleralloc] init];
[self.navigationControllerpushViewController:vc animated:YES];
[vc release];