Swift / iOS:折叠UITableView中的一个部分

时间:2016-07-19 09:58:44

标签: ios swift uitableview

我有一个UITableView,大约有5个部分。我试图通过单击按钮来折叠并展开其中一个部分,但我发现一个问题,即我使用的代码也导致其他部分的折叠。具体来说,所有可见部分的第一行都是折叠的。

以下是代码的样子:

func didClickSectionCollapseButton() {
    shouldCollapseSection = !shouldCollapseSection
    tableView.beginUpdates()
    tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: .Fade)
    tableView.endUpdates()
}

这是numberOfRowInSection方法:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
    case 0:
        return 1
    case 1:
        // collapsible section
        return shouldCollapse ? 0 : collapsibleSectionCellCount
    case 2:
        return getCellCount()
    case 3:
        return 1
    case 4:
        return 1
    default:
        return 0
    }
}

这里有什么我想念的吗?我已经完成了各种教程和问题,但我还没有找到解决方案。

5 个答案:

答案 0 :(得分:2)

您好,经过大量研究,我找到了一个使用情节提要对我非常有用的解决方案。

storyboard setup

查看控制器代码:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tblView: UITableView!

var sections = ["section1","section2","section3"]

var cells = ["cell1","cell2","cell3","cell4"]

var selectedIndx = -1

var thereIsCellTapped = false

override func viewDidLoad() {
    super.viewDidLoad()
    tblView.reloadData()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    switch section {
    case 0:
        return 2
    case 1:
        return 3
    default:
        return 4
    }
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 50
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == selectedIndx && thereIsCellTapped{
        return 50
    }else{
        return 0
    }
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerCell = tableView.dequeueReusableCell(withIdentifier: "SectionTableViewCell") as! SectionTableViewCell
    headerCell.lblHeader.text = sections[section]
    headerCell.btnSelection.tag = section
    headerCell.btnSelection.addTarget(self, action: #selector(ViewController.btnSectionClick(sender:)), for: .touchUpInside)
    return headerCell
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandeTableViewCell") as! ExpandeTableViewCell
    cell.lblCell.text = cells[indexPath.row]
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print(indexPath.section)
}

@objc func btnSectionClick(sender:UIButton!){
    print("selected index",sender.tag)
    if selectedIndx != sender.tag {
        self.thereIsCellTapped = true
        self.selectedIndx = sender.tag
    }
    else {
        // there is no cell selected anymore
        self.thereIsCellTapped = false
        self.selectedIndx = -1
    }
    tblView.reloadData()
}
}

如果您不想对同一选择进行选择和取消选择,请参见下面的代码。

@objc func btnSectionClick(sender:UIButton!){
    print("selected index",sender.tag)

    selectedIndx = sender.tag

    tblView.reloadData()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == selectedIndx{
        return 50
    }else{
        return 0
    }
}

它对我有用,我参考了很多答案并做到了。希望对您有帮助。

答案 1 :(得分:1)

我很久以前就使用过这段代码,它在Swift 2.3中。我不知道这是否有帮助,但值得一提。

class DriversVC : UIViewController , UITableViewDelegate , UITableViewDataSource {
    //-----------------------------------------------------------------------
    //MARK: - Outlets

    @IBOutlet var tvDriverList: UITableView! {
        didSet {
            tvDriverList.delegate = self
            tvDriverList.dataSource = self
        }
    }

    //-----------------------------------------------------------------------
    //MARK: - Variables

    var arrDriverList : NSArray? //Section data
    var arrWorkerList : NSArray? //Section data
    var collapseSection0 : Bool = false
    var collapseSection1 : Bool = false
    var btnSection0Headder : UIButton = UIButton()
    var btnSection1Headder : UIButton = UIButton()

    //------------------------------------------------------

    func btnSection0HeadderTapped () {
        if collapseSection0 {
            collapseSection0 = false
        } else {
            collapseSection0 = true
        }
        tvDriverList.reloadSections(NSIndexSet(index: 0), withRowAnimation: UITableViewRowAnimation.Fade)
    }

