草庐IT

ios - 分割 UITableView 单元格

coder 2023-09-15 原文

我试图将我的 tableview 单元格组织成列表中项目元素的部分 (dueTime)。 Firebase 是我的后端,每个项目都有一个名为 dueTime 的子节点,其中包含时间字符串。我已经创建了这些部分并让它们显示出来,但我需要将实际项目分成它们。目前,当我运行我的代码时,所有显示的都是部分。

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        let tasksRef = ref.childByAppendingPath("tasks")
        tasksRef.observeSingleEventOfType(.Value, withBlock: {snapshot in
            var dueTimesArray = [String]()
            for task in snapshot.children.allObjects as! [FDataSnapshot] {
                let times = task.value["dueTime"] as! String
                dueTimesArray.append(times)
            }
            self.sectionTimes = dueTimesArray
        })
        let uniqueSectionTimes = Array(Set(sectionTimes))
        return uniqueSectionTimes.count
    }


    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        var uniqueSectionTimes = Array(Set(sectionTimes))
        let tasksRef = Firebase(url: "\(self.ref)/tasks")
        tasksRef.queryOrderedByChild("dueTime").queryEqualToValue(uniqueSectionTimes[section]).observeEventType(.Value, withBlock: { snapshot in
            var newTasks = [Task]()
            for task in snapshot.children.allObjects as! [FDataSnapshot] {
                let tasks = Task(snapshot: task)
                newTasks.append(tasks)
            }
            self.sectionTasks = newTasks
        })
        return self.sectionTasks.count
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! TaskCell

        // Configure the cell...
        cell.selectionStyle = .None
//        let uniqueSectionTimes = Array(Set(sectionTimes))
//        let times = self.sectionTasks[uniqueSectionTimes[indexPath.section]]
        let task = tasks[indexPath.row]
        cell.label.text = task.title
        ref.childByAppendingPath("tasks").observeEventType(.Value, withBlock: { snapshot in
        if task.done == true {
            cell.checkBox.image = UIImage(named: "checkedbox")
            cell.detailLabel.text = "Completed By: \(task.completedBy)"
            }
            else {
            cell.checkBox.image = UIImage(named: "uncheckedbox")
            cell.detailLabel.text = ""
            }
        })

        cell.delegate = self
        return cell
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let uniqueSectionTimes = Array(Set(sectionTimes))

        return uniqueSectionTimes[section]
    }

我觉得问题的根源可能在 numberOfRowsInSection 和 cellForRowAtIndexPath 中。从 numberOfRowsInSection 中,当我将 self.sectionTasks 设置为等于 newTasks 后打印时,我得到 6 个数组(等于部分的数量),其中包含所有正确的任务正确的数组。但是,当我打印 self.sectionTasks.count 时,我得到了六次“0”,这对我来说没有意义。我不知道要在 cellForRowAtIndexPath 中做什么。我似乎无法在任何地方找到很好的解释它的好教程。

更新 1:

我也在 numberOfRows 中尝试过这个

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        var uniqueSectionTimes = Array(Set(sectionTimes))
        let tasksRef = Firebase(url: "\(self.ref)/tasks")
        tasksRef.queryOrderedByChild("dueTime").queryEqualToValue(uniqueSectionTimes[section]).observeEventType(.Value, withBlock: { snapshot in
            var newTasks = [String]()
            for task in snapshot.children.allObjects as! [FDataSnapshot] {
                let tasks = task.value["title"] as! String
                newTasks.append(tasks)
            }
//            for task in snapshot.children.allObjects as! [FDataSnapshot] {
//                let tasks = Task(snapshot: task)
//                newTasks.append(tasks)
//            }
            self.sectionTasks = newTasks
        })
        print(sectionTasks.count)
        return self.sectionTasks.count
    }

我得到了相同的结果。基本上,这种方式只给我项目的标题,而不是每个数组中的整个项目。但它仍然告诉我所有数组的计数都是 0。

更新 2:

在实现以下代码后,我现在在每个部分下复制了所有任务。我想我需要以某种方式过滤任务,但我不确定在哪里或如何做。

 func queryDueTimes(uniqueSectionTimes:Array<String>) {
        let tasksRef = Firebase(url: "\(self.ref)/tasks")
        tasksRef.queryOrderedByChild("dueTime").observeEventType(.Value, withBlock: { snapshot in
            var newTasks = [Task]()
            for task in snapshot.children.allObjects as! [FDataSnapshot] {
                let times = Task(snapshot: task)
                newTasks.append(times)
            }
            self.sectionTasks = newTasks
            print(self.sectionTasks)
            self.tableView.reloadData()
        })
    }

我在 viewDidLoad() 中运行这个函数,并得到一个大数组,其中包含每个任务的所有元素。我想我需要使用 numberOfRows 中的“section”元素,但我不确定如何使用。此外,我正在查看的教程显示了 cellForRow< 中="" indexpath.section=""> 但我只是不确定如何实现这些东西。

解决方案:

我最终完全更改了查询代码,所以我从本地数组而不是 Firebase 中提取数据。

