iosuitableviewuicollectionviewswift4realm-database

Set UICollectionView embedded in UITableViewCell


I have a UITableView that contains a list of categories (in this example, list of sports types i.e. Water and Land based)

Each cell in this table then has a list of sports associated with the type of sport displayed in a nested UICollectionView. For example, water based will have Surfing and swimming.

Think Netflix - with Vertical scrolling categories with horizontally scrollable subcategories.

Here is example JSON (Note that the JSON shown is just to describe the structure. I have in fact stored this in RealmDb)

{
"category": [
    {
        "title": "Sport Listings",
        "category_content": [
            {
                "title": "Water Based",
                "category_content": [
                    {
                        "title": "Surfing"
                    }, {
                        "title": "Swimming"
                    }, {
                        "title": "Snorkelling"
                    }, {
                        "title": "Tombstoning"
                    }
                ]
            },
            {
                "title": "Land Based",
                "category_content": [
                    {
                        "title": "Football"
                    }, {
                        "title": "Rugby"
                    }
                ]
            }
        ]
    }
]
}

I have the table correctly populated with two cells ("water Based" and "Land Based") but i am now having trouble understanding how to parse the count and data to each of the tables rows' collection view so that i can set the text for each collection view delegate.

If i just set the collection view count for each table row to an random value then get each cell text to display the row index, it is displaying the correct index. I did this to eliminate any layout issues.

Does anyone have any pointers? From examples i've seen already, the nested UICollectionView count is being hardcoded instead of dynamic as same with the delegate content (same image/text)

I haven't posted any code as it has become a complete mess whilst i've tried to figure it out. If needed i can strip it back and put it up here.


Solution

  • In my opinion a tableview should only be used when you want to take advantage of its main features: Recycling in order to support a large number of cells, and other features like search, alphabetizer, etc. I would rather use a vertical stack view and manage your collection views yourself, rather than having them in cells. I would imagine having your collection views recycled as you scroll would be a nightmare - because the same cell instance would be reused - but now it would have the wrong collection view in it, as you scroll down.

    If you will only have less than 10 rows in this table view, I would use a Vertical orientation Stackview. You don't need cells or recycling. When I used table views for vertical layouts before, I ran into problems with state cleanup and bleeding of elements across recycled cells.

    I would probably break out each collection view's delegate into a separate class.

    To answer your main question: If you still want to use a tableview, set the reuseIdentifier to a unique value for each row, so recycling doesn't take place. And manage an array of data source objects, to assign to each of your collection views in cellForRow of your tableView method.

    Another option is to have each cell be the dataSource for each collection view - so it's completely self contained, by making a custom UITableViewCell subclass that serves as both a datasource and UI container for your collection view. Then injecting a universal data model into that cell in cellForRow method (that would work for all types of collection views - regardless of data type).

    I'd keep the datasources as separate objects though, and inject them into the cells, because to me a cell should just be a "shell" - a UI layout element and shouldn't hold the details of a dataSource (that way the dataSource can be re-used in other places too, not just that cell)