Obj cに次のような警告ビューがあるとしましょう
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:@"download"];
[alert show];
[alert release];
これで、アラートビューに2つのボタン([OK]と[ダウンロード])ができました。ダウンロードボタンのイベントハンドラーを作成する方法は?
最初に、以下のようにヘッダーファイルにUIAlertViewDelegateを追加する必要があります。
ヘッダーファイル(.h)
@interface YourViewController : UIViewController<UIAlertViewDelegate>
実装ファイル(.m)
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"title" message:@"szMsg" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:@"download"];
[alert show];
[alert release];
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
//Code for OK button
}
if (buttonIndex == 1)
{
//Code for download button
}
}
ほとんどのiOSデバイスには、ブロックをサポートするしっかりしたバージョンがあり、ボタンの押下を処理するために不器用なコールバックAPIを使用することは時代遅れです。ブロックは進むべき道です、例えば GitHubのLambda Alertクラス を参照してください:
CCAlertView *alert = [[CCAlertView alloc]
initWithTitle:@"Test Alert"
message:@"See if the thing works."];
[alert addButtonWithTitle:@"Foo" block:^{ NSLog(@"Foo"); }];
[alert addButtonWithTitle:@"Bar" block:^{ NSLog(@"Bar"); }];
[alert addButtonWithTitle:@"Cancel" block:NULL];
[alert show];
既知のUIAlertViewsを宣言します。
UIAlertView *alertLogout=[[UIAlertView alloc]initWithTitle:@"Title" message:@"Stop Application?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil];
[alertLogout show];
[alertLogout release];
デリゲートを自分に設定し、このメソッドを実装します。
-(void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if(actionSheet== alertLogout) {//alertLogout
if (buttonIndex == 0){
}else if(buttonIndex==1){
}
}else if (actionSheet==alertComment) {//alertComment
if (buttonIndex==0) {
}
}
}
StackとGuillermo Ortegaの答えは、おそらくUIAlertViewのカップルで使用するものですが、10では使用しません。私は BlocksKit を使用しています。これは、魂が示唆したLambdaのものと同じです。これも良いオプションですが、ネストされたブロックが多すぎると、そのデメリットが明らかになります(別のライブラリに依存しているという事実は別として)。
複数のものを処理する通常の方法は、ハンドラーオブジェクトを持つことです。 (_@interface MyAlertViewDelegate : NSObject <UIAlertViewDelegate> @end
_)そのオブジェクトをアラートビューのデリゲートにし、少なくともアラートビューが閉じられるまでオブジェクトが有効であることを確認します。これは確かにうまくいきますが、やり過ぎかもしれません...
以下は私が思いついたものです。 IMOのほうが簡単で、サードパーティのライブラリやUIAlertViewごとのivarは必要ありません。現在のUIAlertViewが実行するアクションを格納するための1つの追加オブジェクト(@property (nonatomic, strong) NSArray *modalActions
)
_UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:alertTitle
message:@"Blah blah"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:b1, b2, b3, nil];
// Add one selector/action per button at the proper index
self.modalActions = @[
[NSNull null], // Because indexes of UIAlertView buttons start at 1
NSStringFromSelector(@selector(actionForAlertViewButton1)),
NSStringFromSelector(@selector(actionForAlertViewButton2)),
NSStringFromSelector(@selector(actionForAlertViewButton3))];
[alertView show];
_
デリゲートメソッド:
_- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.cancelButtonIndex != buttonIndex) {
[self performModalActionAtIndex:buttonIndex];
}
}
_
実際にアクションを実行する部分:
_- (void)performModalActionAtIndex:(NSInteger)index
{
if (-1 < index && index < self.modalActions.count &&
[self.modalActions[index] isKindOfClass:[NSString class]]) {
SEL action = NSSelectorFromString(self.modalActions[index]);
NSLog(@"action: %@", self.modalActions[index]);
if ([self respondsToSelector:action]) {
// There is a situation with performSelector: in ARC.
// http://stackoverflow.com/questions/7017281/
#pragma clang diagnostic Push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self performSelector:action];
#pragma clang diagnostic pop
}
self.modalActions = nil;
}
_
_UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:title
delegate:self
cancelButtonTitle:cancelButton
destructiveButtonTitle:nil
otherButtonTitles:button1, button2, button3, nil];
// Similarly, add one action per button at the proper index
self.modalActions = @[
NSStringFromSelector(@selector(actionForActionSheetButton1)),
NSStringFromSelector(@selector(actionForActionSheetButton2)),
NSStringFromSelector(@selector(actionForActionSheetButton3))];
_
デリゲートメソッド:
_- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (actionSheet.cancelButtonIndex != buttonIndex) {
[self performModalActionAtIndex:buttonIndex];
}
}
_
これには2つの理由があります。
まず、デリゲートを同時に持つ2つのUIAlertViewを表示することはありません。 (IMOすべきではない、見栄えが悪い)。 2番目に、私の場合(ケースの90%として)、アクションのターゲットは常に同じオブジェクトです(この場合:self
)。上記の条件を満たしていない場合でも、いくつかの変更を加えてこのアプローチを使用できます。
2つ以上のUIAlerViewsまたはUIActionSheetsを同時に表示する場合(iPadで可能)で辞書を使用して、特定のUIAlertView/UIActionSheetに関連付けられたアクションの1つの配列を保存します。
アクションのターゲットがself
でない場合、ペア(ターゲットとアクション)を配列に格納する必要があります。 (UIButtonsをシミュレートするもの_addTarget:action:...
_)。
どちらの場合でも、ターゲットやUIActionSheet/UIAlertViewを格納するには、_[NSValue valueWithNonretainedObject:]
_が便利になるはずです:)
First of all you declare UIAlertViewDelegate in .h file after put below code in .m file
- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
//put button action which you want.
}
}
UIAlertViewDelegate
を実装し、デリゲートメソッドを利用する
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0) {
// Do something
}
else {
// Do something
}
}
swift:この小さなコードブロックを使用できます
let alert = UIAlertController(title: "Alert", message: "This is an alert message", preferredStyle: UIAlertControllerStyle.Alert)
let action = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {(action:UIAlertAction) in print("This is in alert block")
})
alert.addAction(action)
self.presentViewController(alert, animated: true, completion: nil)
UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"Data Saved" message:@"Choose more photos" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:Nil];
[alertView show];
[alertView release];
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(buttonIndex==0)
{
[self dismissModalViewControllerAnimated:YES];
}
}