{"id":2847,"url":"https://github.com/TimOliver/TORoundedTableView","last_synced_at":"2025-08-03T12:31:23.586Z","repository":{"id":56923082,"uuid":"75164503","full_name":"TimOliver/TORoundedTableView","owner":"TimOliver","description":"A subclass of UITableView that styles it like Settings.app on iPad","archived":false,"fork":false,"pushed_at":"2020-04-13T04:57:26.000Z","size":671,"stargazers_count":160,"open_issues_count":1,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-27T17:38:27.187Z","etag":null,"topics":["cocoapods","ios","rounded-corners","uitableview"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TimOliver.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-30T07:55:42.000Z","updated_at":"2024-05-08T22:48:12.000Z","dependencies_parsed_at":"2022-08-20T22:20:15.357Z","dependency_job_id":null,"html_url":"https://github.com/TimOliver/TORoundedTableView","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimOliver%2FTORoundedTableView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimOliver%2FTORoundedTableView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimOliver%2FTORoundedTableView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimOliver%2FTORoundedTableView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TimOliver","download_url":"https://codeload.github.com/TimOliver/TORoundedTableView/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228543146,"owners_count":17934433,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cocoapods","ios","rounded-corners","uitableview"],"created_at":"2024-01-05T20:16:24.400Z","updated_at":"2024-12-07T00:30:59.544Z","avatar_url":"https://github.com/TimOliver.png","language":"Objective-C","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=M4RKULAVKV7K8"],"categories":["UI"],"sub_categories":["Table View / Collection View","Layout","Other free courses"],"readme":"# TORoundedTableView\n\n![TORoundedTableView](screenshot.jpg)\n\n[![CI](https://github.com/TimOliver/TORoundedTableView/workflows/CI/badge.svg)](https://github.com/TimOliver/TORoundedTableView/actions?query=workflow%3ACI)\n[![Version](https://img.shields.io/cocoapods/v/TORoundedTableView.svg?style=flat)](http://cocoadocs.org/docsets/TORoundedTableView)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/TimOliver/TORoundedTableView/master/LICENSE)\n[![Platform](https://img.shields.io/cocoapods/p/TORoundedTableView.svg?style=flat)](http://cocoadocs.org/docsets/TORoundedTableView)\n[![Beerpay](https://beerpay.io/TimOliver/TORoundedTableView/badge.svg?style=flat)](https://beerpay.io/TimOliver/TORoundedTableView)\n[![PayPal](https://img.shields.io/badge/paypal-donate-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=M4RKULAVKV7K8)\n[![Twitch](https://img.shields.io/badge/twitch-timXD-6441a5.svg)](http://twitch.tv/timXD)\n\n***As of iOS 13, Apple has released an official version of this table view style called [`UITableViewStyleInsetGrouped`](https://developer.apple.com/documentation/uikit/uitableviewstyle/uitableviewstyleinsetgrouped)! Yay! In order to officially adopt this style, while still providing backwards compatibility to iOS 11, I've created a new library called [`TOInsetGroupedTableView`](https://github.com/TimOliver/TOInsetGroupedTableView). Moving forward, please only use `TORoundedTableView` if you still need to support iOS 10 or lower in your apps. :)***\n\n`TORoundedTableView` is a subclass of the standard UIKit `UITableView` class. Harkening back to the days of iOS 6, it overrides the standard grouped `UITableView` appearence and behaviour to match the borderless, rounded corner style seen in the Settings app on every iPad since iOS 7.\n\nAs iOS device screens increased (Like iPhone 6 Plus and the original iPad Pro), there are a lot of UI design cases where the 'edge-to-edge' style of the stock grouped `UITableView` doesn't make sense, and will end up looking rather distorted in ultra-wide regions.\n\n# Features\n\n* Integrates with `UITableViewController` (On account of the `tableView` property being mutable!)\n* Relatively autonomous operation with only a few extra APIs required.\n* Optimized to the absolute nth-degree to ensure no drops in performance or broken animations.\n* Reverts back to the standard table view style in compact trait collections (Just like in Settings.app)\n* Corner radius graphics are procedurally generated and can be customized on the fly.\n\n# Sample Code\n\n`TORoundedTableView` can easily be integrated into `UITableViewController` all you need to do is replace the `UITableView` object stored in the controller's `tableView` property befor it is shown on-screen.\n\n`TORoundedTableView` tries to be as hands-off as possible in the amount of extra `delegate` / `dataSource` code necessary to write. However, in order to ensure maximum efficiency, a few extra bits of code are required:\n\nIn a standard `UITableViewController` implementing `TORoundedTableView`, the `tableView:cellForRowAtIndexPath:` data source method would look like this:\n\n```objc\n- (UITableViewCell *)tableView:(TORoundedTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath\n{\n    /*\n     Because the first and last cells in a section (dubbed the 'cap' cells) do a lot of extra work on account of the rounded corners,\n     for ultimate efficiency, it is recommended to create those ones separately from the ones in the middle of the section.\n    */\n    \n    // Create identifiers for standard cells and the cells that will show the rounded corners\n    static NSString *cellIdentifier     = @\"Cell\";\n    static NSString *capCellIdentifier  = @\"CapCell\";\n    \n    // Work out if this cell needs the top or bottom corners rounded (Or if the section only has 1 row, both!)\n    BOOL isTop = (indexPath.row == 0);\n    BOOL isBottom = indexPath.row == ([tableView numberOfRowsInSection:indexPath.section] - 1);\n    \n    // Create a common table cell instance we can configure\n    UITableViewCell *cell = nil;\n    \n    // If it's a non-cap cell, dequeue one with the regular identifier\n    if (!isTop \u0026\u0026 !isBottom) {\n        TORoundedTableViewCell *normalCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];\n        if (normalCell == nil) {\n            normalCell = [[TORoundedTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];\n        }\n        \n        cell = normalCell;\n    }\n    else {\n        // If the cell is indeed one that needs rounded corners, dequeue from the pool of cap cells\n        TORoundedTableViewCapCell *capCell = [tableView dequeueReusableCellWithIdentifier:capCellIdentifier];\n        if (capCell == nil) {\n            capCell = [[TORoundedTableViewCapCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:capCellIdentifier];\n        }\n        \n        // Configure the cell to set the appropriate corners as rounded\n        capCell.topCornersRounded = isTop;\n        capCell.bottomCornersRounded = isBottom;\n        cell = capCell;\n    }\n\n    // Configure the cell's label\n    cell.textLabel.text = [NSString stringWithFormat:@\"Cell %ld\", indexPath.row+1];\n    \n    // Since we know the background is white, set the label's background to also be white for performance optimizations\n    cell.textLabel.backgroundColor = [UIColor whiteColor];\n    cell.textLabel.opaque = YES;\n    \n    // Return the cell\n    return cell;\n}\n```\n\n# Installation\n\n`TORoundedTableView` will work with iOS 8 and above. While written in Objective-C, it should easily import into Swift as well.\n\n## Manual Installation\n\nTo manually install this library in your app, simply [download a copy of this repo](https://github.com/TimOliver/TORoundedTableView/archive/master.zip). When the download has completed, copy the contents of the `TORoundedTableView` folder to your app project folder, and then import it into your Xcode project.\n\n## CocoaPods\n\nTo integrate `TORoundedTableView`, simply add the following to your podfile:\n\n```\npod 'TORoundedTableView'\n```\n\n## Carthage\n\nTo integrate `TORoundedTableView`, simply add the following to your Cartfile:\n\n```\ngithub \"TimOliver/TORoundedTableView\"\n```\n\n# Classes\n\n`TORoundedTableView` consists of 4 separate classes that are used in tandem together to achieve the desired functionality.\n\n### `TORoundedTableView`\n\nA very basic subclass wrapper for `UITableView` that overrides the original 'edge-to-edge' philosophy by manually re-laying out all of the content views in a more narrow column. It also creates and manages the rounded corner image assets, so they can be efficiently shared amongst all cells.\n\n### `TORoundedTableViewCell`\n\nA very small wrapper for `UITableViewCell` that internally overrides the cell's `frame` property, constraining all cells to the narrower column width of the parent `TORoundedTableView`.\n\n### `TORoundedTableViewCapCell`\n\nA subclass of `TORoundedTableViewCell` that provides the additional logic needed to manage the views responsible for drawing the rounded corners, and overriding the `UITableViewCell` behaviour of placing hairline borders on the top and bottoms of sections.\n\n### `TORoundedTableViewCellBackground`\nThe view in charge of drawing the rounded edges on the cells at the top and bottom of the section, instances are set as the `backgroundView` and `selectedBackgroundView` for each `TORoundedTableViewCapCell`. The drawing is handled by 3 solid `CALayer` objects that fill the view, and 4 additional `CALayer` objects that draw the rounded edge image in each corner.\n\n`CALayer` objects were used instead of `UIView` to avoid `UITableViewCell`'s implicit behaviour of making `backgroundView` subviews transparent when tapped, and the laying out of a grid of layers was to ensure only the elements in the corner needed alpha-blending (For performance reasons).\n\n# Contributing\nThis view is still very much in its infancy, and a lot of it hasn't been tested beyond what's in the example app. If you have a specific use case for this view, or an idea to make it better, I'd love to hear about it. Please [file an issue](https://github.com/TimOliver/TORoundedTableView/issues) outlining it, and if you're up for filing a PR, that would be fantastic.\n\n# Why build this?\n\nSince a similar style of `UITableView` has been prevalent in Settings.app on iPad since 2013, I'd always assumed that it was relatively trivial to modify a table view to that style if ever needed.\n\nThat assumption was put to the test one week back in 2016 when I needed to create a login view controller for a test app I was building at work. It turns out that assumption was very wrong and overriding `UITableView`'s edge-to-edge design scheme is actually incredibly difficult.\n\nGiven the time constraints at work, I came up with a 'compromise' that let me deliver the code on time, but I was left being really curious to see if this sort of table view style could actually be done 'properly'.\n\nSo I decided to spend several evenings this past week to implement a more elegant version of the same idea.\n\nIt turns out it really isn't easy. `UITableView` tries to reset its UI on every tick of `layoutSubviews`, and `UITableViewCell` has a lot of implicit behaviour that messed with the 'cap' background views.\n\nIn any case, after much perseverance I'm really happy I managed to get it working to a point where it's indistinguishable from the Settings.app table view. It's this sort of thrill I absolutely love in programming. :D\n\n# Credits\n\n`TORoundedTableView` was created by [Tim Oliver](http://twitter.com/TimOliverAU) as an experiment in insanity of reliably hacking `UITableView`.\n\niPhone XR device mockup by [Pixeden](http://www.pixeden.com).\n\n# License\n\n`TORoundedTableView` is available under the MIT license. Please see the [LICENSE](LICENSE) file for more information. ![analytics](https://ga-beacon.appspot.com/UA-5643664-16/TORoundedTableView/README.md?pixel)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTimOliver%2FTORoundedTableView","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTimOliver%2FTORoundedTableView","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTimOliver%2FTORoundedTableView/lists"}