从上一节uitableview获取单元格

时间:2015-12-29 12:27:34

标签: ios swift uitableview swift2

我有动态的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
}

0 个答案:

没有答案