    //------------------------------------------------------

    func btnSection1HeadderTapped () {
        if collapseSection1 {
            collapseSection1 = false
        } else {
            collapseSection1 = true
        }
        tvDriverList.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Fade)
    }

    //-----------------------------------------------------------------------------------
    //MARK:- Table delegate and data sources

    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50
    }

    //------------------------------------------------------

    func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 20
    }

    //------------------------------------------------------

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, height: 50))
        view.backgroundColor = OrangeColor //Set your color
        let lbl = UILabel(frame: CGRect(x: 10, y: 5, width: UIScreen.mainScreen().bounds.width - 20, height: 40))
        lbl.font = UIFont(name: OpenSansRegular, size: 18) //Set your font
        lbl.textColor = UIColor.whiteColor()
        view.addSubview(lbl)
        if section == 0 {
            lbl.text = "D R I V E R"
            btnSection0Headder.addTarget(self, action: #selector(self.btnSection0HeadderTapped), forControlEvents: .TouchUpInside)
            btnSection0Headder.frame = view.frame
            view.addSubview(btnSection0Headder) // uncomment to apply collapse effect
        } else {
            lbl.text = "W O R K E R"
            btnSection1Headder.addTarget(self, action: #selector(self.btnSection1HeadderTapped), forControlEvents: .TouchUpInside)
            btnSection1Headder.frame = view.frame
            view.addSubview(btnSection1Headder) // uncomment to apply collapse effect
        }
        return view
    }

    //------------------------------------------------------

    func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return UIView()
    }

    //------------------------------------------------------

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        if arrWorkerList != nil && arrWorkerList?.count > 0 {
            return 2
        }
        return 1
    }

    //------------------------------------------------------

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            if !collapseSection0 {
                guard arrDriverList != nil else {return 0}
                return arrDriverList!.count
            } else {
                return 0
            }
        } else {
            if !collapseSection1 {
                guard arrWorkerList != nil else {return 0}
                return arrWorkerList!.count
            } else {
                return 0
            }
        }
    }

    //------------------------------------------------------

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCellWithIdentifier(NSStringFromClass(DriversCVC).componentsSeparatedByString(".").last!) as? DriversCVC else { fatalError("unexpected DriversCVC dequeued from tableView") }
        cell.superViewController = self
        if indexPath.section == 0 {
            guard let dict = arrDriverList![indexPath.row] as? NSDictionary else {return cell}
            cell.data = dict
        } else {
            guard let dict = arrWorkerList![indexPath.row] as? NSDictionary else {return cell}
            cell.data = dict
        }
        cell.setup()
        return cell
    }

    //----------------------------------------------------------------------
    //MARK: - Action Method

    @IBAction func btnBackTapped(sender: AnyObject) {
        guard self.navigationController != nil else {
            self.dismissViewControllerAnimated(true, completion: nil)
            return
        }
        guard self.navigationController?.popViewControllerAnimated(true) != nil else {
            guard self.navigationController?.dismissViewControllerAnimated(true, completion: nil) != nil else {
                AppDelegate.sharedInstance().loginCall()
                return
            }
            return
        }
    }

    //-----------------------------------------------------------------------
    //MARK: - View Life Cycle Methods

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    //----------------------------------------------------------------------

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        setUpVC()
    }

    //----------------------------------------------------------------------

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
    } }

答案 2 :(得分:0)

您可以使用:

func didClickSectionCollapseButton() {
    shouldCollapseSection = !shouldCollapseSection
    tableView.beginUpdates()
    tableView.deleteSections(NSIndexSet(index: 1), withRowAnimation: .Fade)
    tableView.endUpdates()
}

答案 3 :(得分:0)

如果您想要后续插入,删除和选择操作,

beginUpdates()endUpdates()成对配对,但reloadData则不然。 在您的代码中,移除beginUpdates()endUpdates()

答案 4 :(得分:0)

按钮操作中设置的shouldCollapseSection变量与numberOfRowsInSection方法中使用的shouldCollapse变量之间是否存在差异?

您似乎没有在数据源代理中设置相同的变量。