I have a tableview inside of an UIViewController. This tableview has a dynamic table with buttons.
I set the function for each button inside of the TableViewCell like this:
class ButtonTableViewCell: UITableViewCell {
let defaults = UserDefaults.standard
var targetTitle: String!
@IBOutlet weak var buttonDisplay: UIButton!
func setButton(title: String) {
buttonDisplay.setTitle(title.uppercased(), for: .normal)
targetTitle = title
buttonDisplay.addTarget(self, action: #selector(changeValue(_:)), for: .touchUpInside)
}
@objc func changeValue(_ sender: Any) {
currentCar = targetTitle
defaults.set(currentCar, forKey: "currentCar")
}
}
How can I dismiss the UIViewController which contains the TableView within the function @objc func changeValue(_ sender: Any)
?
Furthermore, since the buttons are being added dynamically, I do also need a dynamic height for the tableview itself - how can I adjust tableview's with every added cell?
UIViewController:
class DropdownViewController: UIViewController {
@IBOutlet weak var tableViewButtons: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableViewButtons.delegate = self
tableViewButtons.dataSource = self
}
}
extension DropdownViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return carsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let rowData = carsArray[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "buttonCell") as! ButtonTableViewCell
cell.setButton(title: rowData.name)
return cell
}
}
You can use delegates:
protocol ButtonTableViewCellDelegate {
func dismissFromCell()
}
class ButtonTableViewCell: UITableViewCell {
let defaults = UserDefaults.standard
var targetTitle: String!
// Delegate should be weak to avoid memory leaks
weak var delegate: ButtonTableViewCellDelegate?
@IBOutlet weak var buttonDisplay: UIButton!
func setButton(title: String) {
buttonDisplay.setTitle(title.uppercased(), for: .normal)
targetTitle = title
buttonDisplay.addTarget(self, action: #selector(changeValue(_:)), for: .touchUpInside)
}
@objc func changeValue(_ sender: Any) {
currentCar = targetTitle
defaults.set(currentCar, forKey: "currentCar")
delegate?.dismissFromCell()
}
}
class DropdownViewController: UIViewController {
@IBOutlet weak var tableViewButtons: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableViewButtons.delegate = self
tableViewButtons.dataSource = self
}
}
extension DropdownViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return carsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let rowData = carsArray[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "buttonCell") as! ButtonTableViewCell
cell.setButton(title: rowData.name)
// Setting Delegate here
cell.delegate = self
return cell
}
}
// Extend your controller to conform your Delegate Protocol
extension DropdownViewController: ButtonTableViewCellDelegate {
func dismissFromCell() {
self.dismiss()
}
}
You can get more info about delegation pattern here: https://www.appcoda.com/swift-delegate/
You'll want to use a delegate to perform the action. Just create a protocol with a function, and call the delegate within your changeValue
function.
Otherwise, use this:
var responder: UIResponder! = self
repeat { responder = responder.next } while !(responder is UIViewController)
(responder as! UIViewController).dismiss()
It just goes up the responder chain until it finds a UIViewController, and then performs any action needed. Only use this if you have a UIViewController as a parent somewhere, otherwise it won't work.
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.