可扩展标头更改自定义Xib标签

问题描述

我有一个带有可扩展/可折叠标头以及子项的表。效果很好。

我有一个标题一个标题(在行中选择文本之前,文本不会显示)。我想通过选择子标题项来更改子标题。在示例中,我单击sub1,并且子标题文本更改为sub1

enter image description here

标题和子标题已在viewForHeaderInSection中设置

    func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView?  {
    
    
     let headerView = tableView.dequeueReusableheaderfooterView(withIdentifier: "DemoHeaderView") as! DemoHeaderView
    
       headerView.mylabeltitle.text = self.sectionNames[section] as? String
       headerView.sublabel.text = "sub heading"

这是代码

import UIKit

class AddMeditationViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate,DemoHeaderViewDelegate {
func toggleSelection(header: DemoHeaderView,section: Int) {
    var t = 9
}


@IBOutlet weak var tableview: UITableView!




   let kHeaderSectionTag: Int = 6900;
   var lastSelection: NSIndexPath!

   
   var label = UILabel()
   var expandedSectionHeaderNumber: Int = -1
   var expandedSectionHeader: UITableViewheaderfooterView!
   var sectionItems: Array<Any> = []
   var sectionNames: Array<Any> = []
   var AVoice: [String] = []
   var selectedindexPath: IndexPath!

  var gText = ""
  var sTime = ""
  var name = ""
  var aType = ""


   override func viewDidLoad() {
       super.viewDidLoad()
    
    let headerNib = UINib.init(nibName: "DemoHeaderView",bundle: Bundle.main)
    tableview.register(headerNib,forheaderfooterViewReuseIdentifier: "DemoHeaderView")

    selectedindexPath = IndexPath(row: -1,section: -1)
       

    sectionNames = [ "heading 1","heading 2","heading 3","heading 4"];
              sectionItems = [ ["sub 1","sub 2","sub 3"],["sub 1","sub 2"],"sub 3","sub 4","sub 5","sub 6","sub 7"],[" "]
                             ];
       

    
       self.tableview!.tableFooterView = UIView()
   }
   
   override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)
       
   }

   override func didReceiveMemoryWarning() {
       super.didReceiveMemoryWarning()
   }


   func numberOfSections(in tableView: UITableView) -> Int {
       if sectionNames.count > 0 {
           tableView.backgroundView = nil
           return sectionNames.count
       } else {
       }
       return 0
   }
   
   func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
       if (self.expandedSectionHeaderNumber == section) {
           let arrayOfItems = self.sectionItems[section] as! NSArray
           return arrayOfItems.count;
       } else {
           return 0;
       }
   }
   

func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell",for: indexPath) as UITableViewCell
           let section = self.sectionItems[indexPath.section] as! NSArray
           //let section2 = self.sectionNames[section] as? String
           cell.textLabel?.textColor = UIColor.black
           cell.textLabel?.text = section[indexPath.row] as? String
    
        let headerView = tableView.dequeueReusableheaderfooterView(withIdentifier: "DemoHeaderView") as! DemoHeaderView

        
        var headerNumber = self.expandedSectionHeaderNumber
      
        let sectionheading = self.sectionNames[indexPath.section] as? String
        
        if headerNumber == 0 {
         var type = section[indexPath.row] as? String
            
          if(type == aType){
               cell.accessoryType = .checkmark
             } else{
                cell.accessoryType = .none
              }
        }
        
       if headerNumber == 1 {
            var voice = section[indexPath.row] as? String
            if(voice == gText){
                cell.accessoryType = .checkmark
             } else{
                cell.accessoryType = .none
                }
        }
        
        
        if headerNumber == 2 {
            var sNow = section[indexPath.row] as? String
            if(sNow == sTime){
                cell.accessoryType = .checkmark
            } else{
                cell.accessoryType = .none
            }
        }
        
        
      
           var s = section[indexPath.row] as? String
        
         let myView = UITextField(frame: CGRect(x: 20,y: 0,width: 300,height: 20))
        
        if s == " " {
            
            if(name != ""){
                myView.text = name
            }else{
                myView.placeholder = "Enter text here"
            }
     
            myView.font = UIFont.systemFont(ofSize: 15)
            myView.translatesAutoresizingMaskIntoConstraints = false
            myView.delegate = self
            myView.returnKeyType = .done
            cell.addSubview(myView)
            
            NSLayoutConstraint(item: myView,attribute: NSLayoutAttribute.height,relatedBy: NSLayoutRelation.equal,toItem: nil,attribute: NSLayoutAttribute.notAnAttribute,multiplier: 1,constant: 40).isActive = true
            NSLayoutConstraint(item: myView,attribute: NSLayoutConstraint.Attribute.centerX,relatedBy: NSLayoutConstraint.Relation.equal,toItem: view,constant: 0).isActive = true
            NSLayoutConstraint(item: myView,attribute: NSLayoutConstraint.Attribute.width,attribute: NSLayoutConstraint.Attribute.notAnAttribute,constant: 350).isActive = true
    
        } else{
            for view in cell.subviews  as! [UIView]{
                   if let label = view as? UITextField {
                       label.removeFromSuperview()
                   }
               }
          
        }
        
    return cell
}
    
