【问题标题】:Objective c, callback from viewController when button is clicked目标c,单击按钮时来自viewController的回调
【发布时间】:2021-02-16 01:52:48
【问题描述】:

我有 viewController1 - 主视图控制器和 viewController2 - 这是我的 customPopUp。我想在单击 button1 或 button2 时从 viewController2 创建回调。

在 viewController1 中的代码是这样的

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
    CustomPopUpViewController *vc = (CustomPopUpViewController *)[storyboard instantiateViewControllerWithIdentifier:@"CustomPopUpViewControllerID"];
    vc.textAlert = text;
    vc.btn1TxtAlert = btn1Txt;
    vc.isAlertOneBtn = YES;

我想做这样的事情:

vc.button1Callback {

}
vc.button2Callback {

}

-- 代码在viewController2

viewController2.h

@interface CustomPopUpViewController : UIViewController
@property (nonatomic, assign) NSString* titleAlert;
@property (nonatomic, assign) NSString* textAlert;
@property (nonatomic, assign) NSString* btn1TxtAlert;
@property (nonatomic, assign) NSString* btn2TxtAlert;
@property (nonatomic, assign) BOOL isAlertOneBtn;

viewController2.m

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    _UIbtn2Txt.layer.borderWidth = 2.0f;
    _UIbtn2Txt.layer.borderColor = [UIColor colorWithRed:0.09 green:0.53 blue:0.00 alpha:1.0].CGColor;
    
    _textLbl.text = _textAlert;
    [_UIbtn1Txt setTitle:_btn1TxtAlert forState:UIControlStateNormal];
    [_UIbtn2Txt setTitle:_btn2TxtAlert forState:UIControlStateNormal];
    if(_isAlertOneBtn) {
        _UIbtn2Txt.hidden = YES;
    }
}

- (IBAction)btnAction1:(id)sender {
    [self dismissViewControllerAnimated:true completion:nil];
       // how i can do callback from this place

}

- (IBAction)btnAction2:(id)sender {
    [self dismissViewControllerAnimated:true completion:nil];
   // how i can do callback from this place

}

我考虑在 viewController2.h 委托方法中创建,如下所示:

@protocol CustomPopUpDelegate;

@interface CustomPopUpViewController : UIViewController


@property (nonatomic, assign) NSString* titleAlert;
@property (nonatomic, assign) NSString* textAlert;
@property (nonatomic, assign) NSString* btn1TxtAlert;
@property (nonatomic, assign) NSString* btn2TxtAlert;
@property (nonatomic, assign) BOOL isAlertOneBtn;

@property (weak)id <CustomPopUpDelegate> delegate;
@end

@protocol CustomPopUpDelegate <NSObject >
    - (id) btn1Action;
    - (id) btn2Action;

@end

改变这个地方

- (IBAction)btnAction1:(id)sender {
    [self dismissViewControllerAnimated:true completion:nil];
    [self.delegate btn1Action];
}

- (IBAction)btnAction2:(id)sender {
    [self dismissViewControllerAnimated:true completion:nil];
    [self.delegate btn2Action];

}

然后我无法理解如何在 viewController1 中没有全局实现 CustomPopUpDelegate 的情况下从 btn1Actionbtn2Action 委派操作。

我需要从 viewController2 "localy" 写回调,在同一个地方,例如:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
        CustomPopUpViewController *vc = (CustomPopUpViewController *)[storyboard instantiateViewControllerWithIdentifier:@"CustomPopUpViewControllerID"];
        vc.textAlert = text;
        vc.btn1TxtAlert = btn1Txt;
        vc.isAlertOneBtn = YES;
    vc.button1Callback {
// how write like this??    
    }
    vc.button2Callback {
    // how write like this??    

    }

【问题讨论】:

  • 在 vc2 中使用块 ...,有两个 ivars @property (nonatomic,strong) void ( ^ action1 )( void ); 或您需要的任何东西,然后从 vc1 设置它们并在 vc2 中执行它们。
  • @skaak 谢谢你的回答,但你能解释一下吗,我不清楚。例如,在 vc2 中,我创建了 @property (nonatomic, strong) void ( ^ action1 )( void );,然后在 vc2 中,如果单击了按钮,我将调用方法 [self action1];。在 vc1 中,我尝试创建这样的回调 [vc action1:^ {}] 但似乎有问题(
  • 好的,因为我需要更多空间,所以我会发布作为答案,但是块是这项工作的人......

标签: ios objective-c callback delegates


【解决方案1】:

块是你在这里使用的。可以说,它们就是为此而生的。

在你想要回调的地方创建一个 ivar。现在回调是一个块,一段您将在需要时执行的代码。所以块的类型会有所不同。这里有一些例子......

@property (nonatomic, strong) void ( ^ callbackAction1 )( BOOL ); // Block is named callbackAction1 - it takes a BOOL arg and returns nothing
@property (nonatomic, strong) BOOL ( ^ callbackAction2 )( BOOL ); // Block is named callbackAction2 - it takes a BOOL and returns a BOOL
@property (nonatomic, strong) void ( ^ callbackAction3 )( void ); // Block is named callbackAction3 - it takes nothing and returns nothing

// Real life example
@property (nonatomic,strong)    void ( ^ valueChanged )( XXBooleanCollectionViewCell *, BOOL );

...等等。

然后您将这些块链接到您的操作,例如在你的情况下

- (IBAction)btnAction1:(id)sender {
    [self dismissViewControllerAnimated:true completion:nil];
    if ( self.callbackAction1 ) {
       // Here we use the block
       self.callbackAction1 ( YES ); // or whatever you need ...
    }
}

有时如果 UI 需要它,您可以在完成块中执行该块,如果完成块的格式正确,您甚至可以将该块作为完成块传递,因此

- (IBAction)btnAction1:(id)sender {
    [self dismissViewControllerAnimated:true completion:callbackAction3];
}

这将在完成后调用 callbackAction3。

然后,要在您调用它时将其称为“本地”,请按照以下示例更改您的代码。

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
        CustomPopUpViewController *vc = (CustomPopUpViewController *)[storyboard instantiateViewControllerWithIdentifier:@"CustomPopUpViewControllerID"];
        vc.textAlert = text;
        vc.btn1TxtAlert = btn1Txt;
        vc.isAlertOneBtn = YES;
    vc.button1Callback {
// how write like this??    
    }
    vc.button2Callback {
    // how write like this??    

    }
    // This is how
    vc.callbackAction1 = ^ ( BOOL p ) { 
       if ( p ) something ... the logic of the callback goes in here
    };
    vc.callbackAction2 = ^ BOOL { ... callback logic ... };
    vc.callbackAction3 = ^ { ... };

这是此类事物的常见模式。我对你的逻辑并不完全清楚,我的回答可能并不完全正确,所以请告诉我,我会相应地更新,但这是适合这项工作的人。

根据您的评论,我认为您的语法错误,应该是

vc.action1 = ^{ ... };

一旦您陷入语法http://goshdarnblocksyntax.com/,这里是一个不错的网站。

【讨论】:

  • 很好 - 我确定之前有人问过这个问题,但是您的代码正在乞求块,而且很容易将这些片段插入代码中的正确位置。但同样,也许我在某个地方弄错了,所以让我知道,我会修复它......
  • 好东西——你的想法是对的,我可以在你的代码中看到,你只是缺乏技术。现在你知道了 - 它很棒并且经常使用,例如所有这些完成处理程序。有时您也会使用委托,但这有点重 - 块既好又轻。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多