首页 > 解决方案 > Swift Firebase 选择 UITableView 原型单元 - UI 问题

问题描述

有用户从 firebase 下载并显示在 UITableView 上,其中单元格是可选择的,一旦选择将有一个复选标记。所以从firebase是异步下载的,所以我认为这可能是我解决问题的开始,但不确定。When selecting lets say two cells when the view appears and then you begin scrolling through the list other cells will appear to be selected when the user did not select them. 下面将是发生的代码和图片。

Firebase 通话

func getTableViewData() {
    Database.database().reference().child("Businesses").queryOrdered(byChild: "businessName").observe(.childAdded, with: { (snapshot) in
        let key = snapshot.key
        
        if(key == self.loggedInUser?.uid) {
            print("Same as logged in user, so don't show!")
        } else {
            if let locationValue = snapshot.value as? [String: AnyObject] {
                let lat = Double(locationValue["businessLatitude"] as! String)
                let long = Double(locationValue["businessLongitude"] as! String)
                let businessLocation = CLLocation(latitude: lat!, longitude: long!)
                
                let latitude = self.locationManager.location?.coordinate.latitude
                let longitude = self.locationManager.location?.coordinate.longitude
                let userLocation = CLLocation(latitude: latitude!, longitude: longitude!)
                
                let distanceInMeters: Double = userLocation.distance(from: businessLocation)
                let distanceInMiles: Double = distanceInMeters * 0.00062137
                let distanceLabelText = String(format: "%.2f miles away", distanceInMiles)
                
                var singleChildDictionary = locationValue
                singleChildDictionary["distanceLabelText"] = distanceLabelText as AnyObject
                singleChildDictionary["distanceInMiles"] = distanceInMiles as AnyObject
                self.usersArray.append(singleChildDictionary as NSDictionary)
                self.usersArray = self.usersArray.sorted {
                    !($0?["distanceInMiles"] as! Double > $1?["distanceInMiles"] as! Double)
                }
            }
            //insert the rows
            //self.followUsersTableView.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
            self.listedBusiness.reloadData()
        }
    }) { (error) in
        print(error.localizedDescription)
    }
    
}

表视图设置

