Swift - 从自定义 UITableViewCell 调用 UIViewController 的函数 [英] Swift - Calling a func of a UIViewController from a Custom UITableViewCell

查看:40
本文介绍了Swift - 从自定义 UITableViewCell 调用 UIViewController 的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的问题:

我有一个 MainTableViewController,带有一个用于使用自定义 UITableViewCells 的表格的插座.我在 MainTableViewController 中还有一个 UIView 的插座,称为 BlackView.

I have a MainTableViewController with an outlet for a table that uses custom UITableViewCells. I also have an outlet for a UIView, called BlackView, in MainTableViewController.

我想要做什么:在 myCustomCell 中,我想设置BlackView.hidden = false".我试图在我的 MainTableViewController 文件中使用class func",并从 myCustomCell 调用它,但它不起作用,因为当我将class"这个词放在func"之前时,Xcode 停止识别 BlackView.

What I want to do: Inside myCustomCell I would like to set "BlackView.hidden = false". I am trying to use "class func" in my MainTableViewController file, and call it from myCustomCell, but it is not working, because Xcode stops recognizing BlackView when I put the word "class" before "func".

因此,我想调用 MainTableViewController 的函数或从我的 .xib 文件的 .swift 访问其出口.

So, I would like to call a function of a MainTableViewController or access its outlet from the .swift of my .xib file.

有人知道怎么做吗?

这是我的 .xib 文件:

Here is my .xib file:

我的 .xib 文件

这是我的 .xib 文件的 .swift:

Here is the .swift for my .xib file:

class myCustomCell: UITableViewCell {

    @IBOutlet weak var commentTextView: UITextView!


    override func awakeFromNib() {

        commentTextView.delegate = self

        super.awakeFromNib()

    }


    func textViewDidBeginEditing(textView: UITextView) {

        MainTableViewController.hideBlackView(true)

    }

    func textViewDidEndEditing(textView: UITextView) {

        var comment = commentTextView.text

    }

}

这是我的 MainTableViewController:

Here is my MainTableViewController:

class MainTableViewController: UIViewController

    @IBOutlet weak var MyTable: UITableView!

    @IBOutlet weak var BlackView: UIView!

    override func viewDidLoad() {

        BlackView.hidden = true;

        MyTable.registerNib(UINib(nibName: "myCustomCell", bundle: nil), forCellReuseIdentifier: "myCustomCellID")

    }

    class func hideBlackView(setToHidden: Bool) {

        if setToHidden == true {

            BlackView.hidden = true

        } else {

            BlackView.hidden = false

        }


    }


    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


            let cell = tableView.dequeueReusableCellWithIdentifier("myCustomCellID") as! PublishHeaderTableViewCell

            cell.selectionStyle = UITableViewCellSelectionStyle.None


            return cell


    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return 1

    }

}

这是我的 Main.storyboard:

Here is my Main.storyboard:

我的主故事板

推荐答案

答案是委托

BlackView 是一个将由操作系统创建的实例.插座是引用该实例的特殊属性(称为插座).当显示 MainTableViewController 时,操作系统会创建它的一个实例.

BlackView is an instance which will be created by the OS. The outlet is a special property (called an outlet) referencing that instance. When MainTableViewController is shown, an instance of it is created by the OS.

您可能想使用实例方法,而不是类方法来更改 BlackView 实例上的隐藏属性.为此,您需要将 MainTableViewController 实例的引用传递给 myCustomCell.这称为委托,这是 ios 编程和大多数 MVC 模型的工作方式.

You probably want to use an instance method, not a class method to change the hidden property on instance of BlackView. To do that you will need to pass a reference of the MainTableViewController instance to myCustomCell. This is called delegation, which is how ios programming and most MVC models work.

为此添加定义一个委托协议(就在自定义单元格的定义之上是正常的)并向这种类型的单元格添加一个弱变量:

To do this add define a delegate protocol (just above the definition for the custom cell would be normal) and add a weak var to the cell of this type:

// use a class protocol for delegates so weak properties can be used
protocol MyCustomCellDelegate: class {
    func hideBlackView(setToHidden: Bool)
}

class MyCustomCell: UITableViewCell {

    @IBOutlet weak var commentTextView: UITextView!

    weak var delegate: MyCustomCellDelegate?

    override func awakeFromNib() {
        commentTextView.delegate = self
        super.awakeFromNib()
    }


