Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karthikAdaptavant/870acd93b1ef9a45ffed6866ae40d045 to your computer and use it in GitHub Desktop.
Save karthikAdaptavant/870acd93b1ef9a45ffed6866ae40d045 to your computer and use it in GitHub Desktop.
FetchedResultsTableViewController
public class FetchedResultsTableViewController<Entity: NSFetchRequestResult, Content: View>: UITableViewController {
private let reuseIdentifier = "FetchedResultsCell"
private let fetchedResultsController: NSFetchedResultsController<Entity>
private var selectionType: SelectionType = .single
private var cellSelectionStyle: UITableViewCell.SelectionStyle = .default
private let baseQuery: Query<Entity>
private var cellContent: (Entity, _ isSelected: Bool) -> Content
private var didSelectRow: ((Entity) -> Void)?
public init(parentView: FetchedResultsTableViewControllerWrapper<Entity, Content>, context: NSManagedObjectContext) {
self.cellContent = parentView.cellContent
self.didSelectRow = parentView.didSelectRow
self.baseQuery = parentView.query
self.selectionType = parentView.selectionType
self.cellSelectionStyle = parentView.cellSelectionStyle
let entityName = String(describing: Entity.self)
let fetchRequest: NSFetchRequest<Entity> = NSFetchRequest<Entity>(entityName: entityName)
fetchRequest.sortDescriptors = baseQuery.sortDescriptors
fetchRequest.predicate = baseQuerySet.predicate
fetchRequest.fetchBatchSize = 20 //
self.fetchedResultsController = NSFetchedResultsController(
fetchRequest: fetchRequest,
managedObjectContext: context,
sectionNameKeyPath: nil,
cacheName: nil
)
super.init(style: .plain)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
}
// MARK: - Table view data source
override public func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultsController.sections?.count ?? 0
}
override public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fetchedResultsController.sections?[section].numberOfObjects ?? 0
}
override public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
/// Workaround: Clear subviews from reused cells
/// Sometimes old cell weren't clearning out which retained in memory.
cell.contentView.subviews.forEach { $0.removeFromSuperview() }
cell.selectionStyle = cellSelectionStyle
let item = fetchedResultsController.object(at: indexPath)
let isItemSelected = selectedEntities.contains(item)
let cellContentView = cellContent(item, isItemSelected)
let hostingController = UIHostingController(rootView: cellContentView)
hostingController.view.frame = cell.contentView.bounds
hostingController.view.backgroundColor = .clear
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(hostingController.view)
NSLayoutConstraint.activate([
hostingController.view.leadingAnchor.constraint(equalTo: cell.contentView.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: cell.contentView.trailingAnchor),
hostingController.view.topAnchor.constraint(equalTo: cell.contentView.topAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: cell.contentView.bottomAnchor)
])
hostingController.didMove(toParent: self)
return cell
}
public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
fileprivate func updateQueryIfNeeded(with searchText: String?) {
// Update your search query here.
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment