我有一個函數,顯示一個UIAlertView與YES/NO按鈕,它只用於函數的範圍內,所以我不想實現一個委託來捕捉用戶反饋。有沒有委託處理UIAlertView結果的簡單方法?
有沒有辦法知道哪個按鈕用戶點擊不落實UIAlertViewDelegate,是這樣的:
[alert show];
if([alert indexOfClickedButton] == indexOfYes)
{
....
}
或lambda表達式,如動畫
我有一個函數,顯示一個UIAlertView與YES/NO按鈕,它只用於函數的範圍內,所以我不想實現一個委託來捕捉用戶反饋。有沒有委託處理UIAlertView結果的簡單方法?
有沒有辦法知道哪個按鈕用戶點擊不落實UIAlertViewDelegate,是這樣的:
[alert show];
if([alert indexOfClickedButton] == indexOfYes)
{
....
}
或lambda表達式,如動畫
沒有辦法完全避免委託,但是您可以沿着這些方向創建一個包裝效果:
@interface MyAlertViewDelegate : NSObject<UIAlertViewDelegate>
typedef void (^AlertViewCompletionBlock)(NSInteger buttonIndex);
@property (strong,nonatomic) AlertViewCompletionBlock callback;
+ (void)showAlertView:(UIAlertView *)alertView withCallback:(AlertViewCompletionBlock)callback;
@end
@implementation MyAlertViewDelegate
@synthesize callback;
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
callback(buttonIndex);
}
+ (void)showAlertView:(UIAlertView *)alertView
withCallback:(AlertViewCompletionBlock)callback {
__block MyAlertViewDelegate *delegate = [[MyAlertViewDelegate alloc] init];
alertView.delegate = delegate;
delegate.callback = ^(NSInteger buttonIndex) {
callback(buttonIndex);
alertView.delegate = nil;
delegate = nil;
};
[alertView show];
}
@end
(假設ARC,如果你不使用它改變delegate = nil
至[delegate release]
)
用法是這樣的:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm" message:@"Yes or No?" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes",@"No", nil];
[MyAlertViewDelegate showAlertView:alert withCallback:^(NSInteger buttonIndex) {
// code to take action depending on the value of buttonIndex
}];
謝謝,您的解決方案的工作原理。 – jAckOdE 2012-03-13 01:27:41
我在執行'delegate = nil'的行上收到編譯器警告:在此塊中強烈地捕獲委託很可能導致保留週期。這在iOS 5.1 ARC下。 – 2012-05-20 13:25:42
'delegate = nil'是必須的,因爲'alertView.delegate'是一個非保留屬性,我們需要保持對象爲「委託」,直到警報視圖爲按鈕回調完成。這個警告(誤報)可以用'#pragma clang diagnostic push'和'#pragma clang diagnostic ignored'-Warc-retain-cycles''忽略,並在該行後面加上'#pragma clang diagnostic pop'。 – AndiDog 2013-09-23 11:24:51
這很容易。假設你有一個警告,這樣的事情:
//Alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm" message:@"Yes or No?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes",@"No", nil];
[alert show];
你將需要添加這個方法:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
一種可能實現這個方法的是這樣的:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
//Checks For Approval
if (buttonIndex == 1) {
//do something because they selected button one, yes
} else {
//do nothing because they selected no
}
}
你可以做哪些可以隱藏這一點使用自定義視圖並顯示爲避免動作片
UIView *AlertVw=[UIView alloc]initWithFrame:CGRect(x,y,w,h)]];
UIButton *SaveButton=[UIButton alloc]initWithFrame:CGRect(x,y,w,h)]];
[CustomButton setTitle:@"Ok" forState:UIControlStateNormal];
[SaveButton addTarget:self action:@selector(SaveClicked) forControlEvents:UIControlEventTouchUpInside];
UIButton *CancelButton=[UIButton alloc]initWithFrame:CGRect(x,y,w,h)]];
[CustomButton setTitle:@"Cancel" forState:UIControlStateNormal];
[CancelButton addTarget:self action:@selector(CancelClicked) forControlEvents:UIControlEventTouchUpInside];
[AlertVw addSubview:SaveButton];
[AlertVw addSubview:CancelButton];
[self.view addSubview:AlertVw];
-(void)SaveButton
{
//Code to apply on Save clicked
[AlertVw removeFromSuperView]; //Also you can use AlertView.hidden=YES;
}
-(void)CancelButton
{
//Code to apply on cancel clicked
[AlertVw removeFromSuperView]; //Also you can use AlertView.hidden=YES;
}
無需派生類。使用Block,可以很容易地獲得用戶選擇的按鈕索引。
typedef void(^AlertViewCallBackBlock)(NSInteger selectedIndex);
@interface ABC()
@property (nonatomic, copy) AlertViewCallBackBlock alertViewBlock;
@end
@implementation
- (void)showAlert {
self.alertViewBlock = ^(NSInteger selectedIndex) {
if (selectedIndex == 1) {
}
};
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Confirm" message:@"Yes or No?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Yes",@"No", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
self.alertViewBlock(buttonIndex);
}
@end
我寫了一個博客張貼有關如何(以及爲何)加擋回調來提醒觀點,動作片和動畫:
http://blog.innovattic.com/uikitblocks/
如果你只是想這樣一個工作實現你可以從GitHub下載源文件:
https://github.com/Innovattic/UIKit-Blocks
用法:
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"My easy alert"
message:@"Would you like to perform some kind of action?"
cancelButtonTitle:@"No"
otherButtonTitles:@"Yes", nil];
[alert setHandler:^(UIAlertView* alert, NSInteger buttonIndex) {
NSLog(@"Perform some kind of action");
} forButtonAtIndex:[alert firstOtherButtonIndex]];
[alert show];
很久以前找到答案,但仍然是很好的作品 – jAckOdE 2014-02-27 02:59:52
謝謝Arkku。這是Swift版本。
https://github.com/exchangegroup/alert-view-with-callback-swift
let alertView = UIAlertView(...)
AlertViewWithCallback().show(alertView) { alertView, buttonIndex in
println("You closed alert by tapping button #\(buttonIndex)")
}
UIAlertView
從iOS版8.0中,建議更好的解決方案將使用UIAlertController
:
let alert = UIAlertController(title: "message", message: "Title", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "YES", style: .Default, handler: { (action) -> Void in
// Action for YES
}))
alert.addAction(UIAlertAction(title: "NO", style: .Default, handler: { (action) -> Void in
// Action for NO
}))
self.view.window!.rootViewController!.presentViewController(alert, animated: true, completion: nil)
UIAlertView中沒有代表團只有一個,ü創建一個自定義UIAlertView中的方式。 – ios 2012-03-12 05:03:46
這裏是一個實現基於塊的UIAlertview的網站(以及其他內容):http://blog.mugunthkumar.com/coding/ios-code-block-based-uialertview-and-uiactionsheet/ – lnafziger 2012-03-12 05:18:13
UIAlertView * aletView = [[UIAlertView alloc] initWithTitle:@「Any Title」message:@「Hiii」delegate:self cancelButtonTitle:@「Cancel」otherButtonTitles:nil,nil]; [alert show];如果需要, 不使用任何委託。 – 2012-03-12 09:46:51