繰り返し学習時間を記録するiOSアプリ「StudyLap」をリリースしました

問題集などで繰り返し学習する際、問題を解いた時間を記録し並べて表示できる
iOSアプリ「StudyLap」をリリースしました。


基本的にはラップ付きタイマーと同じですが、1回目、2回目・・・と繰り返し
問題を解いた後、問題ごとに解いた時間の比較しやすいように横に並べて表示します。


・画面



また、問題ごとにアラーム設定ができるので、
例えば1問3分みたいに目標解答時間を設定して、時間内に解けなかったら
アラームを鳴らすという使い方ができます。


おまけで記録時間のメール送信機能を付けました。


デフォルトではミリ秒は表示されませんが、
iOSの設定 -> StudyLap -> ミリ秒を表示
でオンオフの切り替えができます。


ぜひ、ご活用ください。


OS移行時にカスペルスキーのアクティベーションでトラブル → サポセンで解決

先日、興味本位でWindows8 Pro 64bitを使ってみたくて、
現行のWindow7 Home 32bitから変えてみました。
そこで、使用中の「カスペルスキー 2013 マルチプラットフォーム セキュリティ」
(3年3台使えるやつ)のアクティベーションを解除してWindows8をインストール。
インストール完了後にカスペルスキーをインストール&アクティベーションしようとしたら
「すでにアクティベーション数を超えています」みたいなエラーが表示されて弾かれました。


いや、3台もアクティベーションしてないし、さっき1個解除したし…。
と、心の中で叫んでも一向に解決しないので、マイカスペルスキー
テクニカルサポートセンターにフォームで問い合わせしました。(要アカウント作成)


実はカスペルスキー製品のサポートページは、カスペルスキーストアにも似たようなページがあって迷いました。
ストア側のページではどうも対応出来なさそうだったので、マイカスペルスキーで以下の手順で進めました。

  1. アカウントを作成
  2. ログイン
  3. 画面左のメニューから「アクティベーションコードを管理」を選択
  4. アクティベーションコードを追加
  5. 画面左のメニューから「お問い合わせの送信」
  6. お問い合わせ送信タブを選択して、お問い合わせ作成ボタンをクリック


大体、中1日くらいで返信が来ました。
結局、直接の原因は分かりませんでしたが、何かのタイミングでアクティベーションが解除できなくなる不具合があるそうです。
こちらではどうしようも出来ないので、新しいアクティベーションコードを発行していただきました。
旧コードは使えなくなるので再度設定が必要ですが。
サポートの対応も好感が持てたので、不満は残らず無事解決出来て良かったです。


Windows8は結局使いこなせなくてWindows7に戻してみたり、
無駄な作業が増えまくった年末でした。
うーん、OSのインストールは鬼門か…。

任意にタブバー内の指定のタブに移動する方法

ボタンタップ時などの任意の処理でタブバーの表示タブを切り替える方法です。

TabBarControllerに対して、以下のように複数のTabBarが設定されている状態とします。



TabBar内のViewControllerからUITabBarControllerにアクセスできるので、
UITabBarControllerの選択状態を設定できます。


まずはインデックスを設定する方法。
TabBarのインデックスは左のタブから0, 1, 2...と設定されているので、
一番左を表示したい場合は0を設定します。
上のイメージだとCurrentタブ切り替わります。


・選択インデックスを設定して表示切替

//0 = 一番左のTabBarを設定
self.tabBarController.selectedIndex = 0;


他にも、あまり使う頻度はないかもしれませんが、
子ViewControllerでNavigationControllerのrightBarButtonItemの処理を実装している場合、
実装されている子ViewControllerのタブに切り替えるには以下のようにします。


・選択ViewControllerを設定して表示切替

//実装されているViewControllerを設定(ViewControllerのViewを表示)
self.tabBarController.selectedViewController = self;


処理がListタブのViewControllerに実装されていれば、他のタブを表示していても
Listタブに切り替わります。

UITableViewCellの右側にイメージを表示する方法

以前、二郎系ではラーメンの画像をリストの左側に表示していました。
お店が増えるに従って表示される画像の比率が低くなり、見栄えも悪くなってしまったので、
店名を左に詰めて画像があれば右側に表示するように修正しました。
その時の対応です。


UITableViewCellはaccessoryViewというUIViewを持っています。
「>」なんかが表示される部分ですね。
完結に書くと、そこにごっそりUIImageViewを設定します。

