我有一个 tableView,其中包含由 UIStackView 填充的单元格,带有排列的按钮子视图,这些按钮是用几个函数创建的。堆栈视图中的顶部视图是可见的,所有其他视图都是隐藏的,顶部视图中的按钮有一个操作,当调用它时,其他视图应该在可见和隐藏之间切换。
func generateButtons() -> [[UIButton]]{
var topButtonArray = [UIButton]()
var finalButtonArray = [[UIButton]]()
for title in array1 {
topButtonArray.append(createButton(title: title , action: "buttonPressed"))
}
for button in topButtonArray {
var buttonArray = [UIButton]()
buttonArray.append(button)
for title in array2 {
buttonArray.append(createButton(title: title, action: "moveOn"))
}
finalButtonArray.append(buttonArray)
}
return finalButtonArray
}
func generateStackViews() -> [UIStackView] {
stackViewArray = [UIStackView]()
let finalButtonArray = generateButtons()
for buttons in finalButtonArray{
stackViewArray.append(createStackView(subViews: buttons))
}
for stackView in stackViewArray{
let views = stackView.arrangedSubviews
let hiddenViews = views[1..<views.count]
for views in hiddenViews{
views.isHidden = true
}
}
return stackViewArray
}
func buttonPressed(){
//let stackViewArray = generateStackViews()
for stackView in stackViewArray{
let views = stackView.arrangedSubviews
let hiddenViews = views[1..<views.count]
for view in hiddenViews {
if view.isHidden == true{showViews(view: view)} else{hideViews(view: view)}
}
}
}
func showViews(view : UIView){
UIView.animate(withDuration: 0.3) {
view.isHidden = false
}
}
func hideViews(view : UIView) {
UIView.animate(withDuration: 0.2) {
view.isHidden = true
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "First")!
let stackViewArray = generateStackViews()
cell.contentView.addSubview(stackViewArray[indexPath.row])
return cell
}
现在发生的事情是,只有最后一个单元格中的隐藏视图在可见和隐藏之间切换(无论我单击哪个单元格) - 我想我需要实例化所有单元格上的切换,但我找不到一种方法来做到这一点。
另一个问题是我希望顶部视图仅打开其单元格中的隐藏视图,我认为我需要在"cellForRowAt indexPath"之外以某种方式使用 indexPath.row。
如果你把很多这样的逻辑移到一个UITableViewCell
子类中,你会感谢你的理智。
不是对代码段的完全重写(暗示通过情节提要设置一些视图,但与在代码中执行没有太大区别,除非没有情节提要,您还需要覆盖单元格的 init 并设置子视图),但这里有一个起点,您可以调查:
class StackViewCell: UITableViewCell {
// these could be set up in code in the `init` method if
// you don't want to use storyboards
@IBOutlet var stackView: UIStackView!
@IBOutlet var toggleButton: UIButton!
var optionButtons: [UIButton] = [] {
didSet {
for button in optionButtons {
button.isHidden = optionsAreHidden
stackView.addArrangedSubview(button)
}
}
}
// iterates over buttons to change hidden property based on `optionsAreHidden` property
var optionsAreHidden: Bool = true {
didSet {
optionButtons.forEach({ $0.isHidden = optionsAreHidden })
}
}
@IBAction func toggleButtonPressed(button: UIButton) {
optionsAreHidden = !optionsAreHidden
}
// set up stackview and toggle button here if not setting up in storyboard
//init?(coder aDecoder: NSCoder) { }
}
然后视图控制器变得简单得多。我不清楚每个单元格的堆栈视图是否具有相同的选项按钮集,或者选项按钮是否根据它们所在的行以某种方式上下文相关。
如果它们都相同,我也会将generateOptionsButtons()
逻辑移动到StackViewCell
中(或者实际上,如果每个单元格的逻辑相同,我可能会在故事板中设置它们)。
class OptionsViewController: UITableViewController {
func generateOptionsButtons() -> [UIButton] {
// create and return buttons for a cell
// potentially move this into `StackViewCell` too...
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "StackViewCellIdentifier", for: indexPath)
if let stackViewCell = cell as? StackViewCell {
stackViewCell.optionButtons = generateOptionsButtons()
}
return cell
}
}