1

I'm trying to convert a UITableView with multiple section and dynamic rows.

I'm currently trying to loop through all the subviews of a UITableView. I'm trying to insert each subview into a container UIView where I could combine them all to make up a UIView representing one page for a specific height limit, where I may add a footer dynamically.

Basically the goal is to iterate through all sections, and combine all view for each cell into one big UIView that represents that section including the section header.

This is so I could easily just convert each UIView into specific PDF pages later on. As if I just directly convert the UITableView into PDF, I would get page cuts where I don't want them.

Jojo Narte
  • 2,767
  • 2
  • 30
  • 52
  • it is very unclear , What is your goal to do this – Prashant Tukadiya Feb 14 '18 at 12:49
  • Here is a scenario I currently have. I have this tableview that has multiple sections. I'd like to separate these sections into different UIViews let's call it a page, so that would mean each separate page would contain all rows for a specific section. – Jojo Narte Feb 14 '18 at 12:56
  • can i show you objective c code because i am bad in swift –  Feb 14 '18 at 12:57
  • @JRB I wouldn't mind. :) Please show me. – Jojo Narte Feb 14 '18 at 12:58
  • this may be helpful https://stackoverflow.com/a/41313008/4601900 – Prashant Tukadiya Feb 14 '18 at 13:03
  • This is what you are searching https://github.com/davidman/DHSmartScreenshot loop the rows in section take screenshot for each cell then combine image – Prashant Tukadiya Feb 14 '18 at 13:05
  • Use MVC design pattern, where the delegate is just a `controller`. And when you want to iterate, you just iterate through the model, (just a foreach, filter or reduce). – user9335240 Feb 14 '18 at 13:10
  • @PrashantTukadiya I'd like to stay away from screenshots though. When rendering images to pdfcontext it would result into blurry pdf views. – Jojo Narte Feb 14 '18 at 13:16
  • @user9335240 I'm not having problems iterating on the model, but on the views. – Jojo Narte Feb 14 '18 at 13:16
  • Then see this answer https://stackoverflow.com/a/32115726/4601900 – Prashant Tukadiya Feb 14 '18 at 13:18
  • @PrashantTukadiya yup, tried a similar approach beforehand, it results in blurry pdf. – Jojo Narte Feb 14 '18 at 13:19
  • @JojoNarté use this option . **0.0** at last argument UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0); – Prashant Tukadiya Feb 14 '18 at 13:20
  • @PrashantTukadiya provided that I could convert each cell into image screenshots. The problem still lies that I couldn't get the exact view of each cell that are hidden. How do you do that? – Jojo Narte Feb 14 '18 at 13:30
  • @JojoNarté If you observe that link there is `scrollToRowAtIndexPath` which will scroll that row to screen bounds and take the screnshot of that. so it should works. you should give a try – Prashant Tukadiya Feb 14 '18 at 13:33
  • You talk about cells being hidden but the real problem is that they don't actually exist until you scroll to them and configure them from your model. – Phillip Mills Feb 14 '18 at 14:07

2 Answers2

2

I was able to iterate through all UITableView sections and row through code below:

The logic here is that to be able to get the right subview that I've appended to the cell.contentView, I've set them with a tag before adding them as Subview, so that I would be able to get the exact view that I've added instead of the wrapping contentView.

var subviews = [UIView]()
let sectionCount = tableView.numberOfSections

/// loop through available sections
for section in 0..<sectionCount {

    /// get each section headers
    if let sectionHeader = self.tableView(tableView, viewForHeaderInSection: section) {
        subviews.append(sectionHeader)
    }


    if tableView.numberOfRows(inSection: section) > 0 {
        /// loop through rows within section
        for row in 0..<tableView.numberOfRows(inSection: section) {
            let indexPath = IndexPath(row: row, section: section)
            tableView.scrollToRow(at: indexPath, at: .top, animated: false)
            if let currentCell = tableView.cellForRow(at: indexPath), let view = currentCell.contentView.viewWithTag(999) {
                subviews.append(view)
            }
        }
    }
}
Jojo Narte
  • 2,767
  • 2
  • 30
  • 52
0

The view should be a representation of your model. Having to access the view to know how the controller should be presenting the view seems conceptually wrong.

Views are a representation of your model, thus views are not the source of truth of how they are represented/built. Perhaps you should consider making some utility functions to know what view should be presented instead of iterating through the views/cells to know if you want to group them (do whatever you want with them).

That utility function could be called once the model is updated (can be on the callback of a service call, or in a NSFetchDelegate if you are using a pattern such as MVVM).

Your controller would be alerted by the change and then update the view / tableView / sections (anything you want really) accordingly.

This applies no matter what design pattern you are using (MVC, MVP, etc...)

Swift Rabbit
  • 1,370
  • 3
  • 14
  • 29