Ios 带有块回调的自定义UIAlertView
MyAlertView(UIAlertView的子类)具有以下方法:Ios 带有块回调的自定义UIAlertView,ios,block,uialertview,objective-c-blocks,Ios,Block,Uialertview,Objective C Blocks,MyAlertView(UIAlertView的子类)具有以下方法: - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (self.clickedButtonAtIndexBlock != NULL) self.clickedButtonAtIndexBlock(buttonIndex); } 我的问题是在创建警报视图时如何定义回调?显然
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (self.clickedButtonAtIndexBlock != NULL)
self.clickedButtonAtIndexBlock(buttonIndex);
}
我的问题是在创建警报视图时如何定义回调?显然这是错误的:
alert.clickedButtonAtIndexBlock = ^{
NSLog(@"clicked: %d", buttonIndex);
}
尝试这样做(我还没有测试过):
尝试这样做(我还没有测试过): 试试这个 假设您创建了一个名为MyCustomAlert的类,并将其声明为此变量
MyCustomAlert *myCustomAlert = [[MyCustomAlent alloc] init];
您可以将其放在头文件中
- (void)setCompletion:(void (^)(int selectedButtonIndex))completion;
你可以把它放在你的实现文件中
typedef void (^IntBlock)(int intBlock);
IntBlock _completion;
- (void)setCompletion:(void (^)(int selectedButtonIndex))completion{
_completion = completion;
}
现在在您声明“myCustomAlert”的项目中。如果你输入
[myCustomAlert setCompletion: // And select the autocomplete item
你最终会得到这个
[myCustomAlert setCompletion:<#^(int intBlock)completion#>]
当您想在自定义类中触发_completion块时,您可以在代码中的某个地方调用它,如下所示
- (void) callCompletionWithButtonIndex:(int) index{
if (_completion != nil) _completion(index);
}
希望这能消除并发症。试试这个
假设您创建了一个名为MyCustomAlert的类,并将其声明为此变量
MyCustomAlert *myCustomAlert = [[MyCustomAlent alloc] init];
您可以将其放在头文件中
- (void)setCompletion:(void (^)(int selectedButtonIndex))completion;
你可以把它放在你的实现文件中
typedef void (^IntBlock)(int intBlock);
IntBlock _completion;
- (void)setCompletion:(void (^)(int selectedButtonIndex))completion{
_completion = completion;
}
现在在您声明“myCustomAlert”的项目中。如果你输入
[myCustomAlert setCompletion: // And select the autocomplete item
你最终会得到这个
[myCustomAlert setCompletion:<#^(int intBlock)completion#>]
当您想在自定义类中触发_completion块时,您可以在代码中的某个地方调用它,如下所示
- (void) callCompletionWithButtonIndex:(int) index{
if (_completion != nil) _completion(index);
}
希望这能解决这个复杂问题。我编写了一个简单的类LMSVBlocks,它可以在一行中轻松显示警报和获取块回调。希望您会发现它在这方面很有用 概念:要使UIAlertView块兼容,您需要另一个类(如LMSVBlockAlert)来处理委托方法,并且当UIAlertView委托将发出回调时,LMSVBlockAlert类可以在块中发送回调 代码: (LMSVBlockAlert.m) 在一个数组中维护LMSVBlockAlert的所有实例,以便它们具有强引用
static NSMutableArray *_LMSVblockHandlersArray = nil;
将块处理程序保持在LMSVBlockAlert中
@interface LMSVBlockAlert() <UIAlertViewDelegate>
@property (nonatomic, copy) void (^cancelCompletionBlock)();
@property (nonatomic, copy) void (^confirmCompletionBlock)();
@end
当在LMSVBlockAlert中触发警报委托时,向block发送回调并从内存中清除
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
switch (buttonIndex) {
case 0://Cancel
{
if(_cancelCompletionBlock){
_cancelCompletionBlock();
}
}
break;
case 1://OK
{
if(_confirmCompletionBlock){
_confirmCompletionBlock(alertView);
}
}
break;
default:
break;
}
[_LMSVblockHandlersArray removeObject:self];
}
现在您可以有两个简单的方法,可以为您提供UIAlertView回调
+(LMSVBlockAlert*)newInstance{
LMSVBlockAlert *newIns = [[LMSVBlockAlert alloc] init];
[LMSVBlockAlert updateHandlerArrayWith:newIns];
return newIns;
}
+(UIAlertView*)promptAlertTwoBtn:(NSString*)msg title:(NSString*)title onCancel:(void (^)())onCancel onConfirm:(void (^)())onConfirm{
return [[LMSVBlockAlert newInstance] showAlertMainWithTitle:title msg:msg onCancel:^{
onCancel();
} onConfirm:^(UIAlertView *alertView) {
onConfirm();
}];
}
-(UIAlertView*)showAlertMainWithTitle:(NSString*)title msg:(NSString*)msg onCancel:(void (^)())onCancel onConfirm:(void (^)(UIAlertView*))onConfirm{
UIAlertView *newAlert = nil;
newAlert = [[UIAlertView alloc]
initWithTitle:title
message:msg
delegate:self
@"Cancel"
otherButtonTitles:@"Confirm", nil];
[newAlert show];
self.cancelCompletionBlock = onCancel;
self.confirmCompletionBlock = onConfirm;
return newAlert;
}
最后
希望您觉得它很有用。我编写了一个简单的类LMSVBlocks,可以在一行中轻松显示警报和获取块回调。希望您会发现它在这方面很有用 概念:要使UIAlertView块兼容,您需要另一个类(如LMSVBlockAlert)来处理委托方法,并且当UIAlertView委托将发出回调时,LMSVBlockAlert类可以在块中发送回调 代码: (LMSVBlockAlert.m) 在一个数组中维护LMSVBlockAlert的所有实例,以便它们具有强引用
static NSMutableArray *_LMSVblockHandlersArray = nil;
将块处理程序保持在LMSVBlockAlert中
@interface LMSVBlockAlert() <UIAlertViewDelegate>
@property (nonatomic, copy) void (^cancelCompletionBlock)();
@property (nonatomic, copy) void (^confirmCompletionBlock)();
@end
当在LMSVBlockAlert中触发警报委托时,向block发送回调并从内存中清除
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
switch (buttonIndex) {
case 0://Cancel
{
if(_cancelCompletionBlock){
_cancelCompletionBlock();
}
}
break;
case 1://OK
{
if(_confirmCompletionBlock){
_confirmCompletionBlock(alertView);
}
}
break;
default:
break;
}
[_LMSVblockHandlersArray removeObject:self];
}
现在您可以有两个简单的方法,可以为您提供UIAlertView回调
+(LMSVBlockAlert*)newInstance{
LMSVBlockAlert *newIns = [[LMSVBlockAlert alloc] init];
[LMSVBlockAlert updateHandlerArrayWith:newIns];
return newIns;
}
+(UIAlertView*)promptAlertTwoBtn:(NSString*)msg title:(NSString*)title onCancel:(void (^)())onCancel onConfirm:(void (^)())onConfirm{
return [[LMSVBlockAlert newInstance] showAlertMainWithTitle:title msg:msg onCancel:^{
onCancel();
} onConfirm:^(UIAlertView *alertView) {
onConfirm();
}];
}
-(UIAlertView*)showAlertMainWithTitle:(NSString*)title msg:(NSString*)msg onCancel:(void (^)())onCancel onConfirm:(void (^)(UIAlertView*))onConfirm{
UIAlertView *newAlert = nil;
newAlert = [[UIAlertView alloc]
initWithTitle:title
message:msg
delegate:self
@"Cancel"
otherButtonTitles:@"Confirm", nil];
[newAlert show];
self.cancelCompletionBlock = onCancel;
self.confirmCompletionBlock = onConfirm;
return newAlert;
}
最后
希望您发现它很有用。您可以从github简单地使用这些类别类 这为AlertView和action Sheet提供了关闭块 例如
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"AlertView+Block" message:@"WithBlocks" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"newAlertViewWithTextFields",@"newAlertViewWithSingleTextField", nil];
[alert showWithFinishBlock:^(UIAlertView *alertView, NSInteger buttonIndex)
{ if (buttonIndex == 0) { } else if (buttonIndex == 1) { } }];
除此之外,它还为文本字段提供方法
-(void) showWithFinishBlock:(FinishBlock_)block_; //-- AlertView with TextField [simple or secure]
-(void) showWithTextFieldBlock:(TextFieldBlock_)block_ secure:(BOOL)isSecure; //-- AlertView with two textfields username & password
您可以看看附带的示例。
我希望它能对您有所帮助。您可以从github简单地使用这些类别类 这为AlertView和action Sheet提供了关闭块 例如
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"AlertView+Block" message:@"WithBlocks" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"newAlertViewWithTextFields",@"newAlertViewWithSingleTextField", nil];
[alert showWithFinishBlock:^(UIAlertView *alertView, NSInteger buttonIndex)
{ if (buttonIndex == 0) { } else if (buttonIndex == 1) { } }];
除此之外,它还为文本字段提供方法
-(void) showWithFinishBlock:(FinishBlock_)block_; //-- AlertView with TextField [simple or secure]
-(void) showWithTextFieldBlock:(TextFieldBlock_)block_ secure:(BOOL)isSecure; //-- AlertView with two textfields username & password
您可以看看附带的示例。
我希望它能对您有所帮助。我写了一篇博客文章,介绍了如何(以及为什么)将块回调添加到警报视图、动作表和动画中: 如果您只想实现此功能,可以从GitHub下载源文件: 用法:
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];
我写了一篇关于如何(以及为什么)将块回调添加到警报视图、动作表和动画的博客文章: 如果您只想实现此功能,可以从GitHub下载源文件: 用法:
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];
我已经用Swift写了一个简单的扩展,希望对你有所帮助
import UIKit
extension UIAlertView {
func show(completion: (alertView: UIAlertView, buttonIndex: Int) -> Void){
self.delegate = AlertViewDelegate(completion: completion)
self.show()
}
class func showInput(title: String?, message: String?, cancellable: Bool, completion: (text: String?) -> Void){
var strOK = NSLocalizedString("OK",comment: "OK")
var strCancel = NSLocalizedString("Cancel",comment: "Cancel")
var alert = UIAlertView(title: title, message: message, delegate: nil, cancelButtonTitle: cancellable ? strCancel : strOK)
alert.alertViewStyle = UIAlertViewStyle.PlainTextInput
if(cancellable) {
alert.addButtonWithTitle(strOK)
}
alert.show { (alertView, buttonIndex) -> Void in
if(cancellable && alertView.cancelButtonIndex == buttonIndex) {
completion(text: nil)
return
}
completion(text: alertView.textFieldAtIndex(0)?.text)
}
}
private class AlertViewDelegate : NSObject, UIAlertViewDelegate {
var completion : (alertView: UIAlertView, buttonIndex: Int) -> Void
var retainedSelf : NSObject?
init(completion: (UIAlertView, Int) -> Void ) {
self.completion = completion
super.init()
self.retainedSelf = self
}
func alertView(alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int) {
var retain = self
retain.retainedSelf = nil
retain.completion(alertView: alertView, buttonIndex: buttonIndex)
}
}
}
我已经用Swift写了一个简单的扩展,希望对你有所帮助
import UIKit
extension UIAlertView {
func show(completion: (alertView: UIAlertView, buttonIndex: Int) -> Void){
self.delegate = AlertViewDelegate(completion: completion)
self.show()
}
class func showInput(title: String?, message: String?, cancellable: Bool, completion: (text: String?) -> Void){
var strOK = NSLocalizedString("OK",comment: "OK")
var strCancel = NSLocalizedString("Cancel",comment: "Cancel")
var alert = UIAlertView(title: title, message: message, delegate: nil, cancelButtonTitle: cancellable ? strCancel : strOK)
alert.alertViewStyle = UIAlertViewStyle.PlainTextInput
if(cancellable) {
alert.addButtonWithTitle(strOK)
}
alert.show { (alertView, buttonIndex) -> Void in
if(cancellable && alertView.cancelButtonIndex == buttonIndex) {
completion(text: nil)
return
}
completion(text: alertView.textFieldAtIndex(0)?.text)
}
}
private class AlertViewDelegate : NSObject, UIAlertViewDelegate {
var completion : (alertView: UIAlertView, buttonIndex: Int) -> Void
var retainedSelf : NSObject?
init(completion: (UIAlertView, Int) -> Void ) {
self.completion = completion
super.init()
self.retainedSelf = self
}
func alertView(alertView: UIAlertView, didDismissWithButtonIndex buttonIndex: Int) {
var retain = self
retain.retainedSelf = nil
retain.completion(alertView: alertView, buttonIndex: buttonIndex)
}
}
}
检查这个,我在几个项目中使用过它,对我很好。以下是示例:
OpinionzAlertView *alert = [[OpinionzAlertView alloc] initWithTitle:@"title"
message:@"message"
cancelButtonTitle:@"No, thanks"
otherButtonTitles:@[@"Done"]
usingBlockWhenTapButton:^(OpinionzAlertView *alertView, NSInteger buttonIndex) {
NSLog(@"buttonIndex: %li", (long)buttonIndex);
NSLog(@"buttonTitle: %@", [alertView buttonTitleAtIndex:buttonIndex]);
}];
[alert show];
我希望它能对您有所帮助。检查一下,我已经在几个项目中使用过它,对我很有用。以下是示例:
OpinionzAlertView *alert = [[OpinionzAlertView alloc] initWithTitle:@"title"
message:@"message"
cancelButtonTitle:@"No, thanks"
otherButtonTitles:@[@"Done"]
usingBlockWhenTapButton:^(OpinionzAlertView *alertView, NSInteger buttonIndex) {
NSLog(@"buttonIndex: %li", (long)buttonIndex);
NSLog(@"buttonTitle: %@", [alertView buttonTitleAtIndex:buttonIndex]);
}];
[alert show];
我希望这将对您有所帮助。在这个回答中,您没有显示您所引用的头文件/实现文件。您还引入了自定义警报概念,但没有解释它如何适合解决方案。这迫使读者猜测你的意图(这总是不好的)。答案可以通过解决这些错失的机会来改进,我指的是你的头文件和实现文件,而不是我的。因此,我无法向您提供一个,因为这意味着要放入您的代码中。。但你是对的,我没有提供完成电话。我已经补充了这一点。当您提到头文件和实现文件时,这两者是如何结合的?它是视图控制器还是自定义警报的子类?如果我先前的要求不清楚,很抱歉。我可以简单地假设是后者,但具体性总是更好的。头文件和实现文件是.h和.m文件,它们是您希望使用此函数指针的类的文件。可以将UIAlertView子类化,可以创建AlertManager,可以将其放在ViewController上,这取决于您想要做什么。这些信息仅仅显示了如何实现回调函数,以便您可以创建回调,使用回调函数,以及如何允许编辑器为您提供块本身:)在这个回答中,您没有显示所引用的头文件/实现文件。您还引入了自定义警报con