func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView? {
    
    
     let headerView = tableView.dequeueReusableheaderfooterView(withIdentifier: "DemoHeaderView") as! DemoHeaderView
    
       headerView.mylabeltitle.text = self.sectionNames[section] as? String
       headerView.sublabel.text = "sub heading"

      return headerView
        
    
    
}
    
   func tableView(_ tableView: UITableView,heightForHeaderInSection section: Int) -> CGFloat {
       return 74.0;
   }
   
   func tableView(_ tableView: UITableView,heightForFooterInSection section: Int) -> CGFloat{
       return 0;
   }
   
   func tableView(_ tableView: UITableView,willdisplayHeaderView view: UIView,forSection section: Int) {
       //recast your view as a UITableViewheaderfooterView
       let header: UITableViewheaderfooterView = view as! UITableViewheaderfooterView
       header.contentView.backgroundColor = UIColor.colorWithHexString(hexStr: "#0075d4")
    
    let topBorderView = UIView(frame: CGRect(x: 0,width: view.frame.size.width,height: 1))
    topBorderView.backgroundColor = UIColor.black
    header.addSubview(topBorderView)
  
       header.textLabel?.textColor = UIColor.white
       
       if let viewWithTag = self.view.viewWithTag(kHeaderSectionTag + section) {
           viewWithTag.removeFromSuperview()
       }
       let headerFrame = self.view.frame.size
       let theImageView = UIImageView(frame: CGRect(x: headerFrame.width - 32,y: 13,width: 18,height: 18));
       theImageView.image = UIImage(named: "Chevron-Dn-Wht")
       theImageView.tag = kHeaderSectionTag + section
       header.addSubview(theImageView)

       header.tag = section
       let headerTapGesture = UITapGestureRecognizer()
       headerTapGesture.addTarget(self,action: #selector(AddMeditationViewController.sectionHeaderWasTouched(_:)))
       header.addGestureRecognizer(headerTapGesture)
   }
   

   func tableView(_ tableView: UITableView,diddeselectRowAt indexPath: IndexPath) {
       tableView.deselectRow(at: indexPath,animated: true)
                                                    
    let section = self.sectionItems[indexPath.section] as! NSArray
    var t = section[indexPath.row] as? String

  //  selectedArray.removeAll(where: { $0 == t } )
    
   }


func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
    
    self.selectedindexPath = indexPath
    //self.sections[indexPath.section].SubTiltle = "l"
   //section[indexPath.section].SubTiltle = tableView.cellForRowAt(at: indexPath).textLabel?.text
      
    if self.lastSelection != nil {
        self.tableview.cellForRow(at: self.lastSelection as IndexPath)?.accessoryType = .none
    }

     let headerView = tableView.dequeueReusableheaderfooterView(withIdentifier: "DemoHeaderView") as! DemoHeaderView
    let section = self.sectionItems[indexPath.section] as! NSArray
    var sectionheading = self.sectionNames[indexPath.section] as? String
    var subSectionName = (section[indexPath.row] as? String)!
    var headerNumber = self.expandedSectionHeaderNumber
    
   
    
    self.selectedindexPath = indexPath
  
  //  headerView.sublabel.text = subSectionName
       //headerView.sec.text = subSectionName
    
  //  let headerView2 = tableView.dequeueReusableheaderfooterView(withIdentifier: "DemoHeaderView") as! DemoHeaderView
         //headerView2.sublabel.text = subSectionName
            

    self.lastSelection = indexPath as NSIndexPath
    self.selectedindexPath = indexPath
    
    tableView.beginUpdates()
  tableView.reloadSections([indexPath.section],with: .automatic)
    tableView.endUpdates()

    self.tableview.deselectRow(at: indexPath,animated: true)
}


