我已经使用 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
设置为 delegate
和 dataSource
TableView 。然后您可以删除您在 UserTable
类中编写的所有代码。如果您根本不需要它,您的 TableView 可以是一个简单的 UITableView
。我几乎从不创建它的子类,因为您通常可以通过委托(delegate)和 UITableViewCell
子类来完成所有事情。
关于ios - Swift 委托(delegate)和协议(protocol)方法不在 iOS 中调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50050072/