    func textViewDidBeginEditing(textView: UITextView) {
        delegate?.hideBlackView(true)
    }

    func textViewDidEndEditing(textView: UITextView) {
        var comment = commentTextView.text
    }
}

然后,当您在 cellForRowAtIndexPath 中设置单元格时,将其转换为正确的单元格类型,在您给出的示例中应为 MyCustomCell,而不是 PublishHeaderTableViewCell(另请注意,我已将您的自定义单元格类名称切换为以开头)ios 开发中的行业标准的大写字母).最后,将委托设置为 MainTableViewController 的实例(在实例函数中称为self").

Then when you are setting up the cells in cellForRowAtIndexPath, cast as the the proper cell type which should be MyCustomCell in the example you've given not PublishHeaderTableViewCell (also note that I've switched your custom cell class name to starting with a capital letter as is industry standard in ios development). Finally, set the delegate to the instance of the MainTableViewController (which is called "self" from within instance functions).

顺便说一句,在您的情况下,您只使用一个单元格,因此您可能不需要出列和重用单元格.您可以将所有这些取出并返回您在 cellForRowAtIndexPath 方法中创建的单元格的简单实例.无论如何,如果您刚刚简化了 Stack Overflow 的代码,我将保留所有这些内容.

BTW, in your case, you are only using one cell, so you probably don't need to dequeue and reuse cells. You could just take all that out and return a simple instance you created of the cell in the cellForRowAtIndexPath method. Anyway, I will leave all that in place in case you have just simplified your code for Stack Overflow.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    // you need to cast the cell to your custom class to use it
    let cell = tableView.dequeueReusableCellWithIdentifier("myCustomCellID") as! MyCustomCell
    cell.selectionStyle = UITableViewCellSelectionStyle.None

    // set the delegate
    cell.delegate = self

    return cell
}

最后,非常重要的是,您需要声明 MainTableViewController 符合将使用它的协议,以便其他对象想要委托给它的函数(方法)将成功.在您的情况下,它需要符合我们上面写的 MyCustomCellDelegate,而且由于您将它用于 tableView 的数据源(对于 cellForRowAtIndexPath 和 numberOfRowsInSection),您需要声明它符合 UITableViewDataSource(您可能已经这样做了已经通过 Interface Builder(故事板)...如果没有,您可以在类定义中完成.

Finally, and VERY IMPORTANTLY, you need to declare that MainTableViewController conforms to the the protocols that will use it so the functions (methods) that other objects want to delegate to it will succeed. In your case it needs to conform to both MyCustomCellDelegate which we wrote above, but also since you are using it for the for the tableView's data source (for cellForRowAtIndexPath and numberOfRowsInSection) you need to declare that it conforms to UITableViewDataSource (You may have done this already through Interface Builder (story board).. if not you can do it in the class definition).

// Declare objects conform to protocols by including protocol names separated by commas after the colon (or the class inherited from) 

class MainTableViewController: UIViewController, MyCustomCellDelegate, UITableViewDataSource {

    @IBOutlet weak var MyTable: UITableView!
    @IBOutlet weak var BlackView: UIView!

    override func viewDidLoad() {
        BlackView.hidden = true
        MyTable.registerNib(UINib(nibName: "myCustomCell", bundle: nil), forCellReuseIdentifier: "myCustomCellID")
    }

    func hideBlackView(setToHidden: Bool) {
        // since they are both bools just set BlackView.hidden to the setToHidden parameter directly
        BlackView.hidden = setToHidden
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("myCustomCellID") as! MyCustomCell
        cell.selectionStyle = UITableViewCellSelectionStyle.None

        // set the delegate
        cell.delegate = self

        return cell
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
}

最后一点,我不确定在自定义单元格中的awakeFromNib 方法中设置UITextView 的委托是否合适.我知道这种方法并不总是会触发..在你的情况下,因为它在插座上,我认为可以,但我自己不太使用 XIB 文件,所以你可能想打印到控制台以确保每次都会调用它或更多地研究问题.

As a final note, I'm not sure is setting the delegate for the UITextView is a appropriate in the awakeFromNib method in your custom cell. I know that this method doesn't always fire.. In your case since it is on an outlet, I think it is OK, but I don't use XIB files very much my self, so you may want to print to the console to make sure it is being called each time or research the issue more.

这篇关于Swift - 从自定义 UITableViewCell 调用 UIViewController 的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