从子视图中访问UIViewController方法

时间:2016-09-25 04:39:18

标签: ios objective-c

我将UITableViewCell子类化并在UIView中初始化它。从TableView,我需要在父ViewController中调用一个方法(以执行segues等)。

现在,由于ViewController无法直接传递给它的子视图(就MVC原则而言),我创建了一个委托模式,向UITableView添加协议,并在UIVIewController中将协议实现为委托。

问题在于,由于TableView是从UIView实例化的,UIView是Viewcontroller的子视图,因此我不能将ViewController指定为cellForRowAtIndexPath方法中的委托,因为" self"将指向View而不是ViewController。

如果我将所有表方法移动到ViewController并从那里实例化表,那么一切都按照我的意愿工作。但这不允许我在其他ViewControllers中重用代码。

CustomViewController.h

html, body {
    height: 100%;
}

.navbar {
    width: 100%;
    text-align: center;
    z-index: 1;
    box-shadow: 0px 0px 10px 10px black;
    /*position: absolute;*/
    padding: 0;
    margin: 0;
}

.navbar ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
    overflow: hidden;
    background-color: #E7E7EF;
    padding: 10px;
    width: 100%;
}

.navbar ul li {
    display: inline;
    text-align: center;
    padding: 10px;
    margin: 0;
    padding: 0;
    position: relative;
}

.navbar ul li a {
    padding: 10px;
    background: #E7E7EF;
    text-decoration: none;
    color: #CE0000;
    font-size: 2em;
    display: inline;
    cursor: pointer;
}

.navbar ul li a:hover {
    background-color: #C6CFD6;
}

.body {
    background-color: #C6CFD6;
    width: 70%;
    z-index: -1;
    text-align: center;
    display: block;
    margin: auto;
    box-shadow: 0px 0px 10px 10px black;
    margin-top: 0;
    padding-top: 0;
}

CustomViewController.m

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

CustomUIView.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];
}

CustomTableViewCell.h

- (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.m

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

1 个答案:

答案 0 :(得分:0)

我能找到的最佳解决方案是使用通知。 在viewController中,在viewWillAppear方法中设置观察者。您还需要在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 the subview
[[NSNotificationCenter defaultCenter] postNotificationName:@"imageTapped" object:self userInfo:tempDictionary];

每次在子视图中调用“imageTapped”通知时,都会触发viewController中的“imageTappedMessageReceived”方法。