简体   繁体   English

从子视图中访问UIViewController方法

[英]Access UIViewController methods from within subview

I subclassed UITableViewCell and initialized it in a UIView. 我将UITableViewCell子类化,并在UIView中对其进行了初始化。 From the TableView, I need to call a method in the parent ViewController (to perform segues, etc.). 从TableView,我需要在父ViewController中调用一个方法(以执行segue等)。

Now, since the ViewController cannot be directly passed to its subviews (in respect of MVC principles), I created a delegation pattern, adding a protocol to the UITableView, and implementing the protocol as delegate in the UIVIewController. 现在,由于无法将ViewController直接传递到其子视图(就MVC原理而言),因此我创建了一个委托模式,向UITableView添加了协议,并在UIVIewController中将协议实现为委托。

The problem is that since the TableView is instantiated from the UIView, which is a subview of the Viewcontroller, I cannot assign the ViewController as delegate in the cellForRowAtIndexPath method since "self" would point to the View not the ViewController. 问题在于,由于TableView是从UIView实例化的,UIView是Viewcontroller的子视图,因此我无法在cellForRowAtIndexPath方法中将ViewController分配为委托,因为“自身”将指向View而不是ViewController。

If I move all the table methods to the ViewController and instantiate the table from there, everything work as I wish. 如果我将所有表方法都移到ViewController并从那里实例化表,那么一切都会按我的意愿进行。 But that would not allow me to reuse the code in other ViewControllers. 但这不允许我在其他ViewController中重用代码。

CustomViewController.h CustomViewController.h

#import "CustomTableViewCell.h"
@interface CustomViewController : UIViewController<CustomTableViewCellDelegate>

CustomViewController.m CustomViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    // Create a sub-view where the custom table will appear
   _customUIView = [[CustomUIView alloc] initWithFrame:CGRectMake(0, 60, self.view.frame.size.width, self.view.frame.size.height-60)];

   [self.view addSubview:_customUIView];
   [_customUIView populateTheView];
}

CustomUIView.m CustomUIView.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *cellIdentifier = [NSString stringWithFormat:@"cell%ld",(long)indexPath.row];

    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {
        cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
        cell.delegate = self; // << THIS WILL NOT WORK AS IT WOULD POINT TO THE View, RATHER THAN THE ViewController
    }
}

CustomTableViewCell.h CustomTableViewCell.h

@protocol CustomTableViewCellDelegate <NSObject>
    -(void)performSegue;
@end
@interface CustomTableViewCell : UITableViewCell
    @property(weak, nonatomic) id<CustomTableViewCellDelegate>delegate;
@end

CustomTableViewCell.m CustomTableViewCell.m

if ([self.delegate respondsToSelector:@selector(performSegue)]) {
    [self.delegate performSegue];
}

The best solution I could find is using notifications. 我能找到的最佳解决方案是使用通知。 In your viewController set up the observer in the viewWillAppear method. 在您的viewController中,在viewWillAppear方法中设置观察者。 You will also need to remove it in the viewWillDisappear method or the app will crash: 您还需要在viewWillDisappear方法中将其删除,否则应用程序将崩溃:

// In the parent view controller
- (void)viewWillAppear:(BOOL)animated {
    // Add observers to perform an action    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(imageTappedMessageReceived:) name:@"imageTapped" object:nil];
}

-(void) imageTappedMessageReceived:(NSNotification *)notification {
    NSLog(@"The image was tapped");
}

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"View controller will disappear");
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"imageTapped" object:nil];
}

In your subview issue the notification when you need to (button pushed or other logic your have): 在子视图中,在需要时发出通知(按按钮或您拥有的其他逻辑):

// In the subview
[[NSNotificationCenter defaultCenter] postNotificationName:@"imageTapped" object:self userInfo:tempDictionary];

The "imageTappedMessageReceived" method in the viewController will be fired every time the "imageTapped" notification is called in the subview. 每当在子视图中调用“ imageTapped”通知时,都会触发viewController中的“ imageTappedMessageReceived”方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM