web-dev-qa-db-ja.com

iOS 8でUIAlertControllerをカスタマイズして、UITableViewなどの標準要素を含めます

[alert setValue:someView forKey:@"accessoryView"]メソッドを使用してUIAlertViewsをカスタマイズするのに慣れています。これにより、カスタムの高さを持つUIAlertViewsのカスタマイズ可能なコンテンツが作成されます。ただし、iOS7以下でのみ動作します。 iOS8では、UIAlertControllerが引き継ぎました。これ以上カスタマイズできません。UIAlertViewの高さをカットします。

UIAlertControllerの誤用が原因で不可能なのですか、それともどうすればいいのですか? UIAlertControllerStyleAlertを使用してUIAlertController内にUITableViewを組み込みます。

THX。

17
kbjeppesen

今すぐ同じ問題に遭遇しました。 UIAlertControllerのプライベートヘッダー( https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIAlertController.h )を見て、有望なものを見つけましたプロパティ:contentViewController

また、UIAlertViewで使用されていたaccessoryViewとまったく同じであることが判明しました。違いは、UIViewではなくUIViewControllerをこのプロパティに割り当てる必要があることです。

UIViewController *v = [[UIViewController alloc] init];
v.view.backgroundColor = [UIColor redColor];

[alertController setValue:v forKey:@"contentViewController"];

そのコードは、アラートビューに赤いビューを表示します!ハッピーUIAlertControllerカスタマイズ;)

PS。これは私有財産ですが、KVCを使用することでApp Storeに問題はないはずです。

編集:

これはあまり安全ではないと不満を言う人もいます。これはパブリックAPIではないため、はい、Appleはどのリリースでも変更でき、このメソッドは失敗します。

その場合、アプリ全体がクラッシュしないようにするには、KVC呼び出しをtryブロックでラップします。プロパティが変更された場合、コントローラーはコンテンツビューを表示しませんが、クラッシュすることもありません。

@try {
    [alertController setValue:v forKey:@"contentViewController"];
}
@catch(NSException *exception) {
    NSLog(@"Failed setting content view controller: %@", exception);
}

本番環境でこの方法を使用するのは危険である可能性があり、重要なアラートには推奨しません。

35
JonasG

追加のUIを想定外の場所に詰め込もうとして時間を無駄にしないことをお勧めします。過去数年の改善に基づいて、Appleはおそらく次のiOSでカスタムビューを追加します。それまでは、ベストプラクティスを破壊することなくこの正確な状況を処理するように設計されたフレームワークをご覧ください: SDCAlertView

サイズ変更、ボタンの種類、回転などの厄介なEdgeケースのすべてを処理するなど、iOS 7,8,9のネイティブアラートを模倣するアラートをサポートします。アラート内の任意のカスタムビューをサポートします。

SDCAlertView demo gif

Yahoo YMPromptKitでこのライブラリを使用して、iOSネイティブとまったく同じように見えるカスタムプッシュ通知プロンプトを作成します。別の例を次に示します。

enter image description here

11
Adam Kaplan

UIAlertControllerのみを使用する特別な理由がない限り、必要なコントロールを追加してUIViewを簡単にカスタマイズし、モーダルで表示できると思います。

https://www.cocoacontrols.com/search?q=UIAlertview

2
CyberInfo

UIAlertControllerカテゴリを使用して1行のコードでそれを実行し、アプリケーション内の既存のアラートを置き換えることができます。 here を確認してください。

enter image description here

1
mientus