我有一个像下面的手风琴菜单的例子,我想做一个嵌套菜单(例如菜单中的菜单),它主要与可扩展的tableViews有关,但我需要在expandable tableView或任何其他解决方案中展开 这是来自互联网的代码,它执行单步手风琴,我需要嵌套的手风琴: PS:我的项目有点沉重,所以我不想添加其他库,也许只是一个类,非常感谢你提前
// Created by ingdanni on 05/11/15.
// Copyright (c) 2015 ManaguaIO. All rights reserved.
//
import UIKit
struct Section {
let title: String
let rows: [String]
var selected: Bool
}
class ViewController: UIViewController {
let CellIdentifier = "Cell"
var sections = [Section]()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Setup Sections
sections.append(Section(title: "A", rows: ["1","2","3","4"], selected: false))
sections.append(Section(title: "B", rows: ["5","6","7","8"], selected: false))
sections.append(Section(title: "C", rows: ["9","10"], selected: false))
// Set cell reuse identifier
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: CellIdentifier)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
if sections[section].selected
{
return sections[section].rows.count
}
return 0
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ""
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 1
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if sections[indexPath.section].selected {
return 50
}
return 2
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40))
headerView.backgroundColor = UIColor.lightGrayColor()
headerView.tag = section
let headerString = UILabel(frame: CGRect(x: 10, y: 10, width: tableView.frame.size.width-10, height: 30)) as UILabel
headerString.text = sections[section].title
headerView.addSubview(headerString)
let headerTapped = UITapGestureRecognizer(target: self, action:"sectionHeaderTapped:")
headerView.addGestureRecognizer(headerTapped)
return headerView
}
func sectionHeaderTapped(recognizer: UITapGestureRecognizer) {
let indexPath = NSIndexPath(forRow: 0, inSection:(recognizer.view?.tag as Int!)!)
if indexPath.row == 0 {
sections[indexPath.section].selected = !sections[indexPath.section].selected
//reload specific section animated
let range = NSMakeRange(indexPath.section, 1)
let sectionToReload = NSIndexSet(indexesInRange: range)
self.tableView.reloadSections(sectionToReload, withRowAnimation:UITableViewRowAnimation.Fade)
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = self.tableView.dequeueReusableCellWithIdentifier(CellIdentifier, forIndexPath: indexPath)
cell.textLabel?.text = sections[indexPath.section].rows[indexPath.row]
return cell
}
}
答案 0 :(得分:0)
实际上在经历了如何制作嵌套手风琴之后,我找到了答案,但后来又决定不将它用于来自服务器和JSON Web服务的动态数据(例如,当你有嵌套的树形菜单时,它具有动态结构来自因此我在一个页面中使用了每个类别并定义了三个级别并使用了segue,但是如果你需要创建这样的菜单,我发现制作NSObject的技巧就像在这里定义每个单元格的属性一样:
import UIKit
class AMPGenericObject: NSObject {
var name:String?
var parentName:String?
var canBeExpanded = false // Bool to determine whether the cell can be expanded
var isExpanded = false // Bool to determine whether the cell is expanded
var level:Int? // Indendation level of tabelview
var type:Int?
var children:[AMPGenericObject] = []
enum ObjectType:Int{
case OBJECT_TYPE_REGION = 0
case OBJECT_TYPE_LOCATION
case OBJECT_TYPE_USERS
}
}
这里是viewController:
import UIKit
class AMPTableViewController: UITableViewController {
var dataArray:[AMPGenericObject] = []
var indendationLevel:Int = 0
var indendationWidth:CGFloat = 20.0
override func viewDidLoad() {
super.viewDidLoad()
for var i=0; i<=10; i++ {
}
for i in 0..<10 {
let prod = AMPGenericObject()
prod.name = "Region \(i)"
prod.parentName = ""
prod.isExpanded = false
prod.level = 0;
prod.type = 0;
// Randomly assign canBeExpanded status
let rem = i % 2
if(rem == 0)
{
prod.canBeExpanded = true;
}
else
{
prod.canBeExpanded = false;
}
dataArray.append(prod)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return dataArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let obj = dataArray[indexPath.row]
// All optionals are ensured to have values, so we can safely unwrap
cell.textLabel!.text = obj.name!;
cell.detailTextLabel!.text = obj.parentName!;
cell.indentationLevel = obj.level!;
cell.indentationWidth = indendationWidth;
// Configure the cell...
// Show disclosure only if the cell can expand
if(obj.canBeExpanded)
{
cell.accessoryView = self.viewForDisclosureForState(obj.isExpanded)
}
else
{
//cell.accessoryType = UITableViewCellAccessoryNone;
cell.accessoryView = nil;
}
return cell
}
func viewForDisclosureForState(isExpanded:Bool)->UIView{
var imageName:String = ""
if(isExpanded)
{
imageName = "ArrowD_blue";
}
else
{
imageName = "ArrowR_blue";
}
let view = UIView(frame: CGRectMake(0, 0, 40, 40))
let imageView = UIImageView(image: UIImage(named: imageName))
imageView.frame = CGRectMake(0, 6, 24, 24)
view.addSubview(imageView)
return view
}
func fetchChildrenforParent(parentProduct:AMPGenericObject){
// If canBeExpanded then only we need to create child
if(parentProduct.canBeExpanded)
{
// If Children are already added then no need to add again
if(parentProduct.children.count > 0){
return
}
// The children property of the parent will be filled with this objects
// If the parent is of type region, then fetch the location.
if (parentProduct.type == 0) {
for i in 0..<10
{
let prod = AMPGenericObject()
prod.name = "Location \(i)"
prod.level = parentProduct.level! + 1;
prod.parentName = "Child \(i) of Level \(prod.level!)"
// This is used for setting the indentation level so that it look like an accordion view
prod.type = 1 //OBJECT_TYPE_LOCATION;
prod.isExpanded = false;
if(i % 2 == 0)
{
prod.canBeExpanded = true
}
else
{
prod.canBeExpanded = false
}
parentProduct.children.append(prod)
}
}
// If tapping on Location, fetch the users
else{
for i in 0..<10
{
let prod = AMPGenericObject()
prod.name = "User \(i)"
prod.level = parentProduct.level! + 1;
prod.parentName = "Child \(i) of Level \(prod.level!)"
// This is used for setting the indentation level so that it look like an accordion view
prod.type = 1 //OBJECT_TYPE_LOCATION;
prod.isExpanded = false;
// Users need not expand
prod.canBeExpanded = false
parentProduct.children.append(prod)
}
}
}
}
func collapseCellsFromIndexOf(prod:AMPGenericObject,indexPath:NSIndexPath,tableView:UITableView)->Void{
// Find the number of childrens opened under the parent recursively as there can be expanded children also
let collapseCol = self.numberOfCellsToBeCollapsed(prod)
// Find the end index by adding the count to start index+1
let end = indexPath.row + 1 + collapseCol
// Find the range from the parent index and the length to be removed.
let collapseRange = Range(start: indexPath.row+1, end: end)
// Remove all the objects in that range from the main array so that number of rows are maintained properly
dataArray.removeRange(collapseRange)
prod.isExpanded = false
// Create index paths for the number of rows to be removed
var indexPaths = [NSIndexPath]()
for i in 0..<collapseRange.count {
indexPaths.append(NSIndexPath.init(forRow: collapseRange.startIndex+i, inSection: 0))
}
// Animate and delete
tableView.deleteRowsAtIndexPaths(indexPaths, withRowAnimation: .Left)
}
func expandCellsFromIndexOf(prod:AMPGenericObject,indexPath:NSIndexPath,tableView:UITableView)->Void{
// Create dummy children
self.fetchChildrenforParent(prod)
// Expand only if children are available
if(prod.children.count>0)
{
prod.isExpanded = true
var i = 0;
// Insert all the child to the main array just after the parent
for prodData in prod.children {
dataArray.insert(prodData, atIndex: indexPath.row+i+1)
i++;
}
// Find the range for insertion
let expandedRange = NSMakeRange(indexPath.row, i)
var indexPaths = [NSIndexPath]()
// Create index paths for the range
for i in 0..<expandedRange.length {
indexPaths.append(NSIndexPath.init(forRow: expandedRange.location+i+1, inSection: 0))
}
// Insert the rows
tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Left)
}
}
func numberOfCellsToBeCollapsed(prod:AMPGenericObject)->Int{
var total = 0
if(prod.isExpanded)
{
// Set the expanded status to no
prod.isExpanded = false
let child = prod.children
total = child.count
// traverse through all the children of the parent and get the count.
for prodData in child{
total += self.numberOfCellsToBeCollapsed(prodData)
}
}
return total
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let prod = dataArray[indexPath.row]
let selectedCell = tableView.cellForRowAtIndexPath(indexPath)
if(prod.canBeExpanded)
{
if(prod.isExpanded){
self.collapseCellsFromIndexOf(prod, indexPath: indexPath, tableView: tableView)
selectedCell?.accessoryView = self.viewForDisclosureForState(false)
}
else{
self.expandCellsFromIndexOf(prod, indexPath: indexPath, tableView: tableView)
selectedCell?.accessoryView = self.viewForDisclosureForState(true)
}
}
}
}
我特别感谢用户anoopm,我丢失了存储库的链接,任何人都有把它放在这里很好,感谢阅读本文的方式