我在视图控制器内部有一个表视图。当您单击单元格中的视图时,它会隐藏或显示另一个视图并更改单元格的高度。
我需要在表视图上调用方法以重新加载此单元格。或者我需要从我的视图控制器中观看此单元格。
这是我在代码上的位置。任何帮助或建议,我们将不胜感激。如果我的问题不清楚,请让我知道,我将尝试进一步详细介绍
单元格
class CheckoutAddressTableViewCell: UITableViewCell {
let addressFieldsHeight:CGFloat = 330
var initialized = false;
var sameAsButtonIsChecked:Bool = false {
didSet {
if sameAsButtonIsChecked {
sameAsCheckboxImageView.image = #imageLiteral(resourceName: "iconCheckboxChecked")
addressFieldsView.isHidden = true
addressFieldsHeightConstraint.constant = 0
}else{
sameAsCheckboxImageView.image = #imageLiteral(resourceName: "iconCheckbox")
addressFieldsView.isHidden = false
addressFieldsHeightConstraint.constant = addressFieldsHeight
}
}
}
}
视图控制器
import UIKit
class CheckoutViewController: UIViewController {
let cellSpacingHeight:CGFloat = 30.0
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
tableView.allowsSelection = false
tableView.keyboardDismissMode = .onDrag
NotificationCenter.default.addObserver(self, selector: #selector(CheckoutViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(CheckoutViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: Keyboard Notifications
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
}
}
@objc func keyboardWillHide(notification: NSNotification) {
UIView.animate(withDuration: 0.2, animations: {
// For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
})
}
}
// datasource
extension CheckoutViewController: UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
// Set the spacing between sections
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return cellSpacingHeight
}
// Make the background color show through
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.clear
return headerView
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellID = "CheckoutAddressTableViewCellReuseID"
let cell = tableView.dequeueReusableCell(withIdentifier: cellID) as! CheckoutAddressTableViewCell
cell.setUp(setUpCase: .billing)
cell.headerLabel.text = "BILLING INFORMATION"
// watch cell.sameAsButtonIsChecked
return cell
return UITableViewCell()
}
}
// delegate
extension CheckoutViewController:UITableViewDelegate {
}
答案 0 :(得分:2)
虽然对于您的情况,使用委托是可以的解决方案,但我建议在单元格上使用闭包。现在,与单元格相关的逻辑位于实际创建单元格的位置,与“委托”模式相比,它具有更高的可见性。
您可以将以下内容添加到您的单元格类中
typealias CellAction: () -> Void
var onMyAction: CellAction?
这可以是触发动作的任何功能
func yourFuncThatTriggersTheAction() {
onMyAction?()
}
现在进入您的cellForRowAt
cell.onMyAction = {
//do whatever necessary when action is invoked
}
请注意,在cellForRowAt中使用此方法还解决了获取触发某些操作的单元格的indexPath的问题。
答案 1 :(得分:1)
委派模式最适合您的情况。 您需要做几件事:
创建协议:
protocol CheckoutAddressCellActionDelegate {
func didUpdateLayout(forCell cell: UITableViewCell)
}
将委托属性添加到CheckoutAddressTableViewCell
:
weak var delegate: CheckoutAddressCellActionDelegate?
在执行布局更改触发器(可能在sameAsButtonIsChecked中)时调用委托方法:
delegate?.didUpdateLayout(forCell: self)
下一步,在您的CheckoutViewController
中,首先需要在cellForRowAt
方法中设置单元格的委托:
cell.delegate = self
最后将扩展添加到实现CheckoutViewController
的{{1}}并重新加载单元格的indexPath:
CheckoutAddressCellActionDelegate
答案 2 :(得分:1)
您可以创建一个协议并将UIViewController
设置为每个单元的委托,例如:
@objc protocol YourCellProtocol {
cell(_ cell: CheckoutAddressTableViewCell, didChangeState state: Bool)
}
您将委托属性添加到UITableViewCell
子类中,并在状态更改时调用该委托
class CheckoutAddressTableViewCell: UITableViewCell {
weak var delegate: YourCellProtocol?
let addressFieldsHeight:CGFloat = 330
var initialized = false;
var sameAsButtonIsChecked:Bool = false {
didSet {
//call the delegate with state change
delegate?.cell(self, didChangeState: sameAsButtonIsChecked)
if sameAsButtonIsChecked {
sameAsCheckboxImageView.image = #imageLiteral(resourceName: "iconCheckboxChecked")
addressFieldsView.isHidden = true
addressFieldsHeightConstraint.constant = 0
}else{
sameAsCheckboxImageView.image = #imageLiteral(resourceName: "iconCheckbox")
addressFieldsView.isHidden = false
addressFieldsHeightConstraint.constant = addressFieldsHeight
}
}
}
}
在您的UIViewController
中,您遵循YourCellProtocol
并实现了
func cell(_ cell: CheckoutAddressTableViewCell, didChangeState state: Bool) {
//state changed for a cell
}
然后在cellForRowAt:
中将UIViewController
设置为代表:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.delegate = self
...
}
或者,您可以走NotificationCenter
路线,以在单元格状态更改为时发布通知
let notificatioName = Notification.Name("CellStateChanged")
NotificationCenter.default.post(name: notificatioName, object: nil, userInfo: ["state": sameAsButtonIsChecked])
然后在您的UIViewController
中观察此通知
let notificatioName = Notification.Name("CellStateChanged")
NotificationCenter.default.addObserver(self, selector: #selector(cellDidChangeState(_:)), name: notificatioName, object: nil)
@objc func cellDidChangeState(_ notification: Notification) {
if let userData = notification.userInfo, let state = userData["state"] {
//you have cells state here
}
}