简体   繁体   中英

how to to toggle visibility of arrangedSubviews in a UIStackView, thats inside a tableViewCell swift3

I have a tableView with cells populated by UIStackViews, with buttons as arrangedSubviews, that are created with a few functions. The top view in the stackView is visible and all the other views are hidden, the button in the top views has an action, and when its called the other views should toggle between visible and hidden.

    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
}

Right now whats happening is that only the hidden views in the last cell are toggling between visible and hidden(no matter which cell i click) - I guess I need to instantiate the toggling on all cells but i cant figure out a way to do that.

another problem is that i want a top view to open only the hidden views in its cell, i figure i need to use indexPath.row somehow outside of 'cellForRowAt indexPath'.

You'll thank your sanity if you move a lot of this logic into a UITableViewCell subclass.

Not a complete rewrite of your snippet (hinting at setting up some of the views via storyboard, but no big difference to doing in code except without storyboard you'll also need to override the cell's init and set up the subviews), but here's a starting point that you could investigate:

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) { }

}

Then the view controller becomes a lot simpler. It's not clear to me if each cell's stack view has the same set of option buttons, or if the option buttons are somehow contextual based on which row they're in.

If they're all the same I'd also move the generateOptionsButtons() logic into the StackViewCell (or actually if they're the same for each cell I'd probably set them up in the storyboard).

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM