イッツァハローワールド

恥さらしていこうかなとか。

(備忘録)AppStoreにリジェクトされた後に再審査出したら言い訳聞いてくれないばかりか審査までまた一週間食うよ

タイトルの通りのことを2度やって無駄に申請長引かせた私はバカ野郎この野郎。

顛末フロー

  1. アプリ申請
  2. 一週間後リジェクト通知がくる。原因はPLA 3.3.12関連
  3. 「広告ちゃんと使っているで!」って言えば申請通る可能性高いからResolution Center に直訴
  4. itunes connectでアプリを再申請
  5. それからお返事がなく、1週間後に上記と同じ理由でリジェクト
  6. 以降ループ(2回もwww)

いけなかったこと。

上記順番4で再申請すると、また列の最後尾まで並んでしまって申請待ち再スタートのになってしまうようです。
せっかくResolution Center で質問や意見しても返事が来ませんでした。のう。
久々に申請するとリジェクトされた時のこととか覚えてないよう(泣)

正解フロー

  1. アプリ申請
  2. 一週間後リジェクト通知がくる。原因はPLA 3.3.12関連
  3. 「広告ちゃんと使っているで!」って言えば申請通る可能性高いからResolution Center に直訴
  4. itunes connectでアプリを再申請ここはじっと返事を待機
  5. リリース通知くる
  6. うれしい。(*^-^*)

注意事項

ビルドし直さないといけない時は、あたりまえに上記の手順やっても時間の無駄なのでお気をつけて。

勉強メモ 2/19

今日触れた内容をダイジェストで備忘録。

指定したセレクタを認識しなくする

メソッド

-(void)doesNotRecognizeSelector:(SEL)aSelector:

// hogeを認識しないようにする
- (void)hoge {
    [self doesNotRecognizeSelector:_cmd]; //_cmdはカレントセレクタ(つまりhoge)
}

NSObjectのメソッドなんでみんなつかえる。

コードを一度だけ呼ぶ

構文

static dispatch_once_t token;
dispatch_once(&token, ^{
    // 1度だけ実行するコード
});

シングルトンオブジェクト作るときに簡単にできそう。



宇宙のスケールでものを話す宇宙人スタンプ作った

懲りずにまたLineスタンプ作った(申請中)

コンセプト

「宇宙のスケールで、ものを話す宇宙人」

わりと路線は前回と似たかんじ。↓前回
スタンプリベンジしたの巻 - イッツァハローワールド

調子がいい時、調子に乗った時に使いたいです。

こんなかんじ

f:id:hanamiju:20150217022047p:plain

頑張ったところ

前回のスタンプでは似た構図の使い回しでリジェクト食らったので多様な構図になるように努力しようとしました。

でもやっぱり、楽したい。

今回はパーツをバラして一から描くものだけを最小限に抑えました。
それでもリジェクトされたらリベンジしてもっといいのを描けばいい話なのです。

おやすみなさい。

外部フォントをiOSアプリで使用する

ゲーム作る時にシステムフォントだけでは物足りない場合が往々にしてあるとおもいます。
そんなとき外部フォントが使いたいのでやり方を備忘録。

フォントを用意する

今回使用したのはこれ。(閲覧注意)
暗黒工房 日本語フリーホラーフォント怨霊


フォントをインストールします。
f:id:hanamiju:20150214204755p:plain

フォントをプロジェクトに登録します。

f:id:hanamiju:20150214204917p:plain

ターゲットにチェック入れてないとフォントが適用されないっていうオチが待ってますので注意。

info.plistに設定を追加する

f:id:hanamiju:20150214205357p:plain

Fonts provided by applicationの項目にフォント名を入力します。

適用する

InterfaceBuilderのフォント選ぶでもいいし、コードで入れるでも良いです。

    // 怨霊フォントのサイズ17をlabelに設定
    _label.font = [UIFont fontWithName:@"onryou" size:17];

表示してみました

f:id:hanamiju:20150214205938p:plain

超怖い。

UIViewを回転させる

地味に傾けるやり方とかわかんないなーと思って調べたので備忘録

