简体   繁体   English

如何从 UITableViewCell 内部加载 UITableView?

[英]How to load an UITableView from inside UITableViewCell?

Quick explanation before showing some code:在显示一些代码之前快速解释一下:

I want to create an architecture where I have Posts, replies to these posts and replies to these replies, etc (with a limit that I can define).我想创建一个架构,其中有帖子、对这些帖子的回复和对这些回复的回复等(我可以定义一个限制)。

Which each one of the replies being expandable.每个回复都是可扩展的。

I don't know if I take this the right way but I'm thinking about adding a UITableView as a child of my UITableViewCell to show the replies and do it again for the replies to replies, etc.我不知道我是否采取了正确的方式,但我正在考虑添加一个 UITableView 作为我的 UITableViewCell 的子项,以显示回复并再次为回复等回复。

What I have for now is only a UITableView with all the posts as a reusable cell from a xib.我现在只有一个 UITableView,所有帖子都是来自 xib 的可重复使用的单元格。 Since I can't add an UITableView and a cell to this xib, I'm stuck.由于我无法在此 xib 中添加 UITableView 和单元格,因此我被卡住了。

Here is some code:这是一些代码:

Posts UITableView funcs:帖子 UITableView 功能:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = argumentList.dequeueReusableCell(withIdentifier: "postBox", for: indexPath) as! PostBox
        let currentPost = postListItems[indexPath.row]
        cell.postBoxView.message = currentPost
        return cell
    }

The PostBox file:邮箱文件:

import UIKit

class PostBox: UITableViewCell {
    let apiClient = APIClient.sharedInstance
    @IBOutlet weak var postBoxView: PostBoxView!
}

The PostBoxView file: PostBoxView 文件:

class PostBoxView: UIView {
    var apiClient = APIClient.sharedInstance
    var repliesOpen: Bool = false
    @IBOutlet var contentView: UIView!
    // Bunch of outlets here
    
    var message: Message! {
        didSet {
            // initializing design stuff here
        }
    }
    
    override init(frame: CGRect){
        super.init(frame: frame)
        self.commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.commonInit()
    }
    
    func commonInit(){
        let bundle = Bundle(for: Self.self)
        let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
        nib.instantiate(withOwner: self, options: nil)

        addSubview(contentView)
        contentView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            contentView.topAnchor.constraint(equalTo: topAnchor),
            contentView.bottomAnchor.constraint(equalTo: bottomAnchor),
            contentView.leadingAnchor.constraint(equalTo: leadingAnchor),
            contentView.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
    }
    
    @IBAction func showPostReplies(_ sender: Any) {
        self.toggleReplies(show: true)
    }
    
    func getReplies() {
        apiClient.getReplies(postId: String(self.message.id), sort: "-created_at", perPage: 5, page: 1, completion: { replies in
            print(replies)
        })
    }
    
    func toggleReplies(show: Bool) {
        self.repliesOpen = show
        switch repliesOpen {
        case true:
            self.getReplies()
        case false:
            print("close")
        }
    }
}

So here I am, wondering how I can add replies to my post, then add replies to my replies.所以我在这里,想知道如何将回复添加到我的帖子中,然后将回复添加到我的回复中。 Maybe I'm taking this the wrong way, so a bit of help would be nice.也许我采取了错误的方式,所以有点帮助会很好。

Mate, adding a table view to a table view cell is a really bad idea (so outrageous that I had to open the question).伙计,将表格视图添加到表格视图单元格是一个非常糟糕的主意(太离谱了,我不得不打开这个问题)。

In terms of UI, it's relatively straight-forward.在 UI 方面,它相对简单。 You can make the post the section header or just a cell.您可以将帖子设为 header 部分或只是一个单元格。 Either way, all the replies will be also cells in the same table -- create a different UITableViewCell subclass for them & use indentation to achieve the hierarchy.无论哪种方式,所有回复也将是同一个表中的单元格——为它们创建一个不同的 UITableViewCell 子类并使用缩进来实现层次结构。 (indentationLevel & indentationWidth properties of UITableviewCell) The actions of expand - collapse (getReplies) should be called not in the cell but in the viewController (or viewModel / presenter depending on what you are using) via delegates. (UITableviewCell 的 indentationLevel 和 indentationWidth 属性)展开 - 折叠(getReplies)的操作不应在单元格中调用,而应通过委托在 viewController(或 viewModel / Presenter,取决于您使用的内容)中调用。

Your real concern should be coming up with a top-notch data structure for the table that will store posts + replies + reply expansion state + reply hierarchy level.您真正关心的应该是为表提供一流的数据结构,该表将存储帖子 + 回复 + 回复扩展 state + 回复层次结构级别。

I hope this'll get you started on the right path.我希望这会让你开始走上正确的道路。 (Do not add table view inside a table view cell, you might actually achieve stack overflow if your replies go deep enough) (不要在表格视图单元格中添加表格视图,如果您的回复 go 足够深,您实际上可能会实现堆栈溢出)

Here's a data structure I quickly came up with (doesn't include data fields but everything else you need to get it running.)这是我很快想到的一个数据结构(不包括数据字段,但运行它所需的所有其他内容。)

protocol Repliable {
    var replies: [Repliable] {get}
    var replyLevel: Int {get}
    var isPost: Bool {get}
}

struct Post: Repliable {
    //data fields
    
    let isPost = true
    let replyLevel = 0
    var replies: [Repliable]
}

struct Reply: Repliable {
    //data fields
    
    let isPost = false
    var replyLevel: Int
    var replies: [Repliable]
}

To use it, your tableview should use an array of Repliable.要使用它,您的 tableview 应该使用 Repliable 数组。 Each time you expand (fetch) replies you simply add them at the correct location in the array & add rows to the table.每次展开(获取)回复时,您只需将它们添加到数组中的正确位置并将行添加到表中。 Your challenge now is just to keep them properly ordered in the array.您现在面临的挑战只是让它们在数组中正确排序。 Like so -> Post 1, Reply 1, Reply1 to Reply1, Reply 2, Post 2...像这样 -> 发帖 1、回复 1、回复 1 到回复 1、回复 2、发帖 2...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM