首页 文章

试图在swift中理解协议和委托

提问于
浏览
0

我试图围绕协议和代表,但似乎有一些问题 . 我有2个ViewControllers,我正在尝试传递数据 . ViewController A有一个文本字段,我希望可以从ViewController B中选择填充 . 所以ViewController A上有一个按钮可以将你调到ViewController B这就是我设置B的方法 .

protocol AddPlayersViewControllerDelegate{
    var playersName:String? { set get }
}

class B-Controller: UIViewController, UITableViewDelegate, UITableViewDataSource{

    var addPlayerDelegate:AddPlayersViewControllerDelegate?

    override func viewDidLoad() {
            super.viewDidLoad()
    ..etc

    }

我在viewControllers B类中使用此代码在选择单元格时关闭currentView

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {


        println("did select")
        let cell = playerTableView.cellForRowAtIndexPath(indexPath)

        addPlayerDelegate?.playersName? = "New Name"

        if let navController = self.navigationController {
            navController.popViewControllerAnimated(true)
        }
    }

它不允许我在协议中设置玩家名称属性 . 当我从ViewController A检查它时,它一直让我返回Nil .

View Controller A看起来像这样:

class A-ViewController: UIViewController, UITextFieldDelegate, AddPlayersViewControllerDelegate{

var addPlayerDelegate:AddPlayersViewControllerDelegate?
}

//然后我只是试图打印出在ViewController B中设置的新名称

override func viewWillAppear(animated:Bool){

println("this is the selected players name \(addPlayerDelegate?.playersName)") - returns nil

}

我确定我并没有完全理解某些东西,但我觉得我只是继续阅读并尝试了一些例子,最后才回到我开始的地方 .

// ***更新 *** //

我将尝试简化我的设置 . 我有2个视图控制器,VC-A和VC-B .

VC-A有一个文本字段和一个按钮 . VC-B有一个tableview . 我希望选项可以从CB-B的cell.text中填充textField,但前提是用户点击按钮查看VC-B . 所以第一次加载VC-A时,它应该从协议中的playersName字符串返回nil,因为VC-B从未被调用过 . 但是一旦用户点击VC-A内的按钮来查看VB-B,然后选择了一个单元格,这将解散VC-B并在VC-B类的协议中填充playersName字符串,那么我正在使用viewWillAppear检查是否已设置playersName的方法,如果是,则使用它 . 这是我给你的帮助中的更新代码 .

VC-A

class FirstViewController: AddPlayersViewControllerDelegate{

    var playersName:String?

    let svc = LookUpViewController()

    override func viewDidLoad() {
        super.viewDidLoad()

        svc.addPlayerDelegate = self
    }
}

VC-B

protocol AddPlayersViewControllerDelegate{
    var playersName:String? { set get }
}


class LookUpViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{

    var addPlayerDelegate: AddPlayersViewControllerDelegate?  
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}


    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        let cell = playerTableView.cellForRowAtIndexPath(indexPath)

        addPlayerDelegate?.playersName = "Ziggy"


        println("the name to be pass is \(addPlayerDelegate?.playersName)")

        if let navController = self.navigationController {
            navController.popViewControllerAnimated(true)
        }
    }

即使我从VC-B回到VC-A,似乎我仍然没有 . 我想要的是能够从VC-B获取一些数据(字符串)并在VC-A中使用它,但只能在用户使用VC-B类之后 . 那有意义吗?

1 回答

  • 4

    您已经在BController中显示了一个属性 addPlayerDelegate

    var addPlayerDelegate:AddPlayersViewControllerDelegate?
    

    你已经证明在BController中你可以和那个属性交谈:

    addPlayerDelegate?.playersName? = "New Name"
    

    但是你还没有证明,在这个控制器的生命周期的任何一点,它的 addPlayerDelegate 属性都被设置为任何东西 . 例如,我想看到这样的代码:

    someBController.addPlayerDelegate = someAController
    

    如果没有发生,那么该属性保持其初始值为零 .


    您的代码的另一个问题是这条线没有意义:

    class A-ViewController : // {
        var addPlayerDelegate:AddPlayersViewControllerDelegate?
    }
    

    AController不需要这个属性 . 他们都不需要代表! AController需要的是 playersName 属性 . 没有它,它没有惊讶,如果没有该属性你的代码甚至编译 . 您确定要正确报告吗?

相关问题