代码之家  ›  专栏  ›  技术社区  ›  Noodledew

Tableviews“cellForRowAt”在添加真实数据后从不调用

  •  0
  • Noodledew  · 技术社区  · 6 年前

    我有一个 UIViewController 单事件视图控制器 UIView TeilnehmerTableView公司 带着一个 UITableView 参与者StableView

    顾名思义,它是用来展示用户、参与活动的。首先,我在没有“真实”数据的情况下实现了它。我对users数组进行了硬编码,并在此基础上构建了表视图。这很有效。

    但是由于我实现了fetchUsers方法并用这些信息填充了数组,所以 tableView 根本不出现。显然,当我第一次加载页面时,它不会显示任何内容,因为 numberOfRowsInSection 返回0。但即使在获取之后,当我重新加载tableview时 返回一个值,则tableview为空。在调试时,我注意到填充单元格的方法 cellForRowAt

    有人能告诉我发生了什么事吗?

    import UIKit
    import Firebase
    
    class TeilnehmerTableView: UIView, UITableViewDelegate, UITableViewDataSource {
    
    var parentVC: SingleEventViewController?
    var users = [User]()
    
    let participantsTableView: UITableView = {
        let ctv = UITableView()
        return ctv
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.green
        setupTableView()
        setupViews()
        confBounds()
        fetchUsers()
    }
    
    func setupTableView() {
        participantsTableView.delegate = self
        participantsTableView.dataSource = self
        participantsTableView.register(TeilnehmerTVCell.self, forCellReuseIdentifier: TeilnehmerTVCell.reuseIdentifier)
        participantsTableView.tintColor = .white
    }
    
    func setupViews() {
        addSubview(participantsTableView)
    }
    
    func confBounds(){
        participantsTableView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
    }
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Users: ",users.count)
        return users.count
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        print("heightForRowAt Called")
        return 44
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("cellForRowAt Called")
        let row = tableView.dequeueReusableCell(withIdentifier: TeilnehmerTVCell.reuseIdentifier, for: indexPath) as! TeilnehmerTVCell
        row.user = users[indexPath.item]
        return row
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: false)
    }
    
    //MARK: - Methods
    func fetchUsers() {
        print("Fetching users..")
    
        let ref = Database.database().reference().child("users")
        ref.observeSingleEvent(of: .value, with: { (snapshot) in
            guard let dictionaries = snapshot.value as? [String: Any] else { return }
    
            dictionaries.forEach({ (key, value) in
    
                if key == Auth.auth().currentUser?.uid {
                    print("Found myself, omit from list")
                    return
                }
    
                guard let userDictionary = value as? [String: Any] else { return }
    
                let user = User(uid: key, dictionary: userDictionary)
                self.users.append(user)
            })
    
            self.users.sort(by: { (u1, u2) -> Bool in
                return u1.username.compare(u2.username) == .orderedAscending
            })
            DispatchQueue.main.async( execute: {
                self.participantsTableView.reloadData()
            })
    
    
        }) { (err) in
            print("Failed to fetch users for search:", err)
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    }
    

    这是父对象的代码 :

    import UIKit
    import MapKit
    
    class SingleEventViewController: UIViewController {
    
    var thisEvent: Event
    var eventName: String?
    var eventDescription: String?
    var eventLocation: CLLocationCoordinate2D?
    var eventStartingDate: Date?
    var eventFinishingDate: Date?
    var eventNeedsApplication: Bool?
    
    let padding: CGFloat = 20
    
    //MARK: - GUI Objects
    let scrollView: UIScrollView = {
        let view = UIScrollView()
        return view
    }()
    
    let teilnehmerLabel: UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 20)
        label.text = "Teilnehmer"
        label.textColor = .black
        return label
    }()
    
    let teilnehmerTV: TeilnehmerTableView = {
        let tvt = TeilnehmerTableView()
        tvt.backgroundColor = .brown
        return tvt
    }()
    
    let buttonDividerView: UIView = {
        let tdv = UIView()
        tdv.backgroundColor = UIColor.gray
        return tdv
    }()
    
    let participateButton: UIButton = {
        let button = UIButton()
        button.backgroundColor = CalendarSettings.Colors.buttonBG
        button.setTitle("Teilnehmen", for: .normal)
        button.setTitleColor(CalendarSettings.Colors.darkRed, for: .normal)
        return button
    }()
    
    init(event: Event) {
        thisEvent = event
        super.init(nibName: nil, bundle: nil)
        setupDefaultValues()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        applyDefaultValues()
        setupNavBar()
        setupViews()
        confBounds()
        getSnapshotForLocation()
    }
    
    
    //MARK: - Setup
    func setupDefaultValues() {
        eventName = thisEvent.eventName
        eventDescription = thisEvent.eventDescription
        eventLocation = thisEvent.eventLocation
        eventStartingDate = thisEvent.eventStartingDate
        eventFinishingDate = thisEvent.eventFinishingDate
        eventNeedsApplication = thisEvent.eventNeedsApplication
    }
    
    func applyDefaultValues() {
        titleLabel.text = eventName
        descLabel.text = eventDescription
        if let start = eventStartingDate, let finish = eventFinishingDate {
            timeLabel.text = "Von \(start.getHourAndMinuteAsStringFromDate()) bis \(finish.getHourAndMinuteAsStringFromDate())"
        }
    
        if let location = eventLocation {
            locationLabel.text = getStringFromLocation(location: location)
            mapLabel.text = getStringFromLocation(location: location)
        }
        if let date = eventStartingDate {
            dateLabel.text = formatDate(date: date)
        }
    }
    
    func setupNavBar() {
        self.navigationItem.title = "Event"
    }
    
    func setupViews() {
        view.addSubview(scrollView)
        view.addSubview(participateButton)
        participateButton.addTarget(self, action: #selector (buttonClick), for: .touchUpInside)
        view.addSubview(buttonDividerView)
    
        scrollView.addSubview(teilnehmerLabel)
        scrollView.addSubview(teilnehmerTV)
        teilnehmerTV.parentVC = self
    }
    
    func confBounds(){
        let tabbarHeight = self.tabBarController?.tabBar.frame.height ?? 0
        let tableviewHeight: CGFloat = CGFloat(teilnehmerTV.users.count) * 44
    
        participateButton.anchor(top: nil, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: tabbarHeight, paddingRight: 0, width: 0, height: 50)
        buttonDividerView.anchor(top: nil, left: view.leftAnchor, bottom: participateButton.topAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0.5)
    
        scrollView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: buttonDividerView.topAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
    
    
    
        teilnehmerLabel.anchor(top: descLabel.bottomAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 20, paddingLeft: padding, paddingBottom: 0, paddingRight: padding, width: 0, height: 0)
        teilnehmerTV.anchor(top: teilnehmerLabel.bottomAnchor, left: view.leftAnchor, bottom: scrollView.bottomAnchor, right: view.rightAnchor, paddingTop: 5, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: tableviewHeight)
    }
    
    override func viewDidLayoutSubviews() {
        let objHeight = titleLabel.frame.height + locationLabel.frame.height + dateLabel.frame.height + timeLabel.frame.height + mapView.frame.height + notizenLabel.frame.height + descLabel.frame.height + teilnehmerLabel.frame.height + teilnehmerTV.frame.height
        let paddingHeight = 10+0+50+padding+20+5 - 15
        print(objHeight, paddingHeight)
    
        scrollView.contentSize = CGSize(width: view.frame.width, height: objHeight+paddingHeight)
    }
    
    //MARK: - Methods
    @objc func buttonClick() {
        teilnehmerTV.participantsTableView.reloadData()
        print(teilnehmerTV.participantsTableView.numberOfRows(inSection: 0))
        scrollView.reloadInputViews()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   nebuler    6 年前

    那是因为你没有添加 TeilnehmerTableView SingleEventViewController 当您发出获取请求时-您在的初始化过程中发出请求 TeilnehmerTableView公司 fetchUsers 单事件视图控制器 之后 您已添加 到视图;然后它应该工作。

    推荐文章