func querySections() -> [String] {
           var sectionsArray = [String]()
        for task in tasks {
            let dueTimes = task.dueTime
            sectionsArray.append(dueTimes)
        }
        let uniqueSectionsArray = Array(Set(sectionsArray)).sort()
        return uniqueSectionsArray
    }


    func queryDueTimes(section:Int) -> [Task] {
        var sectionItems = [Task]()
        for task in tasks {
            let dueTimes = task.dueTime
            if dueTimes == querySections()[section] {
                sectionItems.append(task)
            }
        }
        return sectionItems
    }



    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return querySections().count
    }



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


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! TaskCell

        // Configure the cell...
        cell.selectionStyle = .None
        let times = queryDueTimes(indexPath.section)
        let task = times[indexPath.row]
        cell.label.text = task.title
        if task.done == true {
            cell.checkBox.image = UIImage(named: "checkedbox")
            cell.detailLabel.text = "Completed By: \(task.completedBy)"
            }
            else {
            cell.checkBox.image = UIImage(named: "uncheckedbox")
            cell.detailLabel.text = ""
            }

        cell.delegate = self
        return cell
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return querySections()[section]
    }

最佳答案

发生这种情况是因为对 taskRef.query... 的调用是异步的。并且 numberOfRowsInSection 方法期望此时您已经知道您拥有的行数。

将查询代码移动到其他方法中,例如

func queryDueTimes(uniqueSectionTimes: Array) { 
    let tasksRef = Firebase(url: "\(self.ref)/tasks")
            tasksRef.queryOrderedByChild("dueTime").queryEqualToValue(uniqueSectionTimes[section]).observeEventType(.Value, withBlock: { snapshot in
                var newTasks = [String]()
                for task in snapshot.children.allObjects as! [FDataSnapshot] {
                    let tasks = task.value["title"] as! String
                    newTasks.append(tasks)
                }
    //            for task in snapshot.children.allObjects as! [FDataSnapshot] {
    //                let tasks = Task(snapshot: task)
    //                newTasks.append(tasks)
    //            }
                self.sectionTasks = newTasks


               //IMPORTANT: reload your table here:
                self.tableView.reloadData()
            })
}

然后,从 View Controller 的 viewDidLoad() 方法调用 queryDueTimes 方法:

func viewDidLoad()
{
    super.viewDidLoad()

    var uniqueSectionTimes = Array(Set(sectionTimes))
    self.queryDueTimes(uniqueSectionTimes)
}

关于ios - 分割 UITableView 单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36068601/

有关ios - 分割 UITableView 单元格的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  3. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby - 单元测试文件 I/O 方法 - 2

    我对单元测试还是比较陌生。我用Ruby编写了一个类,它接受一个文件,在该文件中搜索给定的Regex模式,替换它,然后将更改保存回文件。我希望能够为此方法编写单元测试,但我不知道我将如何去做。有人能告诉我我们如何对处理文件i/o的方法进行单元测试吗? 最佳答案 看看这个HowdoIunit-testsavingfiletothedisk?基本上这个想法是一样的,文件系统是你的类的依赖。所以引入一个可以在你的单元测试中模拟的角色/接口(interface)(这样你在单元测试时就没有依赖性);角色中的方法应该是您从文件系统中需要的所有东西

  6. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  7. ruby - 尝试运行 minitest 单元测试时出错 - 2

    尝试使用rubytest/test_foo.rb运行minitest单元测试时出现以下错误:Warning:youshouldrequire'minitest/autorun'instead.Warning:oradd'gem"minitest"'before'require"minitest/autorun"'From:/home/emile/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/minitest/autorun.rb:15:```test_foo.rb看起来像这样:require'minitest/autorun'classTestFoo

  8. ruby 单元测试 : run some code after each failed test - 2

    在Test::Unit中的ruby​​单元测试断言失败后,在执行teardown之前,是否有一些简洁优雅的方法来立即执行我的代码?我正在做一些自动化的GUI测试,并希望在出现问题后立即截图。 最佳答案 如果您使用的是1.9,请不要使用Test::Unit::TestCase作为您的基类。对其进行子类化并覆盖#run_test以进行救援,截取屏幕截图并重新提出:classMyAbstractTestCase或者,我认为这实际上是最简洁的方法,您可以使用before_teardownHook:classMyTestCase这不适用于1.

  9. ruby-on-rails - Ruby on Rails 单表继承(STI)和单元测试问题(使用 PostgreSQL) - 2

    我正在使用带有单个“帐户”表的STI模型来保存用户和技术人员的信息(即用户...8)错误:test_the_truth(用户测试):ActiveRecord::StatementInvalid:PGError:ERROR:关系“技术人员”不存在:从“技术人员”中删除...从本质上讲,标准框架不承认Technicians和Users表(或PostgreSQL称它们为“关系”)不存在,事实上,应该别名为Accounts。有什么想法吗?我对RoR比较陌生,不知道如何解决这个问题而又不完全删除STI。 最佳答案 原来问题是由于存在:./te

  10. ruby-on-rails - 获取当前时间的单元测试代码 - 2

    为获取当前时间的代码编写单元测试的最佳方法是什么?例如,某些对象可能仅在工作日创建,其他对象在检查执行某些操作的权限时会考虑当前时间等。我想我应该模拟Date.today和Time.now。这是正确的做法吗?更新:两种解决方案(a)Time.is和(b)Time.stubs(:now).returns(t)都有效。(a)是非常好的方法,但(b)解决方案将与其他测试代码更加一致。在此question作者要求一个通用的解决方案。对于Ruby,在我的选项中,上述两个解决方案是simpler因此比提取获取当前日期/时间的代码更好。顺便说一句,我建议使用Chronic获得所需的时间,例如requ

随机推荐