[英]Swift delegate and protocol method not calling in iOS
I have parsing the JSON
values in UITableView
using MVC pattern, For that, I have created a separate UITableView
swift class, Model class, and UIViewController
class as well. 我已经使用MVC模式解析了UITableView
的JSON
值。为此,我还创建了一个单独的UITableView
swift类,Model类和UIViewController
类。
I can able to parse the JSON values into the table view. 我可以将JSON值解析为表格视图。 But the problem is I can't able to pass the selected tableView cell values to my controller using the delegate method 但是问题是我无法使用委托方法将选定的tableView单元格值传递给控制器
Here my code is 这是我的代码
UIVIewController : 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 : 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)
}}
Here when I click table on the tableView
cell didSelectRowAtIndexPath
method called but selectedUserContact
not getting called. 在这里,当我在tableView
单元格上单击表时,调用了didSelectRowAtIndexPath
方法,但未调用selectedUserContact
。
You've misunderstood the purpose of delegating here. 您误解了在这里委派的目的。 The idea is that your table view is only responsible for drawing a table, it shouldn't be responsible for maintaining any of the data that it's displaying. 这个想法是,您的表格视图仅负责绘制表格,而不应负责维护其显示的任何数据。 This allows you to cleanly design your code using the Model-View-Controller (MVC) paradigm. 这使您可以使用“模型-视图-控制器”(MVC)范例来干净地设计代码。 Delegation allows your controllers to pass model information to the views without breaking MVC. 委派允许您的控制器将模型信息传递给视图而不会破坏MVC。
In your example: Address
is the model, the table view is the view, and your view controller is the controller. 在您的示例中: Address
是模型,表视图是视图,而视图控制器是控制器。 So you want your controller to conform to the table view's delegate/data source protocols so that it can feed the data to it correctly. 因此,您希望控制器遵守表视图的委托/数据源协议,以便它可以将数据正确地馈送到它。
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)
}
}
EDIT: I just want to add that you need to make sure in your storyboard that you set ViewController
as the delegate
and dataSource
of the table view. 编辑:我只想补充一点,您需要确保在情节ViewController
中将ViewController
设置为表视图的delegate
和dataSource
。 Then you can remove all the code that you've written in the UserTable
class. 然后,您可以删除在UserTable
类中编写的所有代码。 If anything you don't need it at all and your table view can be a simple UITableView
. 如果您根本不需要它,则表视图可以是一个简单的UITableView
。 I almost never create subclasses of it, since you can normally do everything through the delegation and UITableViewCell
subclasses. 我几乎从不创建它的子类,因为您通常可以通过委托和UITableViewCell
子类来完成所有操作。
According to this line, Your have a table view in the storyboard and taken outlet in viewcontroller. 根据此行,您在情节提要中有一个表格视图,并已在viewcontroller中取出。
@IBOutlet weak var userTable: UserTable!
So you don't need to do this like that: 因此,您不需要这样做:
let user = UserTable()
You have to give delegate like this: 您必须像这样给代表:
userTable.userdelegate? = self
Looks like you're instantiating the table view from a storyboard, so you're not setting the delegate on the correct instance of UserTable (and the delegate method is never called because the delegate is nil). 看起来您是从情节提要中实例化表格视图,因此您没有在UserTable的正确实例上设置委托(并且永远不会调用委托方法,因为委托为nil)。
In the view controller change 在视图控制器中更改
user.userdelegate? = self
to 至
userTable.userdelegate? = self
For mine it is working fine with the below scenario. 对于我来说,在以下情况下可以正常工作。 Kindly check with that one. 请检查那个。
UserTable 用户表
@objc protocol contactSelectionDelegate: class {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
}
weak var userdelegate: contactSelectionDelegate?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate?.tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
}
ViewController ViewController
class ViewController: UIViewController {
}
extension ViewController: contactSelectionDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// YOU CAN GET THE ALL THE STUFFS WHICH IS USER SELECTED IN THE TABLE VIEW
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.