func textFieldShouldReturn(_ textField: UITextField) -> Bool {   //delegate method
   textField.resignFirstResponder()
    self.alarmName = (textField.text as String!)
   return true
}
   
   // MARK: - Expand / Collapse Methods
   
   @objc func sectionHeaderWasTouched(_ sender: UITapGestureRecognizer) {
       let headerView = sender.view as! UITableViewheaderfooterView
       let section    = headerView.tag
       let eImageView = headerView.viewWithTag(kHeaderSectionTag + section) as? UIImageView
       
       if (self.expandedSectionHeaderNumber == -1) {
           self.expandedSectionHeaderNumber = section
           tableViewExpandSection(section,imageView: eImageView!)
       } else {
           if (self.expandedSectionHeaderNumber == section) {
               tableViewCollapeSection(section,imageView: eImageView!)
           } else {
               let cImageView = self.view.viewWithTag(kHeaderSectionTag + self.expandedSectionHeaderNumber) as? UIImageView
               tableViewCollapeSection(self.expandedSectionHeaderNumber,imageView: cImageView!)
               tableViewExpandSection(section,imageView: eImageView!)
           }
       }
   }
   
   func tableViewCollapeSection(_ section: Int,imageView: UIImageView) {
       let sectionData = self.sectionItems[section] as! NSArray
       
       self.expandedSectionHeaderNumber = -1;
       if (sectionData.count == 0) {
           return;
       } else {
           UIView.animate(withDuration: 0.4,animations: {
               imageView.transform = CGAffineTransform(rotationAngle: (0.0 * CGFloat(Double.pi)) / 180.0)
           })
           var indexesPath = [IndexPath]()
           for i in 0 ..< sectionData.count {
               let index = IndexPath(row: i,section: section)
               indexesPath.append(index)
           }
           self.tableview!.beginUpdates()
           self.tableview!.deleteRows(at: indexesPath,with: UITableViewRowAnimation.fade)
           self.tableview!.endUpdates()
       }
   }
   
   func tableViewExpandSection(_ section: Int,imageView: UIImageView) {
       let sectionData = self.sectionItems[section] as! NSArray
       
       if (sectionData.count == 0) {
           self.expandedSectionHeaderNumber = -1;
           return;
       } else {
           UIView.animate(withDuration: 0.4,animations: {
               imageView.transform = CGAffineTransform(rotationAngle: (180.0 * CGFloat(Double.pi)) / 180.0)
           })
           var indexesPath = [IndexPath]()
           for i in 0 ..< sectionData.count {
               let index = IndexPath(row: i,section: section)
               indexesPath.append(index)
           }
           self.expandedSectionHeaderNumber = section
           self.tableview!.beginUpdates()
           self.tableview!.insertRows(at: indexesPath,with: UITableViewRowAnimation.fade)
           self.tableview!.endUpdates()
       }
   }

  }

在选择标题行时,可以做些什么来设置子标题? 我自己不知所措。在此先感谢,因为我真的被困住了并且要放弃

解决方法

如果您的数据模型包含节标题的功能,那么更改节标题以响应单元格的选择将很简单。您只需更改模型的功能并重新加载数据:

enter image description here

这当然比您的表简单得多,但是原理是完全相同的。我的数据模型同时包含部分数据和行数据:

struct Row {
    var name = ""
}
struct Section {
    var subtitle = ""
    var rowData = [Row]()
}
var model = [Section]()

因此,当用户点击某个单元格时,我会通过更改该部分的subtitle并重新加载数据来进行响应:

func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
    let name = model[indexPath.section].rowData[indexPath.row].name
    model[indexPath.section].subtitle = name
    tableView.reloadData()
}

(请注意,重新加载表会丢失单元格上的选择指示。我已经解决了这个问题。但是为了简单起见,我省略了该代码,只是显示了表如何工作的基本原理。)