//TableViewCellを設定
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	//iOS5.1ではエラーになるので、以前のメソッドに戻す
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
	if (!cell) {
		cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
	}
	[self configureCell:cell atIndexPath:indexPath];
        return cell;
}

- (void)configureCell:(ImageTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
        UIImage *image = [UIImage imageNamed:@"star.png"];
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
        //画像が大きい場合にはみ出さないようにViewの大きさを固定化
        imageView.frame = CGRectMake(0, 0, 30, 30);
        //アクセサリービューにイメージを設定
        cell.accessoryView = imageView;
}


結果


実際のコードは、サーバーから非同期で画像データを取得して設定しています。

Bitbucketのコミットログからissueにリンクさせる

昔、影舞やらtracやらを利用していた時に、コミットログ(コメント)から
直接チケットに飛べたのを思い出し、試しにやってみたらできました。


XcodeメニューバーのFile → Source Control → Commitでコミット
XcodeメニューバーのFile → Source Control → Pushでbitbucketのリモートリポジトリにプッシュします。


BiubucketではIssue番号は「#1」形式になっているので、
Xcodeでコミットコメントを「#1対応ほげほげ」としてコミットしておくと、
BitbucketのCommitsで表示されるコミットコメントの「#1」に該当のIssueへのリンクが付きます。


2012-12-27追記
他にも

  • FIX:issueステータスをResolveに更新
  • REOPEN:CLOSEしていたissueのステータスを再度OPENに更新
  • REF:issueのコメントに追記(ステータスは変わらない)

小文字でfixやreopenでもいけるみたいです。
issueに反映すると下のようになります。





2013-01-01追記
備忘録。
Xcodeでコミットログに「FIXED[タブ]#10」みたいに、半角スペースの代わりにタブを使うとFIXEDステータスが効かない模様。
タブは使わない方が良さそう。

UIImageViewに値を持たせる

先日リリースした「東京23区タッチ」では、
色のついている区をタップすると区名を吹き出しで表示しています。


その実装方法は、UIImageViewにデータを持たせ
タップ時にそのデータ(区名)を取得して実現しています。


プロパティを持ったUIImageViewのサブクラスを作成する方法が簡単だと思いますが、
今回は変態的にUIImageViewのカテゴリーにNSObjectを紐付けてみました。


まずサブクラスの方法

・DataImageView.h

#import <UIKit/UIKit.h>

@interface DataImageView : UIImageView

//名前
@property (nonatomic)NSString *name;

@end

※DataImageView.mは、XcodeでUIImageViewサブクラスで作成後変更なし。


続いてUIImageViewとNSObjectを紐付ける方法

・UIImageView+data.h

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

@interface UIImageView (data)

//UIImageViewにObjectを紐付けて疑似getter/setter化
- (void)setName:(NSString *)name;
- (NSString *)name;
@end

#import Objective-Cランタイムを定義。


・UIImageView+data.m

#import "UIImageView+data.h"

@implementation UIImageView (obj)

//UIImageViewにObjectを紐付けて疑似getter/setter化
- (void)setName:(NSString *)name {
        //「name」というプロパティ名でデータを紐付け
	objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN);
}

- (NSString *)name {
        //「name」で紐付けられたデータを返却
	return objc_getAssociatedObject(self, @"name");
}
@end

objc_setAssociatedObject()の第2引数に紐付け名、第3引数に値を指定して保持します。
objc_getAssociatedObject()の第2引数で紐付け名をしてして保持した値を取得します。


これで、[imageView setName]やimageView.name = 〜みたいな形で値を設定したり、
imageView.nameで値を取得できるようになります。


1つのアルバム=プレイリストの時、アーティストが別でもアートワークを1つにまとめる方法

iTunesでは、アルバム毎にプレイリストを作成すると、
プレイリストの中に複数のアートワークが表示される時があります。
iTunes11になると、表示方法をグリッドにすると下のように曲がアートワーク毎に表示されたりして
かなり不便です。




アートワークを1つにまとめるには、曲の情報にコンピレーションの一部と設定する必要があります。
設定されていないと、アートワークはアルバム単位ではなくアルバムアーティスト毎に表示されるようです。
もしアルバムアーティストが未設定の場合は、代わりにアーティスト毎に設定されます。
例えばゲド戦記のサントラの場合、テルーの唄は手嶌さんをアーティストとして曲情報を設定し、
他の曲を寺島さんを設定していたため2つアートワークが表示されてました。



アルバム内のすべての曲を選択し、オプションでコンピレーションの一部に「はい」を設定することで、
アートワークを1つにまとめることができました。