从视图控制器观看单元格的变量

时间:2018-08-31 07:57:21

标签: ios swift

我在视图控制器内部有一个表视图。当您单击单元格中的视图时,它会隐藏或显示另一个视图并更改单元格的高度。

我需要在表视图上调用方法以重新加载此单元格。或者我需要从我的视图控制器中观看此单元格。

这是我在代码上的位置。任何帮助或建议,我们将不胜感激。如果我的问题不清楚,请让我知道,我将尝试进一步详细介绍

单元格

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 {

}

3 个答案:

答案 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)

委派模式最适合您的情况。 您需要做几件事:

  1. 创建协议:

    protocol CheckoutAddressCellActionDelegate {
        func didUpdateLayout(forCell cell: UITableViewCell)
    }
    
  2. 将委托属性添加到CheckoutAddressTableViewCell

    weak var delegate: CheckoutAddressCellActionDelegate?
    
  3. 在执行布局更改触发器(可能在sameAsButtonIsChecked中)时调用委托方法:

    delegate?.didUpdateLayout(forCell: self)
    
  4. 下一步,在您的CheckoutViewController中,首先需要在cellForRowAt方法中设置单元格的委托:

    cell.delegate = self
    
  5. 最后将扩展添加到实现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
    }
}