ios - 调用导航堆栈中的协议(protocol)方法

标签 ios delegates protocols

我声明了一个协议(protocol)方法以便其委托(delegate)调用。这是相关代码:

声明协议(protocol)的 View :

CategoryViewController.h

@class  CategoryViewController;
@protocol CategoryViewControllerDelegate<NSObject>
-(void)loadProductsList:(id)sender;


@end

@interface CategoryViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{

    id delegate;

}

@property(nonatomic, strong)id <CategoryViewControllerDelegate>delegate;

CategoryViewController.m

@implementation CategoryViewController

@synthesize delegate;

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
            CategoryViewController *catView = [[CategoryViewController alloc] initWithNibName:@"CategoryViewController" bundle:nil];
            [self.navigationController pushViewController:catView animated:YES];

            if([self.delegate respondsToSelector:@selector(loadProductsList:)]){
                [self.delegate loadProductsList:[arrayCategory objectAtIndex:indexPath.row]];
            }
    }

委托(delegate) View 称为MainViewController,在MainViewController的viewDidLoad方法中,我将委托(delegate)设置为self:

-(void)viewDidLoad{
    //Use a property of CategoryViewController to set the delegate

    self.categoryController.delegate = self;
}

-(void)loadProductsList:(id)sender{
//Logic


}

让我向您解释一下,CategoryViewControllerUINavigationController 管理,因此当单击一个单元格时,我会创建一个新的 CategoryViewController 实例并将其推送到导航堆栈。然后我调用协议(protocol)方法:

if([self.delegate respondsToSelector:@selector(loadProductsList:)]){
  [self.delegate loadProductsList:[arrayCategory objectAtIndex:indexPath.row]];
    }

问题是当 CategoryViewController 当前 View 为 0 索引时,委托(delegate)仅对 Root View 有效。然后委托(delegate)为空,因此当我尝试从堆栈 View 索引 1、2 等调用它时,协议(protocol)方法 loadProductsList: 无法触发。当我返回索引 0( Root View 在导航堆栈)委托(delegate)对象再次有效,我可以调用协议(protocol)方法。

我的问题是:

为什么我在创建 CategoryViewController 的新实例并将其推送到导航堆栈后无法触发协​​议方法?为什么委托(delegate)对象会变成 null 呢?提前致谢。

最佳答案

您仅为一个(第一个)CategoryViewController 类设置委托(delegate)。

每次选择一行时,您都会创建一个新的 CategoryViewController 类,由于您尚未设置它,因此其委托(delegate)为 nil。

编辑,

我在这里看到两个选项。

a) 您可以将 MainController 设置为单例,这样您就可以从代码中的任何位置访问它。然后你就可以在 didSelectRowAtIndexPath 中将它设置为委托(delegate)。

b) 你可以回溯传递委托(delegate)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
        CategoryViewController *catView = [[CategoryViewController alloc] initWithNibName:@"CategoryViewController" bundle:nil];
        [self.navigationController pushViewController:catView animated:YES];

        catView.delegate = self.delegate;

        if([self.delegate respondsToSelector:@selector(loadProductsList:)]){
            [self.delegate loadProductsList:[arrayCategory objectAtIndex:indexPath.row]];
        }
}

关于ios - 调用导航堆栈中的协议(protocol)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15746395/

相关文章:

Swift 通用约束无法转换值

ios - 始终从Internet获取Xcode 7.2文档

ios - -bash : cd: supbot-tut: No such file or directory

c# - 取消订阅通过 ref 关键字传递给订阅方法的委托(delegate)?

c# - 需要 && 在一起不确定数量的 Func<TEntity, bool>

swift - 将委托(delegate)从一个 VC 传递到另一个 VC,而不使用prepareForSegue

ios - 在 Storyboard 中创建包含文本、图像、按钮的列表

iOS 扩展和访问资源中的文件

ios - 类型不符合协议(protocol) - 类型别名到另一个协议(protocol)

c++ - 如何解码跟踪器响应中的对等值 (Bittorrent)