コード

    // myViewを180度回転させる
    myView.transform = CGAffineTransformRotate(myView.transform, M_PI);

サンプル:前の記事のダイアログを回転させました。

手作りモーダルダイアログ(もどき)を作る - イッツァハローワールド

まず、対象のビュー(ContentsView)をOutletにする。
f:id:hanamiju:20150211194014p:plain


つづいてコードを少しいじる。

// CustomDialogViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    _mTitleLabel.text = _title;
    _mContentsLabel.text = _contents;
    // ContentsViewを180度回転させる
    self.mContentsView.transform = CGAffineTransformRotate(self.mContentsView.transform, M_PI);
}

結果

f:id:hanamiju:20150211194154p:plain

ひっくり返ってます。

スタンプリベンジしたの巻

処女作のスタンプ一晩で作ってレビュアーから「ほとんどダメ」っていう痛烈なリジェクト食らって意気消沈したのが前回のお話。

Lineスタンプ早くもリジェクト食らったの巻 - イッツァハローワールド

2ヶ月の時を経て気分転換に製作再開しました。
以下の修正を加えて再申請しました。

  • 手でボディランゲージを試みる
  • 無駄な遊びを入れる

加えて、せっかく再申請するんだから前回よりも面白くしたいなーとワードも再考しました。
そんだら前回よりも卑屈なワードが並んだ印象に。
スタンプは性格を表すな...

こんなかんじ

f:id:hanamiju:20150213025123p:plain

表情を変えないのがコンセプトだからなー
同じこと言われなければいいなー

手作りモーダルダイアログ(もどき)を作る

僕はできるだけ標準のUIつかいたいひとなのですがゲームを作るにあたり、全画面カスタムUIを作る必要性を(勝手に)迫られたのでした。

ペーパーなプロトタイプやモックを作って見た目を吟味するまでは楽しいんだけど、いざ作るとなると結構壁がありました。
そんで手間のかかることかかること...

モーダルダイアログとか関数一発呼べばいいやつを画面から作るとか...
はじめは、どうすんだこれってかんじでした。


この記事では手作りのモーダルダイアログ(もどき)を作ったやりかたを備忘録します。

やったこと

  • ダイアログ用のビューをこしらえる
  • ダイアログ用のビューはディスプレイいっぱい描画して、下のレイヤーを触れなくしておく
  • 親ビューからの呼び出して、親ビューにダイアログ用のビューを重ねる
  • ダイアログのボタン押下でビューを消す

イメージはこんな感じ
f:id:hanamiju:20150211025725p:plain

絵に悪意はない('A`)
注目すべきはダイアログの周りも描画しているところ。
黒の透過40%で塗りつぶしています。これで重ねると陰影で立体感がでるわけ。

こんくらいならそんなに頑張らなくてもできる。

画像作る

f:id:hanamiju:20150211031152p:plain

今回冗談でWindows8テイスト作った。(8つかったことない...)

クラスをつくる

ViewController ... 親ビューのViewController
CustomDialogViewController ... ダイアログのViewController

Story Boardつくる

f:id:hanamiju:20150211033625p:plain

とりあえずこんなかんじ。
親ビュー左上のパワーボタンが押したら「終了しますか?」ってダイアログでるようにします。
ダイアログのOK,キャンセルボタン,右上xボタン押したらダイアログを閉じます。
iPhoneの電源オフはしませんw)

ここで注意すべきは、ダイアログ側のレイヤー構成です。
CustomDialogViewControllerのviewを透過してしまうと全体が透過されてしまうのでダイアログの絵も透過されてしまいます。
なので以下のことをします。

  1. CustomDialogViewControllerのviewはClear Color(alphaは1.0)にする
  2. CustomDialogViewControllerのviewの下にUIViewを敷き、こいつを透過する。(今回はDark Gray Colorのalpha0.4)
  3. ↑の上のレイヤーにダイアログのイメージ以下ボタン等をおく(↑のビューの中に置いてしまうとやっぱり透過します。)


レイヤー構成はこんなん↓(TransparentViewと他が同階層なのに注目)
f:id:hanamiju:20150211041804p:plain
(拡大縮小するとレイアウトが崩れるのでもう一個viewを挟んだりしている。)


