我有动态的tableview,其中很多部分是通过点击按钮在运行时添加的。
此按钮必须从上一节中的单元格发送数据(许多类型的自定义单元格)。
如何在上一节中获取单元格或索引路径的单元格?
我试图将这些单元格添加到cellForRowAtIndexPath
中的数组中,但我使用dequeueReusableCellWithIdentifier
来创建此单元格,因此这是有问题的。
编辑: 我的代码:
class ProcessViewController: UITableViewController, SWRevealViewControllerDelegate{
//this will be cell
struct field {
var name, type, id, hint, output, specialType:String
var selectOptions:NSMutableArray
var settings:NSArray
}
struct group {
var name:String
var fields:[field]
}
// this will be sections
struct block {
var groups:[group]
var id, name:String
}
var blocks:[block] = []
//fields in last (active) block
//var fields:[field] = []
//array of cells with some input
var cellsInTable:NSMutableArray = []
var cellWithCustomHeight:[NSIndexPath] = []
@IBOutlet var sendFormButton: UIButton!
var jsonData:NSDictionary?
@IBOutlet var menuButton: UIBarButtonItem!
var allfields:[field] = []
var numberOfOldCells = 0
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.barTintColor = UIColor(red: 62/255.0, green: 80/255.0, blue: 178/255.0, alpha: 1);
//print("json w srodku \(self.jsonData)")
if self.revealViewController() != nil {
self.revealViewController().delegate = self
menuButton.target = self.revealViewController()
menuButton.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
//print(self.jsonData)
let data = self.jsonData?.valueForKey("data") as! NSMutableDictionary
//set title of the screen
self.title = data.valueForKey("name") as? String
//hide button if process is completed
if(data.valueForKey("progress") as! Int == 1){
sendFormButton.hidden = true
//print("asdasd")
}
parseData(data)
//print("Bloki: \(self.blocks)")
}
func parseData(data:NSMutableDictionary){
self.cellsInTable = []
//blocks is the sections in tableView, fields is a cells and groups (for now)
let blocks = data.valueForKey("blocks") as! NSMutableArray
self.blocks = []
self.allfields = []
blocks.enumerateObjectsUsingBlock {obj, i, stop in
//print( obj.valueForKey("input"))
var inputs:NSMutableArray = []
//get inputs from current block, if input is only one it is dictionary in swift
if let kinputs = obj.valueForKey("input") as? NSArray{
inputs = NSMutableArray(array:kinputs)
}else{
inputs.addObject(obj.valueForKey("input")!)
}
inputs.removeLastObject()
var outputs:NSArray = []
if let koutputs = obj.valueForKey("output") as? NSArray{
outputs = koutputs
}
//print("wrona \(outputs) kracze razy: \(outputs.count)")
var tmpGroups:[group] = []
//inupt is a group
inputs.enumerateObjectsUsingBlock({input, j, stop in
//print("input w petli: \(input)")
if(input.valueForKey("fields") != nil){
let forms = NSMutableArray(array:input.valueForKey("fields") as! NSArray)
var tmpFields:[field] = []
let groupField:field = field(name:
input.valueForKey("name") as! String,
type: "group",
id: "0",
hint: input.valueForKey("name") as! String,
output: "",
specialType: "group",
selectOptions: [],
settings:[]
)
tmpFields.append(groupField)
forms.enumerateObjectsUsingBlock({fieldObj, k, stop in
let fromId = fieldObj.valueForKey("id") as! String
var output:String = ""
let tmpOutputs = outputs.valueForKey(fromId) as! NSArray
print(tmpOutputs)
print(output)
if tmpOutputs.count != 0{
if let _ = tmpOutputs[0] as? NSString{
output = tmpOutputs[0] as! String
}
} else {
//print(outputs.valueForKey(String(k)))
}
let selectOptions = NSMutableArray(array: fieldObj.valueForKey("selectOptions") as! NSArray)
//print("asdasdad\(fieldObj)")
let tmpField:field = field(
name: fieldObj.valueForKey("name") as! String,
type: fieldObj.valueForKey("type") as! String,
id: fromId,
hint: fieldObj.valueForKey("hint") as! String,
output:output,
specialType: fieldObj.valueForKey("specialType") as! String,
selectOptions: selectOptions,
settings:fieldObj.valueForKey("settings") as! NSArray
)
tmpFields.append(tmpField)
})
let tmpGroup:group = group(name: input.valueForKey("name") as! String, fields: tmpFields)
tmpGroups.append(tmpGroup)
}
})
let tmpBlock:block = block(groups: tmpGroups,
id: obj.valueForKey("id") as! String,
name: obj.valueForKey("name") as! String
)
self.blocks.append(tmpBlock)
}
}
func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition) {
UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.blocks[section].name as String
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return blocks.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var formsInGroup:Int = 0;
for group in self.blocks[section].groups{
formsInGroup += group.fields.count
}
return formsInGroup
//return blocks[section].fields.count
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(self.cellWithCustomHeight.contains(indexPath)){
return CGFloat(132)
} else {
return CGFloat(47)
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//geting fields in current group
self.allfields = []
for group in self.blocks[indexPath.section].groups {
self.allfields.appendContentsOf(group.fields)
}
print("bloki \(self.blocks.count), sekcje: \(indexPath.section)")
//print(self.allfields.count)
let cellType = self.allfields[indexPath.row].type as String
//print("row: \(indexPath.row), sections: \(indexPath.section)")
switch cellType {
case "group":
let cell = tableView.dequeueReusableCellWithIdentifier("groupCell", forIndexPath: indexPath) as! groupCell
cell.groupName.text = self.allfields[indexPath.row].name
return cell
case "text":
if(self.allfields[indexPath.row].specialType == "date"){
let cell = tableView.dequeueReusableCellWithIdentifier("datePickerCell", forIndexPath: indexPath) as! datePickerCell
cell.hint.text = self.allfields[indexPath.row].name as String
let output = self.allfields[indexPath.row].output as String
cell.selectionStyle = UITableViewCellSelectionStyle.None
self.cellWithCustomHeight.append(indexPath)
if(output != ""){
print(self.allfields[indexPath.row].name)
//print( " output: \(output)")
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-mm-yyyy"
let date = dateFormatter.dateFromString(self.allfields[indexPath.row].output)
cell.date.setDate(date!, animated: false)
cell.date.userInteractionEnabled = false
}
if !self.cellsInTable.containsObject(cell){
self.cellsInTable.addObject(cell)
}
setCellsToSend(indexPath.section)
return cell
}else{
let cell = tableView.dequeueReusableCellWithIdentifier("textCell", forIndexPath: indexPath) as! textCell
cell.hint.text = self.allfields[indexPath.row].name as String
let output = self.allfields[indexPath.row].output as String
cell.settings = self.allfields[indexPath.row].settings
if self.allfields[indexPath.row].specialType == "number" {
cell.input.keyboardType = UIKeyboardType.NumberPad
}
cell.input.text = ""
cell.selectionStyle = UITableViewCellSelectionStyle.None
if(output != ""){
//print(fields[indexPath.row].name)
//print(output)
cell.input.text = self.allfields[indexPath.row].output
cell.input.userInteractionEnabled = false
}
if !self.cellsInTable.containsObject(cell){
self.cellsInTable.addObject(cell)
} else {
print("kuuuuuurwa \(self.allfields[indexPath.row].name)")
}
setCellsToSend(indexPath.section)
return cell
}
case "checkbox":
let cell = tableView.dequeueReusableCellWithIdentifier("checkBoxCell", forIndexPath: indexPath) as! checkBoxCell
cell.selections = self.allfields[indexPath.row].selectOptions
cell.hint.text = self.allfields[indexPath.row].name as String
cell.settings = self.allfields[indexPath.row].settings
cell.indexPath = indexPath
cell.selectionStyle = UITableViewCellSelectionStyle.None
if !self.cellsInTable.containsObject(cell){
self.cellsInTable.addObject(cell)
} else {
print("kuuuuuurwa \(self.allfields[indexPath.row].name)")
}
setCellsToSend(indexPath.section)
return cell
default:
let cell = tableView.dequeueReusableCellWithIdentifier("unknownCell", forIndexPath: indexPath)
cell.textLabel?.text = "niezaimplementowany typ pola: \(cellType)"
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
}
func setCellsToSend(sectionInTable:Int){
if(sectionInTable == self.blocks.count-2){
print("sekcja \(sectionInTable)")
self.numberOfOldCells = self.cellsInTable.count
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "showCheckBox"){
let checkBoxController = segue.destinationViewController as! CheckBoxController
let cell = sender as! checkBoxCell
//print(cell.settings)
checkBoxController.selections = cell.selections
checkBoxController.multiple = checkboxMultiValue(cell.settings)
checkBoxController.indexPath = cell.indexPath
checkBoxController.selected = cell.output
}
}
func checkboxMultiValue(settings:NSArray)->Bool{
var boolToReturn:Bool = false
settings.enumerateObjectsUsingBlock({obj, i, end in
if(obj.valueForKey("name") as! String == "multi_values"){
if( obj.valueForKey("checked") as! String == "multi_values"){
boolToReturn = true;
}
}
//print(i)
})
return boolToReturn
}
@IBAction func saveSelectedSelections(segue: UIStoryboardSegue) {
let checkBoxController = segue.sourceViewController as! CheckBoxController
let selectedRowsPath = checkBoxController.tableView.indexPathsForSelectedRows
var output:[String] = []
if(selectedRowsPath?.count > 0){
for rowPath in selectedRowsPath!{
let cell = checkBoxController.tableView.cellForRowAtIndexPath(rowPath) as! selectionCell
output.append(cell.nameLabel.text! as String)
}
}
let cell = self.tableView.cellForRowAtIndexPath(checkBoxController.indexPath!) as! checkBoxCell
cell.output = output
}
@IBAction func sendForm(sender: AnyObject) {
print("\(self.numberOfOldCells) i \(self.cellsInTable.count)")
var postData:Dictionary<Int, AnyObject> = [:]
var post = ""
var iterator:Int = 0
for var i = self.numberOfOldCells; i < self.cellsInTable.count; ++i{
if let cellText = self.cellsInTable[i] as? textCell{
//print("cellText \(cellText.input.text as String!)")
postData[iterator] = cellText.input.text as AnyObject!
post += "\(iterator):{'\(cellText.input.text! as String)'}&"
iterator++
} else if let cellCheckBox = self.cellsInTable[i] as? checkBoxCell{
//print(cellCheckBox.output)
let checkBoxOutput = cellCheckBox.output
var data:String = ""
for var i = 0; i < checkBoxOutput.count; ++i {
if ( i == 0) {
data += checkBoxOutput[i]
}else{
data += ";\(checkBoxOutput[i])"
}
}
post += "\(iterator):{'\(data)'}&"
postData[iterator] = data as AnyObject!
//postData.append(data as String!)
iterator++
}else if let cellDate = self.cellsInTable[i] as? datePickerCell{
//print(cellDate.date.date)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-mm-yyyy"
let date = dateFormatter.stringFromDate(cellDate.date.date)
postData[iterator] = date as AnyObject!
post += "\(iterator):{'\(date)'}&"
//postData.append(date as String!)
iterator++
}
}
//print("Post data:\(postData)")
//getNewBlock(NSKeyedArchiver.archivedDataWithRootObject(postData))
print(post)
getNewBlock(post.dataUsingEncoding(NSASCIIStringEncoding)!)
}
func getNewBlock(postData:NSData){
//print("Post data jako nsdata:\(postData)")
//var blockId = "a"
let blockId = blocks.last!.id
let url:NSURL = NSURL(string: "http://app.proces.io/Cloud/?Systems/Proces/Process/Block/makeAction/id-\(blockId)")!
print(url)
let postLength:NSString = String( postData.length )
let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {
urlData, response, error in
var requestData: NSDictionary?
do{
requestData = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as? NSDictionary
//print(requestData)
if ( requestData != nil ) {
let success:NSInteger = requestData!.valueForKey("success") as! NSInteger
if(success == 1)
{
//print(self.blocks.count)
let data = requestData!.valueForKey("process") as! NSMutableDictionary
//print(self.allfields)
//self.numberOfOldCells = self.cellsInTable.count
//print(self.blocks)
self.allfields = []
self.parseData(data)
//print(self.blocks.count)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
} else {
print("cos poszlo nie tak \(requestData?.valueForKey("validation_errors")), values: \(requestData?.valueForKey("values"))")
}
}
} catch let error as NSError{
print("cos poszlo nie tak: \(error)")
}
}
task.resume()
}
编辑2:最小版本,但有一些解释:
class ProcessViewController: UITableViewController, SWRevealViewControllerDelegate{
//this will be cell
struct field {
var name, type, id, hint, output, specialType:String
var selectOptions:NSMutableArray
var settings:NSArray
}
struct group {
var name:String
var fields:[field]
}
// this will be sections
struct block {
var groups:[group]
var id, name:String
}
var blocks:[block] = []
var jsonData:NSDictionary?
@IBOutlet var menuButton: UIBarButtonItem!
var allfields:[field] = []
var numberOfOldCells = 0
override func viewDidLoad() {
super.viewDidLoad()
parseData(data)
}
func parseData(data:NSMutableDictionary){
//in this function i have a parsing data from json, whitch create me array of blocks (global variable "blocks")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.blocks[section].name as String
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return blocks.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var formsInGroup:Int = 0;
for group in self.blocks[section].groups{
formsInGroup += group.fields.count
}
return formsInGroup
//return blocks[section].fields.count
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(self.cellWithCustomHeight.contains(indexPath)){
return CGFloat(132)
} else {
return CGFloat(47)
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//geting fields in current group
self.allfields = []
for group in self.blocks[indexPath.section].groups {
self.allfields.appendContentsOf(group.fields)
}
let cellType = self.allfields[indexPath.row].type as String
switch cellType {
case "group":
let cell = tableView.dequeueReusableCellWithIdentifier("groupCell", forIndexPath: indexPath) as! groupCell
cell.groupName.text = self.allfields[indexPath.row].name
return cell
case "text":
if(self.allfields[indexPath.row].specialType == "date"){
let cell = tableView.dequeueReusableCellWithIdentifier("datePickerCell", forIndexPath: indexPath) as! datePickerCell
cell.hint.text = self.allfields[indexPath.row].name as String
let output = self.allfields[indexPath.row].output as String
cell.selectionStyle = UITableViewCellSelectionStyle.None
self.cellWithCustomHeight.append(indexPath)
if(output != ""){
print(self.allfields[indexPath.row].name)
//print( " output: \(output)")
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-mm-yyyy"
let date = dateFormatter.dateFromString(self.allfields[indexPath.row].output)
cell.date.setDate(date!, animated: false)
cell.date.userInteractionEnabled = false
}
return cell
}else{
let cell = tableView.dequeueReusableCellWithIdentifier("textCell", forIndexPath: indexPath) as! textCell
cell.hint.text = self.allfields[indexPath.row].name as String
let output = self.allfields[indexPath.row].output as String
cell.settings = self.allfields[indexPath.row].settings
if self.allfields[indexPath.row].specialType == "number" {
cell.input.keyboardType = UIKeyboardType.NumberPad
}
cell.input.text = ""
cell.selectionStyle = UITableViewCellSelectionStyle.None
if(output != ""){
cell.input.text = self.allfields[indexPath.row].output
cell.input.userInteractionEnabled = false
}
return cell
}
case "checkbox":
let cell = tableView.dequeueReusableCellWithIdentifier("checkBoxCell", forIndexPath: indexPath) as! checkBoxCell
cell.selections = self.allfields[indexPath.row].selectOptions
cell.hint.text = self.allfields[indexPath.row].name as String
cell.settings = self.allfields[indexPath.row].settings
cell.indexPath = indexPath
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
default:
let cell = tableView.dequeueReusableCellWithIdentifier("unknownCell", forIndexPath: indexPath)
cell.textLabel?.text = "niezaimplementowany typ pola: \(cellType)"
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
}
@IBAction func sendForm(sender: AnyObject) {
// in this function i must send data from cells in last section and add new section on the basis of request
}