iOS:动态创建并分配名称给 UIControl

Posted

技术标签:

【中文标题】iOS:动态创建并分配名称给 UIControl【英文标题】:iOS: create and assign names to UIControl dynamically 【发布时间】:2012-06-28 09:42:37 【问题描述】:

我正在尝试编写数据驱动应用程序,在其中解析 json 字符串以创建 UI。我已经实现了这一点并创建了所需的控件。我根据分配给它们的标签来区分每个控件,这不是有效的方法。无论如何在动态创建 UIControl 时将名称(以下示例中的标签和文本字段除外)分配给它?

NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity: myArrayCount];
for ( loop = 0;  loop< myArrayCount; loop++ ) 
    NSString *propertyName = [NSString stringWithFormat:@"Label %d", loop];
    [myArray addObject:propertyName];

    CGRect labelFrame = CGRectMake(xLabel, yLabel, widthLabel, heightLabel);
    UILabel *label = [[UILabel alloc] initWithFrame: labelFrame];
    label.tag = loop;
    [label setText:propertyName];
    [label sizeToFit];
    [self.view addSubview:label];

    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(xTextField, yTextField, widthTextField, heightTextField)];
    textField.tag = loop;
    textField.borderStyle = UITextBorderStyleRoundedRect;
    textField.font = [UIFont systemFontOfSize:15];
    textField.placeholder = @"Enter parameter value";
    textField.autocorrectionType = UITextAutocorrectionTypeNo;
    textField.keyboardType = UIKeyboardTypeDefault;
    textField.returnKeyType = UIReturnKeyDone;
    textField.clearButtonMode = UITextFieldViewModeWhileEditing;
    textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    textField.returnKeyType = UIReturnKeyDone;
    textField.delegate = self;
    [self.view addSubview:textField];

    yLabel = yLabel+yOffset; 
    yTextField = yTextField+yOffset;


【问题讨论】:

标签是识别动态 UIControls 的有效方法,如果你按名称去的话,它会让事情变得更复杂。 我想是这样,但只是想知道是否有人有其他解决方案。每次我想访问特定文本字段的值时,我都必须解析所有文本字段并获取具有正确标签的文本字段并获取它的值!此外,我还有许多其他控件,如按钮、分段控件、uipicker 等……我可以为所有这些控件使用标签吗? 【参考方案1】:

假设您不想使用 [self.view viewWithTag:tag] 来检索您的控件,通过名称引用动态创建的控件的一种方法是将其放入具有动态生成键的 NSMutableDictionary 中。

所以可能类似于(修改您的代码,省略了一些细节):

NSMutableDictionary *controlsDictionary = [[NSMutableDictionary alloc] init];
for ( loop = 0;  loop< myArrayCount; loop++ ) 

CGRect labelFrame = CGRectMake(xLabel, yLabel, widthLabel, heightLabel);
UILabel *label = [[UILabel alloc] initWithFrame: labelFrame];
[controlsDictionary setObject:label forKey:[NSString stringWithFormat:@"label%d", loop]];

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(xTextField, yTextField, widthTextField, heightTextField)];
[controlsDictionary setObject:label forKey:[NSString stringWithFormat:@"textField%d", loop]];

yLabel = yLabel+yOffset; 
yTextField = yTextField+yOffset;


然后您可以通过[controlsDictionary objectForKey:@"label1"] 之类的语句检索控件

【讨论】:

这实际上是我正在做的。 key其实是一个标签值! 酷。另请参阅 UIView 上的 viewWithTag 方法,它应该允许您直接查找标记的子视图,而无需维护自己的字典。 哇!我认为 viewWithTag 看起来很棒!谢谢你。【参考方案2】:

虽然您无法通过类别将 iVar 添加到 UIControl,但您可以添加 Associated Objects,它可用于执行几乎相同的功能。

所以,像这样在UIControl 上创建一个类别:

static char kControlNameKey;

- (void) setControlName: (NSString *) name

    objc_setAssociatedObject(self, &kControlNameKey, name, OBJC_ASSOCIATION_COPY);


- (NSString *) controlName

    return (NSString *)objc_getAssociatedObject(array, &kControlNameKey);

除此之外,我想您需要在设置新关联之前检查关联是否存在,否则会泄漏,但这应该给您一个开始。

查看Apple Docs了解更多详情

【讨论】:

只是一个简单的问题。这是否意味着在文本字段中输入的值将被关联对象保存? 不,关联对象就像一个 iVar,您可以将其添加到一个实例中 - 在这种情况下,它就像向所有 UIControls 添加一个 NSString 属性 controlName。

以上是关于iOS:动态创建并分配名称给 UIControl的主要内容,如果未能解决你的问题,请参考以下文章

如何将名称动态分配给 RFID 阅读器连接的串行端口

Swift iOS 应用程序 - 静态分配具有动态变化行的表属性

如何将相同的事件侦听器分配给 Vue.js 中动态创建的按钮并将对象的值作为参数传递给它?

将值分配给由字符串名称动态确定的淘汰赛 observable

将事件分配给在运行时动态创建的 VCL 控件 (2)

传递动态内存