在objective-c中发送不同对象的最佳方式

时间:2016-05-03 05:32:13

标签: ios objective-c messaging

我有一个UITableView,在每个标题内,我有一个手势识别器。在手势处理程序中,我想对标题视图中的内容进行更改。

-(void) sectionHeaderButtonPressed: (UIButton *)sender{
    NSLog(@"Header Button pressed");
    //UIView *mySubView = [sender.view.subviews objectAtIndex:0];
    NSLog(@"Class: %@",[self class]);
    int count = [self.view.subviews count];
    NSLog(@"Self.view.subviews: %u",count);
    Class buttonClass = NSClassFromString(@"UIButton");
    for (int i=0; i < count; i++){
        int subViewCount = [[self.view.subviews objectAtIndex:i] subviews].count;
        Class className = [[self.view.subviews objectAtIndex:i] class];
        NSLog(@"SubView (%u) Class:%@ SubViews: %u",i,className,subViewCount);
        for (int j=0; j < subViewCount; j++){
            Class className01 = [[[self.view.subviews objectAtIndex:i].subviews objectAtIndex:j ] class];
            NSLog(@"----SubSubView (%u) Class:%@",j,[[[self.view.subviews objectAtIndex:i].subviews objectAtIndex:j ] class]);
            NSLog(@"Comparing Class: %@ to Class: %@",className01, buttonClass);
            if (className01 == buttonClass){
                [[[self.view.subviews objectAtIndex:i].subviews objectAtIndex:j ] setTitle:@"ABCDE" forState:UIControlStateNormal];
                NSLog(@"found button class");
            }
        }
    }
}

上面的代码是手势处理程序,我可以找到按钮和其他所有子视图,但这是一个真正的麻烦。

我似乎对一个对象如何调用另一个对象感到困惑。我想将headerview传递给手势处理程序,但无法弄清楚如何做到这一点。

如何直接发送或访问标题视图和/或其子视图。如果我有几个相同的类类型,那么查看类名将无济于事。

问题是关于在另一个对象中调用动作的正确方法。通过所有子视图运行似乎不是正确的方法。基于类名称的id是一种容易出错的方式,因为你可能有许多相同的类。

我希望有一个“从侧面滑入”选择菜单,并根据用户从菜单中选择的内容修改标题。他们将点击标题,它将调用手势处理程序,它将调用滑出菜单,滑出菜单将调用标题以使其更改其内容。

这是令人困惑的最后一部分,如何在菜单完全不同的对象时更改标题视图内容。

1 个答案:

答案 0 :(得分:2)

最好的方法是使用委托,让你的ViewController为你做繁重的工作。可以找到有关如何创建委托的一些示例here

使用自定义委托协议创建自定义视图

您需要做的第一件事是创建要实现的HeaderView的子类。正如您自己已经说过的那样,您的代码变得很麻烦,这将是创建自定义视图的好机会。

在这个自定义视图中,根据需要重新创建标题,并使用界面构建器或以编程方式连接一些标签/按钮(如果以编程方式执行此操作,请记住将UI元素的所有弱指针更改为强,我假设您将使用界面构建器

你的.h应该是这样的:

#import <UIKit/UIKit.h>

@protocol CustomHeaderViewDelegate;

@interface CustomHeaderView : UIView

@property (nonatomic, weak) UILabel *someLabel;
@property (nonatomic, weak) UILabel *someButton;

@property (nonatomic, weak) id<CustomHeaderViewDelegate> delegate;

@end

@protocol CustomHeaderViewDelegate <NSObject>

- (void)customHeaderView:(CustomHeaderView *)customheaderView receivedTouchOnButton:(UIButton *)button;

@end

和您的.m文件:

#import "CustomHeaderView.h"

@implementation CustomHeaderView

- (IBAction)buttonPressed:(id)sender {
    if (self.delegate) {
        [self.delegate customHeaderView:self receivedTouchOnButton:sender];
    }
}

@end

使viewcontroller符合委托协议

在视图控制器中,您希望从新创建的CustomHeaderView实现委托协议。首先确保viewController实际符合新创建的协议,方法是将<CustomHeaderViewDelegate>添加到viewcontroller的.m文件中的接口声明中。它应该看起来像:

...
#import "CustomHeaderView.h"

@interface YOURVIEWCONTROLLER () <CustomHeaderViewDelegate>
...

现在,在viewController的某处,您可以添加以下方法:

- (void)customHeaderView:(CustomHeaderView *)customheaderView receivedTouchOnButton:(UIButton *)button {
    [button setTitle:@"ABCDE" forState:UIControlStateNormal];
}

将标题添加到tableView

在viewForHeaderInSection代码中执行以下操作:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    CustomHeaderView headerView = [[CustomHeaderView alloc] init];
    headerView.delegate = self;
    /* do some more customisation */

    return headerView;
}

查找按钮

如果您想在部分标题中找到您的按钮或其他视图,您只需执行以下操作:

CustomHeaderView *customHeaderView = (CustomHeaderView *)[self tableView:YOURTABLEVIEW viewForHeaderInSection:SOMESECTION];
customHeaderView.button;