我是一个Swift新手,我正在努力摧毁动态创建的嵌套tableview。我有一个自定义UIView(B),它在运行时嵌套在tableViewCell(A)中,具体取决于单元格的属性。在这个UIView(B)中,我动态创建一个tableView(C),它包含与可变长度操作按钮数组相关的单元格。
所以层次结构看起来像这样:
- TableView (A)
|_ Custom UIView (B)
|_ Dynamically created 'nested' TableView (C)
我想确保嵌套的tableview(C)仅针对需要操作按钮的单元格显示(busActions数组的长度> = 1)。 以下是自定义UIView(B)中的代码。它工作正常,但我看到了随机实例,其中tableview(C)显示在不应该的地方(参见下面的setupActionTable方法):
import UIKit
@IBDesignable class CustomComponentView2: UIView, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var view: UIView!
@IBOutlet var busName: UILabel!
@IBOutlet var loyaltyDesc: UILabel!
@IBOutlet weak var testButton: TestButton!
@IBOutlet weak var mapButton: TestButton!
// set the data for the action menu
var busActions:[[String:String]] = []
// create the action menu view
var actionTable:UITableView?
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
setup()
}
override func layoutSubviews() {
super.layoutSubviews()
view.frame = bounds
}
func setup() {
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
addSubview(view)
}
func loadViewFromNib() -> UIView {
let bundle = NSBundle(forClass:self.dynamicType)
let nib = UINib(nibName: "CustomComponentView2", bundle: bundle)
let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return view
}
//MARK: - Tableview Delegate & Datasource
func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int
{
return busActions.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "actionCell")
print("Create action cell:",indexPath.row, busActions[indexPath.row]["title"]!)
cell.textLabel?.text = busActions[indexPath.row]["title"]!
cell.accessoryType = .DisclosureIndicator
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
// do something when the tableview is selected
}
func setupActionTable(busId:Int){
// set the data for the action menu
busActions = BusinessData().getBusinessById(busId).actions!
print("busActions: ",busActions)
if busActions.count >= 1 { // we have some action buttons in the array
print("We've got some action buttons")
actionTable = UITableView(frame: CGRectZero, style:UITableViewStyle.Plain)
actionTable!.delegate = self
actionTable!.dataSource = self
// table size & layout
actionTable!.rowHeight = 30.0
let h = busActions.count*Int(actionTable!.rowHeight)
// config
actionTable!.scrollEnabled = false
view.addSubview(actionTable!)
actionTable!.reloadData()
actionTable!.sizeActionTableView(h)
} else {
print("NO ACTION BUTTONS:", busActions.count)
if(actionTable!.isDescendantOfView(self.view)) {
print("It's there and shouldn't be!!!") // should never be seen
actionTable!.removeFromSuperview()
actionTable!.reloadData()
}
}
return
}
}
extension UIView {
/// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview.
/// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this.
func sizeActionTableView(h:Int) {
guard let superview = self.superview else {
print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `sizeActionTableView()` to fix this.")
return
}
self.translatesAutoresizingMaskIntoConstraints = false
let constraintStringV = "V:[subview("+String(h)+")]-0-|"
superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self]))
superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(constraintStringV, options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self]))
}
}
任何人都可以看到为什么我的代码每次busActions.count == 0
都没有从视图中删除actionTable?
更多信息
如果它是相关的,TableView(A)中的单元格嵌套在扩展部分和&细胞。因此,当点击节标题时,列表会显示该节。当点击特定列表时,单元格Class将更改为将UIView(B)嵌入其中的单元格。
更新1:添加了BusinessData类
这是用于向Custom UIView(上方)提供业务/操作数据的BusinessData类。
import Foundation
class BusinessData {
func getBusinessById(id:Int) -> Business {
// todo: get the businesses from the DB
let tempArray = [
Business(busName: "Dave's Cafe", busId: 1, website: "http://www.google.com",
actions: [["title": "About Us", "contentId": "123456", "type": "content"],
["title": "Website", "url": "http://www.davescafe.com", "type": "web"]]),
Business(busName: "Jane's Tea Room", busId: 2, website: "http://www.bbc.co.uk",
actions: [["title": "Jane's Favourites", "contentId": "123457", "type": "content"],
["title": "Website", "url": "http://www.janestearoom.com", "type": "web"]]),
Business(busName: "Cafe Hero", busId: 3, address: "41 Acacia Ave",
actions: [["title": "The Hero Difference", "contentId": "123456", "type": "content"]]),
Business(busName: "The Scout Group", busId: 18, website: "http://www.scouts.org.uk"),
Business(busName: "Village Bowls Club", busId: 5)
]
// return only the specified business (filtered by busId)
let rtnArray = tempArray.filter{$0.busId == id}
if rtnArray.count == 1{
return rtnArray[0]
} else {
return Business(busName: "Error", busId: 0)
}
}
}
更新2:从TableViewController添加了代码段(A)
// set the type of custom cell to use
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// set the data to use
let entry = categories[indexPath.section].items[indexPath.row]
// create a superview which can be used by either type of custom cell
var cell:CustomTableCellSuper = CustomTableCellSuper()
cell.bus = entry
// check if a cell has been tapped or not
if entry.selected == false {
cell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell", forIndexPath: indexPath) as! CustomTableViewCell
cell.cellComponent.busName.text = entry.busName
} else {
// an expanded (selected) cell
cell = tableView.dequeueReusableCellWithIdentifier("CustomTableViewCell2", forIndexPath: indexPath) as! CustomTableViewCell2
cell.cellComponent.busName.text = entry.busName
// actions menu
cell.cellComponent.setupActionTable(entry.busId)
}
return cell
}