【问题标题】:Strange behavior in table view after deleting event删除事件后表格视图中的奇怪行为
【发布时间】:2020-04-23 00:57:27
【问题描述】:

我正在开发一款让用户注册志愿活动的应用,目前正在努力让他们查看自己的活动并取消注册。

这是用户要求查看他们的事件时看到的屏幕,在这种情况下,这两个事件被称为“ok”和“that”(我刚刚创建了一些随机测试事件)。当您单击一个时,您会看到以下屏幕:

当您单击取消注册时,该事件将从您的已注册事件中删除,但表视图现在有两个相同的事件。

当我点击返回,然后回到表格视图时,一切正常,在这种情况下只显示“ok”事件,因为另一个被删除了。这是tableview布局的代码:

override func viewDidLoad() {
    super.viewDidLoad()
    yourArray = []
    actualEvents = []
    let id = Auth.auth().currentUser?.uid
    Database.database().reference().child("users").child(id!).child("registeredEvents").observe(.value) { snapshot in
          let children = snapshot.children
             while let rest = children.nextObject() as? DataSnapshot, let value = rest.value {
                print(value)
                  self.yourArray.append(value as! String)
              }
               Database.database().reference().child("Events").observe(.value) { (data) in
                    let events = data.value as! [String:[String:Any]]
                    for(_,value) in events{
                        if(self.yourArray.contains(value["EventName"]! as! String)){
                            self.actualEvents.append(PersonalEvents(evName: value["EventName"]! as! String, evDesc: value["EventDescription"]! as! String, evStartDate: value["start time"]! as! String, evEndDate: value["end time"] as! String, evNumPeople: value["NumberOfPeople"]! as! Int, evNumRegistered: value["currentPeople"] as! Int))
                           }
                        }
                        print("Actual events array " + "\(self.actualEvents)")
                  }
            self.tblEvents.reloadData()
        }
        print(yourArray)
        self.tblEvents.dataSource = self
        self.tblEvents.delegate = self
    }

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return yourArray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "productstable", for: indexPath)
    cell.textLabel?.text = self.yourArray[indexPath.row]
    return cell
}

还有注销按钮(这是在不同的视图控制器中,因为在不同的视图中显示有关事件的信息):

 @IBAction func didUnregister(_ sender: Any) {
    let id = Auth.auth().currentUser?.uid
    let ref = Database.database().reference()
    ref.child("users").child(id!).child("registeredEvents").child(personalEventInfo!.eventName!).removeValue { error,arg  in
      if error != nil {
          print("error \(error)")
      }
    }
    let event = ref.child("Events")
    event.child(personalEventInfo!.eventName!).observeSingleEvent(of: .value) { (snapshot) in
        let value = snapshot.value as! NSDictionary
        var currentPeople = value["currentPeople"] as! Int
        currentPeople = currentPeople - 1
    Database.database().reference().child("Events").child(self.personalEventInfo!.eventName!).child("currentPeople").setValue(currentPeople)
    }
}

如果这令人困惑,请告诉我,如果不是,请告诉我为什么会发生这种情况,以及我可以做些什么来解决它。

【问题讨论】:

  • 这有点令人困惑,但请尝试在取消注册事件后致电tblEvents.reloadData() 看看是否有帮助。此外,您不需要在任何地方使用self。尝试阅读有关它的简短博客文章。例如self.tblEvents.dataSource 你不需要在那里使用self。当您更新您的数据源时,例如添加我们为您的tableview 删除的对象时,您还需要通知您的tableView 以更新其视图(单元格)。
  • 对不起,我应该提到注销是在不同的类中,这意味着我不能做 tblEvents.reloadData()

标签: ios swift firebase-realtime-database tableview swift4


【解决方案1】:
  • 先删除数组中的项目,然后再将数据追加到其中。
  • 改进:您需要通过在这些闭包中使用 [weak self] 来保护自己的记忆。

您可以尝试以下方法吗:

 Database.database().reference().child("users").child(id!).child("registeredEvents").observe(.value) { [weak self] snapshot in

    let children = snapshot.children
    self?.yourArray.removeAll()
         while let rest = children.nextObject() as? DataSnapshot, let value = rest.value {
            print(value)
              self?.yourArray.append(value as! String)
          }

    Database.database().reference().child("Events").observe(.value) { [weak self] (data) in
                let events = data.value as! [String:[String:Any]]

                self?.actualEvents.removeAll()
                for(_,value) in events{
                    if(self?.yourArray.contains(value["EventName"]! as! String)){
                        self?.actualEvents.append(PersonalEvents(evName: value["EventName"]! as! String, evDesc: value["EventDescription"]! as! String, evStartDate: value["start time"]! as! String, evEndDate: value["end time"] as! String, evNumPeople: value["NumberOfPeople"]! as! Int, evNumRegistered: value["currentPeople"] as! Int))
                       }
                    }
                    print("Actual events array " + "\(self?.actualEvents)")
              }
        self?.tblEvents.reloadData()
    }

【讨论】:

  • 我试过你说的,由于某种原因,它偶尔会抛出一个错误线程 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) on line "if(self?.yourArray.contains (value["EventName"]!as!String)){".当我单击取消注册或注册时会发生这种情况,但只会偶尔发生一次。你知道是什么原因造成的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多