Swift делегат и метод протокола не вызывают в iOS - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть синтаксический анализ JSON значений в UITableView с использованием шаблона MVC. Для этого я создал отдельный класс UITableView swift, класс Model и класс UIViewController.

Я могу анализировать значения JSON в табличном представлении. Но проблема в том, что я не могу передать выбранные значения ячеек таблицы в мой контроллер, используя метод делегата

Здесь мой код

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 cell didSelectRowAtIndexPath, но selectedUserContact не вызывается.

Ответы [ 4 ]

0 голосов
/ 27 апреля 2018

Для меня это нормально работает с приведенным ниже сценарием. Пожалуйста, проверьте с этим.

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

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
    }
}
0 голосов
/ 26 апреля 2018

Согласно этой строке, у вас есть табличное представление в раскадровке и взятое выходное в viewcontroller.

@IBOutlet weak var userTable: UserTable!

Так что вам не нужно делать это так:

let user = UserTable()

Вы должны дать делегату вот так:

userTable.userdelegate? = self
0 голосов
/ 26 апреля 2018

Похоже, что вы создаете экземпляр табличного представления из раскадровки, поэтому вы не устанавливаете делегата на правильный экземпляр UserTable (и метод делегата никогда не вызывается, потому что делегат равен нулю).

В контроллере вида изменить

user.userdelegate? = self

до

userTable.userdelegate? = self
0 голосов
/ 26 апреля 2018

Вы неправильно поняли цель делегирования здесь. Идея состоит в том, что ваше табличное представление отвечает только за рисование таблицы, но не должно поддерживать какие-либо данные, которые оно отображает. Это позволяет аккуратно спроектировать ваш код с использованием парадигмы Model-View-Controller (MVC). Делегирование позволяет вашим контроллерам передавать информацию о модели в представления, не нарушая MVC.

В вашем примере: Address - это модель, табличное представление - это представление, а контроллер представления - это контроллер. Таким образом, вы хотите, чтобы ваш контроллер соответствовал протоколам делегата / источника данных табличного представления, чтобы он мог корректно передавать данные в него.

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)
    }
}

РЕДАКТИРОВАТЬ: Я просто хочу добавить, что вы должны убедиться, что в вашей раскадровке вы установили ViewController в качестве delegate и dataSource представления таблицы. Затем вы можете удалить весь код, который вы написали в классе UserTable. Если вам что-то вообще не нужно, и ваш табличный вид может быть простым UITableView. Я почти никогда не создаю его подклассы, так как обычно вы можете делать все через делегирование и UITableViewCell подклассы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...