ios - Swift 委托(delegate)和协议(protocol)方法不在 iOS 中调用

标签 ios swift uitableview model-view-controller

我已经使用 MVC 模式解析 UITableView 中的 JSON 值,为此,我创建了一个单独的 UITableView swift 类,Model 类, 和 UIViewController 类。

我可以将 JSON 值解析到 TableView 中。但问题是我无法使用委托(delegate)方法将选定的 tableView 单元格值传递给我的 Controller

我的代码是

UIVIewController :

class ViewController: UIViewController,contactSelectionDelegate {
var contactArray = [Address]()
@IBOutlet weak var userTable: UserTable!
let user = UserTable()


override func viewDidLoad() {
    super.viewDidLoad()

    user.userdelegate? = self
    if Connectivity.isConnectedToInternet() {
        print("Yes! Network connection is available")
        APIManager.sharedInstance.fetchUserDetails(urlString: FETCH_USER_DETAIL_URL, userCount: ["offset":1]) { connectionResult in

            switch connectionResult {
            case .success(let data):
                do {
                    self.contactArray = try JSONDecoder().decode([Address].self, from: data)

                    print(self.contactArray.count)
                    print(self.contactArray[0].Name)

                    DispatchQueue.main.async {
                        print(self.contactArray)
                        self.userTable.dataSourceArray=self.contactArray
                        self.userTable.reloadData()
                    }
                }
                catch let errorValue {
                    print(errorValue)
                }
            case .failure(let error):
                print(error)
            }
        }
    }
    else{
        print("No network connection")
    }
}

func selectedUserContact(name: String, email: String, phone: String) {
    print("Delegate Called")
    let userdetailVC = storyboard?.instantiateViewController(withIdentifier: "UserContactDetailPage") as! UserContactDetailPage
    userdetailVC.name = name
    userdetailVC.email = email
    userdetailVC.phone = phone
    self.navigationController?.pushViewController(userdetailVC, animated: true)
} }

UITableView :

protocol contactSelectionDelegate: class{
func selectedUserContact(name: String ,email: String ,phone: String)
}

class UserTable: UITableView ,UITableViewDelegate ,UITableViewDataSource  {


var dataSourceArray  =   [Address]()
weak var userdelegate: contactSelectionDelegate?

override init(frame: CGRect, style: UITableViewStyle) {
    super.init(frame: frame, style: style)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

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

func numberOfSections(in tableView: UITableView) -> Int {
    return 1;
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.dataSourceArray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell:UserCell   =   tableView.dequeueReusableCell(withIdentifier: "UserCell", for: indexPath) as! UserCell
    if self.dataSourceArray.count>0 {
        let myUser  =   self.dataSourceArray[indexPath.row]
        cell.nameLbl.text  =   myUser.Name
        cell.emailLbl.text  =   myUser.Email
        cell.phoneLbl.text =   myUser.Phone
    }
    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 200
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let myUser  =   self.dataSourceArray[indexPath.row]
    print(myUser.Name)
    print(myUser.Email)
    print(myUser.Phone)
     userdelegate?.selectedUserContact(name: myUser.Name, email: myUser.Email, phone: myUser.Phone)
}}

在这里,当我在 tableView 单元格上单击表格时,调用了 didSelectRowAtIndexPath 方法,但未调用 selectedUserContact

最佳答案

您误解了在这里委派的目的。这个想法是你的表格 View 只负责绘制表格,它不应该负责维护它显示的任何数据。这使您可以使用模型- View - Controller (MVC) 范例清晰地设计您的代码。委托(delegate)允许您的 Controller 在不破坏 MVC 的情况下将模型信息传递给 View 。

在您的示例中:Address 是模型, TableView 是 View ,您的 View Controller 是 Controller 。因此,您希望您的 Controller 符合 TableView 的委托(delegate)/数据源协议(protocol),以便它可以正确地向其提供数据。

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    var contactArray = [Address]()
    @IBOutlet weak var userTable: UserTable!

    override func viewDidLoad() {
        super.viewDidLoad()

        if Connectivity.isConnectedToInternet() {
            print("Yes! Network connection is available")
            APIManager.sharedInstance.fetchUserDetails(urlString: FETCH_USER_DETAIL_URL, userCount: ["offset":1]) { connectionResult in

                switch connectionResult {
                case .success(let data):
                    do {
                        self.contactArray = try JSONDecoder().decode([Address].self, from: data)

                        print(self.contactArray.count)
                        print(self.contactArray[0].Name)

                        DispatchQueue.main.async {
                            print(self.contactArray)
                            self.userTable.reloadData()
                        }
                    }
                    catch let errorValue {
                        print(errorValue)
                    }
                case .failure(let error):
                    print(error)
                }
            }
        }
        else{
            print("No network connection")
        }
    }

    // MARK: - UITableViewDataSource

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1;
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.contactArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UserCell = tableView.dequeueReusableCell(withIdentifier: "UserCell", for: indexPath) as! UserCell
        let myUser = self.contactArray[indexPath.row]
        cell.nameLbl.text = myUser.Name
        cell.emailLbl.text = myUser.Email
        cell.phoneLbl.text = myUser.Phone
        return cell
    }

    // MARK: - UITableViewDelegate

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 200
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let myUser = self.contactArray[indexPath.row]
        print(myUser.Name)
        print(myUser.Email)
        print(myUser.Phone)
        selectedUserContact(name: myUser.Name, email: myUser.Email, phone: myUser.Phone)
    }

    // MARK: -

    func selectedUserContact(name: String, email: String, phone: String) {
        print("Delegate Called")
        let userdetailVC = storyboard?.instantiateViewController(withIdentifier: "UserContactDetailPage") as! UserContactDetailPage
        userdetailVC.name = name
        userdetailVC.email = email
        userdetailVC.phone = phone
        self.navigationController?.pushViewController(userdetailVC, animated: true)
    }
}

编辑:我只想补充一点,您需要确保在 Storyboard中将 ViewController 设置为 delegatedataSource TableView 。然后您可以删除您在 UserTable 类中编写的所有代码。如果您根本不需要它,您的 TableView 可以是一个简单的 UITableView。我几乎从不创建它的子类,因为您通常可以通过委托(delegate)和 UITableViewCell 子类来完成所有事情。

关于ios - Swift 委托(delegate)和协议(protocol)方法不在 iOS 中调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50050072/

相关文章:

objective-c - 表格 View 中的完整文件列表

ios - 将图像从S3存储桶加载到uiTableView

ios - 代码签名配置文件 : What do I need to select? 我需要运行什么方案才能发布?

ios - 以编程方式强制 UIWebView 进入全屏模式

ios - 随时恢复 UILocalNotification 或远程推送通知

ios - 如何使用 panGesture 从 firstViewController 的顶部移动 secondViewController?

swift - 单击 UITableView 时没有任何反应(尝试在 View 之间发送数据)

ios - NSJSONSerialization 和 UIPIckerView 出现奇怪的错误

ios - 删除Eureka中单行的分隔线

Swift - 使用 Firebase 的 Facebook 身份验证发生 (INVALID_CREDENTIALS) 错误