我需要使用JSON创建动态表单。我已经解析了JSON,但我不知道如何动态创建表单。 我正在获取json数据,其中有一些控件,如复选框,文本字段和现在我想要根据问题创建的问题。 与我们如何使用Google表单创建一样。 请查看以下链接https://docs.google.com/forms/d/1lPn1aSvJsiDbJchsJjwsC93tWizXhj1qWkFPygt3oU4/viewform 请提供一些代码或教程。
答案 0 :(得分:2)
我的想法是,步骤
1)创建模型类示例
class UIControl
{
NSString *strControlName;
NSString *strControlType;
NSString *strControlValue;
Bool isSelected;
}
2)解析json并创建模型类的对象
3)将模型类对象添加到arrOfControls
中4)要么去表视图,要么只使用循环来遍历整个arrOfControls
5)以防万一,表视图检查cellForRowAtIndexPath控件类型。
6)为JSON数据可能带来的每个可能字段创建自定义单元格。
7)根据控件的类型,在删除函数(cellForRowAtIndexPath)中返回自定义单元格。例如: -
if([[arrOfControls objectAtIndexPath:indexPath.row] strType] isEqualToString:@"TextField"]])
{
//create object of customcell for textfield and return cell
}
else if([[arrOfControls objectAtIndexPath:indexPath.row] strType] isEqualToString:@"CheckBox"]])
{
//create object of customcell for checkbox and return cell
}
else
{
//control type if not match any of the above
}
这是粗略的想法而非实际代码。 对于cellForRowAtIndexPath
,我的项目中的代码很少 if(indexPath.section==0)
{
FormField *currControl=[fieldArray objectAtIndex:indexPath.row];
if(([currControl.strFieldType caseInsensitiveCompare:@"TextLabel"]==NSOrderedSame )|| [currControl.strFieldType caseInsensitiveCompare:@"Text"]==NSOrderedSame)
{
TextFieldWithLabelTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellTextFieldWithLabel"];
cell.txtTextField.delegate=self;
[cell.txtTextField setTag:indexPath.row];
if([currControl strFieldValue]==nil)
{
cell.txtTextField.text = @"";
[cell.txtTextField setPlaceholder:[currControl strPlaceHolder]];
}
else
{
//if save value exists
cell.txtTextField.text=@"";
cell.txtTextField.text=[currControl strFieldValue];
}
cell.lblTextFieldIdenti.text=[[fieldArray objectAtIndex:indexPath.row] strFieldName];
if([currControl.strFieldType caseInsensitiveCompare:@"Text"]==NSOrderedSame)
{
cell.lblTextFieldIdenti.text=@"";
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
else if(([currControl.strFieldType caseInsensitiveCompare:@"TextView"]==NSOrderedSame)||([currControl.strFieldType caseInsensitiveCompare:@"TextViewWithCam"]==NSOrderedSame))
{
TableViewTextAreaCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableViewTextAreaCell"];
cell.txtView.delegate=self;
cell.txtView.text=@"";
if([currControl strFieldValue]!=nil)
{
//if save value exists
cell.txtView.text=@"";
cell.txtView.text=[currControl strFieldValue];
}
cell.fieldLabel.text=[[fieldArray objectAtIndex:indexPath.row] strFieldName];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
keyboardDoneButtonView.barStyle = UIBarStyleDefault;
keyboardDoneButtonView.translucent = NO;
keyboardDoneButtonView.barTintColor=[UIColor colorWithHue:0.6 saturation:0.33 brightness:0.69 alpha:0];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem *leftFlexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:leftFlexSpace];
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"BTN_DONE", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(pickerDoneClicked:)];
[barItems addObject:btnDone];
[keyboardDoneButtonView setItems:barItems animated:YES];
[cell.txtView setInputAccessoryView:keyboardDoneButtonView];
[cell configureCell:currControl.strFieldName];
cell.fieldLabel.textColor=[UIColor darkTextColor];
cell.txtView.backgroundColor =[UIColor colorWithHexString:@"#f3f1f2"];
cell.fieldLabel.font=[UIFont systemFontOfSize:12];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.imgViewCam setHidden:TRUE];
if([currControl.strFieldType caseInsensitiveCompare:@"TextViewWithCam"]==NSOrderedSame)
{
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(CameraClicked:)];
[singleTap setNumberOfTapsRequired:1];
[cell.imgViewCam addGestureRecognizer:singleTap];
[cell.imgViewCam setHidden:FALSE];
}
return cell;
}
else if([currControl.strFieldType caseInsensitiveCompare:@"DropDown"]==NSOrderedSame)
{
//if dropdwon box
DropDownTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellDropDown"];
cell.lblDropDownidentifier.text=[currControl strFieldName];
[cell.btnDropDown setTag:indexPath.row];
[cell.btnDropDown addTarget:self action:@selector(ShowOptions:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnDropDown setTitle:@"" forState:UIControlStateNormal];
if([currControl strFieldValue]!=nil)
{
[cell.btnDropDown setTitle:[currControl strFieldValue] forState:UIControlStateNormal];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
if([[currControl strFieldName] caseInsensitiveCompare:@"Time Of Delivery:"]==NSOrderedSame)
{
cell.imgDropDown.image=[UIImage imageNamed:@"stopwatch.png"];
}
else if([[currControl strFieldName] caseInsensitiveCompare:@"Date Of Delivery:"]==NSOrderedSame)
{
cell.imgDropDown.image=[UIImage imageNamed:@"calendar.png"];
}
else
{
cell.imgDropDown.image=[UIImage imageNamed:@"dropdown.jpeg"];
}
return cell;
}
答案 1 :(得分:1)
这是我发现非常有趣并快速搜索的内容。根据您的JSON在其中的内容,我可以看到实现此目的的两种方法。
1。)如果你的JSON是这样的:
{"输入":" TextField", "属性" :{ " Property1":"值1&#34 ;, " Property2":"值2"} }
等
您必须拥有条件代码,具体取决于类型;
UIControl *newControl
if([[parsedJson valueForKey:@"Type"] isEqualTo:"TextField"])
{
newControl = [UITextField alloc]init];
for(NSDictionary *dict in [parsedJson valueForKey:"Properties")
{
[newControl setValue:[dict value] forKey:[dict Key]];
}
}
另一方面,如果您的JSON使用类型的UIKit名称,例如:
{"类型":"的UITextField""属性" {" Property1":"值1&#34 ;, " Property2":2}}
等
你可以做一些反思:
id *control = [[NSClassFromString([parsedJson valueForKey:"Type"]) alloc] init];
for(NSDictionary *dict in [parsedJson valueForKey:"Properties")
{
[newControl setValue:[dict value] forKey:[dict Key]];
}
但是,如果系统无法创建类或者为不存在的属性设置值,则需要进行大量错误处理/ try {} catch {}。
JSON中声明的属性也需要引用类的属性。
用于此答案的一些参考文献:
how to instantiate an object of class from string in Objective-C? - StackOverflow Convert a string (“MyExampleClass”) into a class name (MyExampleClass) - StackOverflow