(メモ)iOSアプリのローカライズ
Xcodeでプロジェクトの設定からLocalizationsのセクションの[+]ボタンをクリックして言語を追加する。
iOSでステータスバーの色が写真取得すると黒に戻る件についての対処
ステータスバーの文字の色を
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
で白に変えられる。ところがUIImagePickerControllerで写真アルバムから写真を取得すると、このステータスバーの文字色が黒に戻ってしまう。調べたらstackoverflowが引っかかり、以下のワークアラウンドで回避できることがわかったのでメモ。
まずUIImagePickerControllerのデリゲートを設定し
UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self;
そして以下のデリゲートメソッドを実装する。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; }
UIImagePickerControllerはUINavigationControllerの子クラスなので、UINavigationControllerのデリゲートメソッドであるwillShowViewController
を実装しておく。ここに色を白にするコードを入れておいてデリゲートにセットしておけばOKというわけです。
以下、stackoverflowの元記事です。
ios7 - UIImagePickerController breaks status bar appearance - Stack Overflow
Codeから遷移したUIViewControllerにstoryboard上でナビゲーションバーを表示する
storyboad上のSegueで画面遷移をつないでいった場合、UINavigationControllerに含まれるViewControllerは自動でナビゲーションバーが表示されて、そこにタイトルとかバーボタンをとかを配置することができるのだけど、コードから遷移させた場合storyboad上ではどことも繋がっていないViewControllerとして表現されてしまって、実際はUINavigationControllerの中にいてナビゲーションバーとかがあるのにそれが表示されていない、ということが起こる。
そんなViewControllerの場合以下のようにしてやればstoryboard上にナビゲーションバーを表示でき、IB上でタイトルやボタンを配置することができます。
- storyboard上でViewControllerを選択する。
- Attributes inspectorで
Simulated Metrics
設定のTop Bar
をTranslucent Navigation Bar
に設定する - storyboard上にナビゲーションバーの領域があらわれる
- ナビゲーションバーの領域に
Navigation Item
をドラッグアンドドロップして配置する
以上。
UILabelを上寄せにする
よく忘れるので、メモ
- AutoLayoutでheight以外のconstraintをつける
- IBでPreferred Widthを0
- IBでLinesを0、または表示させたい最大の行数
Preferred Widthが何の設定なのか調べてない。。。
UITextFieldやUITextViewでキーボードの外をタップしたらキーボードを閉じる
すでにいろいろやり方がネット上に書かれているが、自分の中では以下の方法に落ち着いたのでメモっておく。
まず、以下の記事で紹介されているようなFirstResponderを取得するメソッドをUIViewにカテゴリとして事前に実装しておく。
#import "UIView+UIUtil.h" @implementation UIView (UIUtil) - (UIView *)findFirstResponder { if ([self isFirstResponder]) { return self; } for (UIView *subView in [self subviews]) { if ([subView isFirstResponder]) { return subView; } if ([subView findFirstResponder]) { return [subView findFirstResponder]; } } return nil; } @end
あとはViewController上で以下のように実装する。
# XXHogeViewController.m - (void)viewDidLoad { [super viewDidLoad]; // タップを検知するためのGestureRecognizer。デリゲートで処理するように設定 UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] init]; gestureRecognizer.delegate = self; gestureRecognizer.cancelsTouchesInView = NO; [self.view addGestureRecognizer:gestureRecognizer]; } // タップ時のデリゲートメソッド - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { UIView *touchedView = touch.view; UIView *firstResponderView = [self.view findFirstResponder]; if (touchedView != firstResponderView) { // 現在編集中のViewと違う場所がタップされたときのみキーボードを閉じる [self.view endEditing:YES]; } return YES; }
UIPageViewControllerをUINavigationControllerにいれたらナビゲーションバー部分に潜り込まなくなった件
iOS8でUIPageViewController
のトランジションスタイルをUIPageViewControllerTransitionStyleScroll
にしたときのみ発生する。。。マジなんなのこれ。。。しかも一度でも画面をタップすると、潜り込む(正常な)位置に移動するという。挙動が奇妙すぎてStack Overflowでも見つからないし。iOS8のバグを疑ってしまう。ヾ(`Д´)ノ"
このサンプルはXcodeのPage-Based Application
が作った雛形のプロジェクトを元に、RootViewController
をNavigationControllerにいれる、のとUIPageViewController
の初期化処理を以下のようにUIPageViewControllerTransitionStyleScroll
を指定するように変えたもの。
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
表示されるViewのframeなどを調べてみてもx=0,y=0となっていて変なところはない。それでViewの階層を見てみたらこんな感じになっている。 なんか下にズレてる。。。
_UIQueuingScrollView
というViewの位置がy=-64.0
という謎な状態になっていて、その子となるViewがその分だけ下にずれている。
しかもこれviewWillAppear:
などのフェーズでは確認できず、viewDidAppear:
まで到達して初めてこの状態になる。
というわけで以下のようなワークアラウンドを入れた。
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)) { for (UIView *v in self.pageViewController.view.subviews){ if ([v isKindOfClass:[UIScrollView class]]) { UIScrollView *scv = (UIScrollView *)v; CGPoint offset = scv.contentOffset; if (offset.y < 0) { offset.y = 0; scv.contentOffset = offset; } } } } }
iOS8の場合、UIPageViewController
のUIScrollView
をとってきてマイナス値なら0に書き換えるということをやっています。これでなんとか対応できた。
追記
コメント欄でアドバイスをいただいて「UIPageViewControllerのAdjust Scroll View Insetsのチェックを外す」で対応できることがわかりました。
xcode6でViewのconstraintに-16がついてiOS7.1でレイアウトがずれる件
xcode6でビューを重ねている状態で、子のビューを親のビューの端にぴったりあわせるるために、オートレイアウトを指定するとなぜかHorizontal Spaceに-16が設定される。しかもこれをiOS8で動かすと綺麗に端がぴったりあって表示されるのに、iOS7.1で動かすとずれて表示されるという状態に。
これがiOS8で
こっちがiOS7.1
青い領域が子のViewでconstraintが指定してある。青いViewの中にあるテキストフィールドがずれてしまっているが判るだろう。ついでに画面上にピッタリつけたはずの部分にも隙間ができてしまっている。。。
そしていつものstackoverflowから解決策を。
Constraintの指定からRelative to margin
のチェックを外す。これが付いているとConstraintの対象が親のVIewの端にならないためなんだそうだ。しかしiOS7と8でUIレンダリング(オートレイアウト周り?)の挙動が違うのは辛いものがあるなあ(T . T)。。。