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.
What I have for now is only a UITableView with all the posts as a reusable cell from a xib. Since I can't add an UITableView and a cell to this xib, I'm stuck.
Here is some code:
Posts UITableView funcs:
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:
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. You can make the post the section header or just a cell. 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. (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.
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.
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)
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. 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...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.