繁体   English   中英

如何处理动态创建的UIButton

[英]How to handle dynamically created UIButtons

我有一个UIViewController充当一种菜单。 菜单由多个框/小块组成,这些框/小块是UIView,其中包含带有说明的UILabel,链接到另一个显示更多信息的UIViewController的UIButton和另一个链接到显示应用程序另一区域的UIViewController的另一个UIButton。

目前,这些盒子中有3个,但这将会增长。 目前,我已经像这样对每个人进行了硬编码:

- (void)drawProceduresBox
{
self.viewProceduresBox = [[UIView alloc] initWithFrame:CGRectMake((_screenWidth * 0.05), (_screenHeight * 0.35), (_screenWidth * 0.9), (_screenHeight * 0.25))];
[_viewProceduresBox setBackgroundColor:[UIColor whiteColor]];
_viewProceduresBox.layer.borderWidth = 1.0f;
_viewProceduresBox.layer.borderColor = [UIColor grayColor].CGColor;

CGFloat boxHeight = _viewProceduresBox.frame.size.height;
CGFloat boxWidth = _viewProceduresBox.frame.size.width;

self.buttonShowProcedures = [[UIButton alloc] init];
[_buttonShowProcedures setFrame:CGRectMake((boxWidth * 0.8), (boxHeight * 0.4), (boxWidth * 0.1), (boxHeight * 0.2))];
[_buttonShowProcedures setBackgroundColor:[UIColor greenColor]];
[_buttonShowProcedures addTarget:self action:@selector(showProcedures) forControlEvents:UIControlEventTouchUpInside];

_buttonshowMoreInfo = [[appButton alloc] init];
[_buttonshowMoreInfo setFrame:CGRectMake((boxWidth * 0.6), (boxHeight * 0.6), (boxWidth * 0.1), (boxHeight * 0.2))];
[_buttonshowMoreInfo setBackgroundColor:[UIColor blueColor]];
[_buttonshowMoreInfo setWhatToShow:@"vetMed"];
[_buttonshowMoreInfo addTarget:self action:@selector(showMoreInfo:) forControlEvents:UIControlEventTouchUpInside];

[_viewProceduresBox addSubview:_buttonShowProcedures];

}

这些盒子可能有10多个,所以我想要一种动态创建它们的方法。 到目前为止,这是我尝试过的:

-(void)drawBox:(NSString*)moduleName boxFrame:(CGRect)boxFrame labelDesc:(NSString*)labelDesc
{

UIView *moduleInfoBox = [[UIView alloc] initWithFrame:boxFrame];
[moduleInfoBox setBackgroundColor:[UIColor purpleColor]];

CGFloat boxHeight = moduleInfoBox.frame.size.height;
CGFloat boxWidth = moduleInfoBox.frame.size.width;

UILabel *moduleLable = [[UILabel alloc] init];
[moduleLable setFrame:CGRectMake((boxWidth * 0.05), (boxHeight * 0.05), (boxWidth * 0.6), (boxHeight * 0.9))];
[moduleLable setBackgroundColor:[UIColor yellowColor]];
[moduleLable setText:labelDesc];

UIButton *showModuleButton = [[UIButton alloc] init];
[showModuleButton setFrame:CGRectMake((boxWidth * 0.8), (boxHeight * 0.15), (boxWidth * 0.1), (boxWidth * 0.2))];
[showModuleButton setBackgroundColor:[UIColor grayColor]];
[showModuleButton addTarget:self action:@selector(showModule:) forControlEvents:UIControlEventTouchUpInside];

UIButton *showMoreInfoButton = [[UIButton alloc] init];
[showMoreInfoButton setFrame:CGRectMake((boxWidth * 0.8), (boxHeight * 0.65), (boxWidth * 0.1), (boxWidth * 0.1))];
[showMoreInfoButton setBackgroundColor:[UIColor orangeColor]];
[showMoreInfoButton addTarget:self action:@selector(showMoreInfo:) forControlEvents:UIControlEventTouchUpInside];

[moduleInfoBox addSubview:moduleLable];
[moduleInfoBox addSubview:showModuleButton];
[moduleInfoBox addSubview:showMoreInfoButton];

_scrollHeight = _scrollHeight + (moduleInfoBox.frame.origin.y + moduleInfoBox.frame.size.height);

[_scrollView addSubview:moduleInfoBox];


}

我将这样调用该方法(在这种情况下为三个框):

CGRect formularyFrame = CGRectMake((_screenWidth * 0.05), (_screenHeight * 0.05), (_screenWidth * 0.9), (_screenHeight * 0.25));
CGRect proceduresFrame = CGRectMake((_screenWidth * 0.05), (_screenHeight * 0.35), (_screenWidth * 0.9), (_screenHeight * 0.25));
CGRect vetMedFrame = CGRectMake((_screenWidth * 0.05), (_screenHeight * 0.65), (_screenWidth * 0.9), (_screenHeight * 0.25));
[self drawBox:@"Formulary" boxFrame:formularyFrame labelDesc:@"Desc about formulary module"];
[self drawBox:@"Procedures" boxFrame:proceduresFrame labelDesc:@"Desc about procedures module"];
[self drawBox:@"VetMed" boxFrame:vetMedFrame labelDesc:@"Desc about vetMed module"];

我遇到的问题是动态生成的UIButton需要链接到相关的东西,在这种情况下为UIViewControllers。 每个按钮都有一个选择器,该选择器触发方法“ showModule”和“ showModuleInfo”。

在这些方法中,如何知道按下了什么UIButton,并因此知道将navigationController推送到哪个UIViewController? 基本上,我想要一些类似的东西:

-(void)showModule:(NSString*)moduleToShow
{
    [self.navigationController pushViewController:moduleToShow animated:NO];
}

但据我所知,您不能向“ @selector”分配中添加参数:

[_buttonshowMoreInfo addTarget:self action:@selector(showMoreInfo:) forControlEvents:UIControlEventTouchUpInside];

我该怎么办呢?

您在点击UIButton时调用的方法UIButton 例如,现在您有:

// if a button action triggers this as your code is written, it won't have a valid string.
-(void)showModule:(NSString*)moduleToShow
{
    [self.navigationController pushViewController:moduleToShow animated:NO];
}

这意味着,当您点击按钮时, showModule:方法将收到一个NSString对象,但实际上,它将收到触发事件的UIButton对象。 像这样:

-(void)showModule:(UIButton *)sender
{
    // use information about the button that sent the action
}

知道轻按了哪个按钮的常见方法是在创建按钮时在按钮上设置唯一的标签。 如果您只有几个,则将int编码到它们上会很好-如果您有很多并且需要将它们全部区分开,则可能需要设置宏,以便可以命名int

UIButton *showModuleButton = [[UIButton alloc] init];
...
showModuleButton.tag = 1;
[showModuleButton addTarget:self action:@selector(showModule:) forControlEvents:UIControlEventTouchUpInside];

现在,只要您“触摸”按钮内部,就会调用showModule:并可以在其中访问sendertag属性,以查看哪个按钮触发了事件。

-(void)showModule:(UIButton *)sender
{
    // use information about the button that sent the action
    if(sender.tag == 1)
    {
        // you know which button triggered the event now!
    }
}

如果要在按钮和视图控制器类之间创建映射以在单击按钮时显示,则有两个简单的选项:

  1. 为每个按钮分配标签,并创建将标签映射到类(到NSStringClass )的字典:

     @property(nonatomic, strong) NSMutableDictionary *tagClassDic; -(void)drawBox:(NSString*)moduleName boxFrame:(CGRect)boxFrame labelDesc:(NSString*)labelDesc buttonTag:(NSInteger)tag { ... showModuleButton.tag = tag; } -(void)showModule:(UIButton *)sender { NSString *classStr = self.tagClassDic[@(sender.tag)]; [self.navigationController pushViewController:[NSClassFromString(classStr) new] animated:NO]; // or, if you decide to store classes in the dictionary: [self.navigationController pushViewController:[self.tagClassDic[@(sender.tag)] new] animated:NO]; } ... self.tagClassDic = [NSMutableDictionary dictionary]; NSInteger firstTag = 1; [self drawBox:@"Formulary" boxFrame:formularyFrame labelDesc:@"Desc about formulary module" buttonTag:firstTag]; self.tagClassDic[@(firstTag)] = @"ViewController"; // or [ViewController class] 
  2. 将关联的对象(再次是字符串或类)直接设置为按钮对象:

     static const char *kViewControllerClassKey = "viewControllerClassKey"; -(void)drawBox:(NSString*)moduleName boxFrame:(CGRect)boxFrame labelDesc:(NSString*)labelDesc viewControllerClassStr:(NSString*)classStr { ... objc_setAssociatedObject(showModuleButton, kViewControllerClassKey, classStr, OBJC_ASSOCIATION_COPY_NONATOMIC); } -(void)showModule:(UIButton *)sender { NSString *classStr = objc_getAssociatedObject(sender, kViewControllerClassKey); [self.navigationController pushViewController:[NSClassFromString(classStr) new] animated:NO]; } ... [self drawBox:@"Formulary" boxFrame:formularyFrame labelDesc:@"Desc about formulary module" viewControllerClassStr:@"ViewController"]; 

暂无
暂无

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

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