// MARK: - Table view data source

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

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    if searchController.isActive && searchController.searchBar.text != ""{
        return filteredUsers.count
    }
    return self.usersArray.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomerAddSelectedBusinessesCell
    
    var user : NSDictionary?
    
    if searchController.isActive && searchController.searchBar.text != ""{
        
        user = filteredUsers[indexPath.row]
    } else {
        user = self.usersArray[indexPath.row]
    }
    
    if cell.isSelected == true {
        
        var user = self.usersArray[indexPath.row]
        
        if CLLocationManager.locationServicesEnabled() {
            switch(CLLocationManager.authorizationStatus()) {
            case .notDetermined, .restricted, .denied:
                print("No access")
                cell.businessName.text = String(user?["businessName"] as! String)
                cell.businessStreet.text = String(user?["businessStreet"] as! String)
                cell.businessCity.text = String(user?["businessCity"] as! String)
                //cell.selectedCell.image = UIImage(named: "cellSelected")
                
                let businessProfilePicture = String(user?["profPicString"] as! String)
                if (businessProfilePicture.count) > 0 {
                    let url = URL(string: (businessProfilePicture))
                    DispatchQueue.global().async {
                        let data = try? Data(contentsOf: url!)
                        DispatchQueue.main.async {
                            let image = UIImage(data: data!)?.potter_circle
                            cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                            cell.businessImage.image = image
                        }
                    }
                } else {
                    let image = UIImage(named: "default")?.potter_circle
                    cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                    cell.businessImage.image = image
                }
                
                //cell.profileImage.image =
            //cell.businessDistance.text = String(user?["distanceLabelText"] as! String)
            case .authorizedAlways, .authorizedWhenInUse:
                print("Access")
                print("****Called")
                cell.businessName.text = String(user?["businessName"] as! String)
                cell.businessStreet.text = String(user?["businessStreet"] as! String)
                cell.businessCity.text = String(user?["businessCity"] as! String)
                cell.businessDistance.text = String(user?["distanceLabelText"] as! String)
                //cell.selectedCell.image = UIImage(named: "cellSelected")
                
                let businessProfilePicture = String(user?["profPicString"] as! String)
                if (businessProfilePicture.count) > 0 {
                    let url = URL(string: (businessProfilePicture))
                    DispatchQueue.global().async {
                        let data = try? Data(contentsOf: url!)
                        DispatchQueue.main.async {
                            let image = UIImage(data: data!)?.potter_circle
                            cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                            cell.businessImage.image = image
                        }
                    }
                } else {
                    let image = UIImage(named: "default")?.potter_circle
                    cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                    cell.businessImage.image = image
                }
            }
        } else {
            print("Location services are not enabled")
        }
        
    } else if cell.isSelected == false {
        
        var user = self.usersArray[indexPath.row]
        
        if CLLocationManager.locationServicesEnabled() {
            switch(CLLocationManager.authorizationStatus()) {
            case .notDetermined, .restricted, .denied:
                print("No access")
                cell.businessName.text = String(user?["businessName"] as! String)
                cell.businessStreet.text = String(user?["businessStreet"] as! String)
                cell.businessCity.text = String(user?["businessCity"] as! String)
                //cell.selectedCell.image = UIImage(named: "cellNotSelected")
                
                let businessProfilePicture = String(user?["profPicString"] as! String)
                if (businessProfilePicture.count) > 0 {
                    let url = URL(string: (businessProfilePicture))
                    DispatchQueue.global().async {
                        let data = try? Data(contentsOf: url!)
                        DispatchQueue.main.async {
                            let image = UIImage(data: data!)?.potter_circle
                            cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                            cell.businessImage.image = image
                        }
                    }
                } else {
                    let image = UIImage(named: "default")?.potter_circle
                    cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                    cell.businessImage.image = image
                }
                
                //cell.profileImage.image =
            //cell.businessDistance.text = String(user?["distanceLabelText"] as! String)
            case .authorizedAlways, .authorizedWhenInUse:
                print("Access")
                print("%called")
                cell.businessName.text = String(user?["businessName"] as! String)
                cell.businessStreet.text = String(user?["businessStreet"] as! String)
                cell.businessCity.text = String(user?["businessCity"] as! String)
                cell.businessDistance.text = String(user?["distanceLabelText"] as! String)
                //cell.selectedCell.image = UIImage(named: "cellNotSelected")
                
                let businessProfilePicture = String(user?["profPicString"] as! String)
                if (businessProfilePicture.count) > 0 {
                    let url = URL(string: (businessProfilePicture))
                    DispatchQueue.global().async {
                        let data = try? Data(contentsOf: url!)
                        DispatchQueue.main.async {
                            let image = UIImage(data: data!)?.potter_circle
                            cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                            cell.businessImage.image = image
                        }
                    }
                } else {
                    let image = UIImage(named: "default")?.potter_circle
                    cell.businessImage.contentMode = UIView.ContentMode.scaleAspectFill
                    cell.businessImage.image = image
                }
            }
        } else {
            print("Location services are not enabled")
        }
    }
    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomerAddSelectedBusinessesCell
    
    let user = usersArray[indexPath.row]
    let name = user!["uid"] as? String
    var NSdata = NSDictionary()
    var realArray = [NSDictionary]()

    if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
        if cell.accessoryType == .checkmark{
            cell.accessoryType = .none
            print("Deleted \(name!)")
            if let idx = data.index(of:name!) {
                data.remove(at: idx)
                print(data)
            }
        } else {
            cell.accessoryType = .checkmark
            data.append(name!)
            print(data)
        }
    }
    print(data)
}

视图加载后选定的单元格

在此处输入图像描述

看似已选中但未选中的单元格 在此处输入图像描述

标签: iosswiftfirebaseuitableview

解决方案


这是最常见的细胞可重复使用问题。当您滚动时,屏幕上可见的单元格将被重复使用。例如。您有 5 个可见的单元格。当您选择 2,3 并向下滚动时,将选择 7,8。为避免这种情况,您有 2 个选择。

  1. 您可以使用外部 Bool 数组来管理它(Bool 数组计数必须与您的数组计数相同)。
  2. 您可以将 bool 变量放入用户字典中来管理它。

因此,每当您滚动时,不会自动选择新可见的单元格。


推荐阅读