あとはCustomDialogViewControllerを選択してStoryBoardID振っておきます。
今回は"CustomDialog"で。
f:id:hanamiju:20150211034354p:plain

Outletをつくる

ダイアログのTitleとContentsラベルは親でいじれるようにOutletにします。
xボタンもOutletにして表示非表示を切り替えられるようにしてもいいかもしれません。

コードを書く

ダイアログビューから書きます。

// CustomDialogViewController.h
#import <UIKit/UIKit.h>

@interface CustomDialogViewController : UIViewController
- (void)setContents:(NSString*)contents;
- (void)setTitle:(NSString *)title;
@end

ダイアログに表示する文字列のアクセッサメソッドを書きます。

// CustomDialogViewController.m

#import "CustomDialogViewController.h"
@interface CustomDialogViewController ()
{
    NSString* _title;
    NSString* _contents;
}
@property (strong, nonatomic) IBOutlet UIButton *mExitButton;
@property (strong, nonatomic) IBOutlet UILabel *mTitleLabel;
@property (strong, nonatomic) IBOutlet UILabel *mContentsLabel;

- (IBAction)okButtonPushed:(id)sender;
- (IBAction)cancelButtonPushed:(id)sender;
- (IBAction)exitButtonPushed:(id)sender;

@end

@implementation CustomDialogViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _mTitleLabel.text = _title;
    _mContentsLabel.text = _contents;
    // Do any additional setup after loading the view.
}

// OKボタン押下
- (IBAction)okButtonPushed:(id)sender {
    [self closeDialog];
}

// キャンセルボタン押下
- (IBAction)cancelButtonPushed:(id)sender {
    [self closeDialog];
}

// xボタン押下
- (IBAction)exitButtonPushed:(id)sender {
    [self closeDialog];
}

// 内容文字列入力
- (void)setContents:(NSString*)contents {
    _contents = contents;
}

// タイトル文字列入力
- (void)setTitle:(NSString *)title {
    _title = title;
}

// フェードアウトしながら閉じる
- (void)closeDialog
{
    // 0.3秒かけてダイアログを透過する。0.3秒たったらVC,viewを削除する。
    [UIView animateWithDuration:0.3f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         self.view.alpha = 0.0f;
                     }
                     completion:^(BOOL finished) {
                         // このへんで結果の通知とかもやればいいよ。
                         [self removeFromParentViewController];
                         [self.view removeFromSuperview];
                     }];
}
@end
// ViewController.m

#import "ViewController.h"
#import "CustomDialogViewController.h"

@interface ViewController ()
- (IBAction)powerButtonPushed:(id)sender;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (IBAction)powerButtonPushed:(id)sender
{
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    CustomDialogViewController* vc = [storyboard instantiateViewControllerWithIdentifier:@"CustomDialog"];
    
    // ダイアログの内容を書く
    [vc setTitle:@"Shutdown"];
    [vc setContents:@"電源落とすでー。"];
    
    // ダイアログを重ねる
    [self addChildViewController:vc];
    [self.view addSubview:vc.view];
    
}

setTitle, setContentsではCustomDialogViewControllerの文字列メンバ変数にダイアログに表示する内容を入力しています。
Outletに直接やろうぜってノリになりたいところですが、setTitleの時点でViewがロードされていないのでOutletたちはまだnilです。ですので、一旦メンバ(_title, _contents)に退避してダイアログクラスのViewDidLoadでラベルにテキストをいれるっていう方法をとります。

実行結果

ボタン押下前
f:id:hanamiju:20150211043657p:plain

ボタン押下後
f:id:hanamiju:20150211043726p:plain

うん。windowsっぽいな(目的が違う)

まとめ

  • そこそこ簡単なコードでつくれた。でももっと簡単な方法あると思う。教えて。
  • 上記コードだと結果の通知はNotificationとかでやんないといけない。呼び出し側毎に結果の通知を別々にしたいなら、あらかじめダイアログクラスにmessageをsetしてあげるとかの処理が必要です。
  • 見た目に満足した。