{"id":21619095,"url":"https://github.com/bannzai/spreadsheetview","last_synced_at":"2025-05-14T13:08:55.545Z","repository":{"id":38446592,"uuid":"90953887","full_name":"bannzai/SpreadsheetView","owner":"bannzai","description":"Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if you are using Excel.","archived":false,"fork":false,"pushed_at":"2024-05-10T07:06:38.000Z","size":7458,"stargazers_count":3534,"open_issues_count":50,"forks_count":459,"subscribers_count":79,"default_branch":"master","last_synced_at":"2025-04-10T01:05:57.732Z","etag":null,"topics":["gantt-chart","grid-layout","ios","schedule","spreadsheet","timetable"],"latest_commit_sha":null,"homepage":"","language":"HTML","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/bannzai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-11T08:05:23.000Z","updated_at":"2025-04-02T23:55:02.000Z","dependencies_parsed_at":"2024-06-18T13:43:12.818Z","dependency_job_id":"886225d4-d347-44da-9255-c6a4bf382acb","html_url":"https://github.com/bannzai/SpreadsheetView","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bannzai%2FSpreadsheetView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bannzai%2FSpreadsheetView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bannzai%2FSpreadsheetView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bannzai%2FSpreadsheetView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bannzai","download_url":"https://codeload.github.com/bannzai/SpreadsheetView/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137888,"owners_count":21053775,"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":["gantt-chart","grid-layout","ios","schedule","spreadsheet","timetable"],"created_at":"2024-11-24T23:07:53.760Z","updated_at":"2025-04-10T01:06:09.465Z","avatar_url":"https://github.com/bannzai.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"Resources/Logo.png\"  style=\"width: 400px;\" width=\"400\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://travis-ci.org/kishikawakatsumi/SpreadsheetView\"\u003e\n        \u003cimg src=\"https://travis-ci.org/kishikawakatsumi/SpreadsheetView.svg?branch=master\u0026style=flat\"\n             alt=\"Build Status\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/kishikawakatsumi/SpreadsheetView\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/kishikawakatsumi/SpreadsheetView/branch/master/graph/badge.svg\" alt=\"Codecov\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://cocoapods.org/pods/SpreadsheetView\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/v/SpreadsheetView.svg?style=flat\"\n             alt=\"Pods Version\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://cocoapods.org/pods/SpreadsheetView/\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/p/SpreadsheetView.svg?style=flat\"\n             alt=\"Platforms\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-brightgreen.svg?style=flat\"\n             alt=\"Carthage Compatible\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n----------------\n\nFull configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, Gantt chart, timetable as if you are using Excel.\n\n\u003cimg src=\"Resources/DailySchedule_portrait.png\" style=\"width: 300px; height: 534px;\" width=\"300\" height=\"534\"\u003e\u003c/img\u003e\u0026nbsp;\u003cimg src=\"Resources/DailySchedule_landscape.png\" style=\"width: 534px; height: 300px;\" width=\"534\" height=\"300\"\u003e\u003c/img\u003e\u003cbr\u003e\n\u003cimg src=\"Resources/Timetable.png\" style=\"width: 300px; height: 534px;\" width=\"300\" height=\"534\"\u003e\u003c/img\u003e\u0026nbsp;\n\u003cimg src=\"Resources/GanttChart.png\" style=\"width: 534px; height: 300px;\" width=\"534\" height=\"300\"\u003e\u003c/img\u003e\n\n## Features\n- [x] Fixed column and row headers\n- [x] Merge cells\n- [x] Circular infinite scrolling automatically\n- [x] Customize gridlines and borders for each cell\n- [x] Customize inter cell spacing vertically and horizontally\n- [x] Fast scrolling, memory efficient\n- [x] `UICollectionView` like API\n- [x] Well unit tested\n\n##### Find the above displayed examples in the [`Examples`](https://github.com/kishikawakatsumi/SpreadsheetView/tree/master/Examples) folder.\n\n## Requirements\nSpreadsheetView is written in Swift 5. Compatible with iOS 9.0+\n\n## Installation\n\n### CocoaPods\nSpreadsheetView is available through [CocoaPods](https://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod 'SpreadsheetView'\n```\n\n### Carthage\nFor [Carthage](https://github.com/Carthage/Carthage), add the following to your `Cartfile`:\n\n```ogdl\ngithub \"kishikawakatsumi/SpreadsheetView\"\n```\n\n## Getting Started\n\nThe minimum requirement is connecting a data source to return the number of columns/rows, and each column width/row height.\n\n```swift\nimport UIKit\nimport SpreadsheetView\n\nclass ViewController: UIViewController, SpreadsheetViewDataSource {\n    @IBOutlet weak var spreadsheetView: SpreadsheetView!\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        spreadsheetView.dataSource = self\n    }\n\n    func numberOfColumns(in spreadsheetView: SpreadsheetView) -\u003e Int {\n        return 200\n    }\n\n    func numberOfRows(in spreadsheetView: SpreadsheetView) -\u003e Int {\n        return 400\n    }\n\n    func spreadsheetView(_ spreadsheetView: SpreadsheetView, widthForColumn column: Int) -\u003e CGFloat {\n      return 80\n    }\n\n    func spreadsheetView(_ spreadsheetView: SpreadsheetView, heightForRow row: Int) -\u003e CGFloat {\n      return 40\n    }\n}\n```\n\n## Usage\n### Freeze column and row headers\nFreezing a column or row behaves as a fixed column/row header.\n\n#### Column Header\n```swift\nfunc frozenColumns(in spreadsheetView: SpreadsheetView) -\u003e Int {\n    return 2\n}\n```\n\n\u003cimg src=\"Resources/ColumnHeader.gif\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\n#### Row Header\n```swift\nfunc frozenRows(in spreadsheetView: SpreadsheetView) -\u003e Int {\n    return 2\n}\n```\n\n\u003cimg src=\"Resources/RowHeader.gif\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\n#### both\n```swift\nfunc frozenColumns(in spreadsheetView: SpreadsheetView) -\u003e Int {\n    return 2\n}\n\nfunc frozenRows(in spreadsheetView: SpreadsheetView) -\u003e Int {\n    return 2\n}\n```\n\n\u003cimg src=\"Resources/BothHeaders.gif\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\n### Merge cells\nMultiple cells can be merged and then they are treated as one cell. It is used for grouping cells.\n\n```swift\nfunc mergedCells(in spreadsheetView: SpreadsheetView) -\u003e [CellRange] {\n    return [CellRange(from: (row: 1, column: 1), to: (row: 3, column: 2)),\n            CellRange(from: (row: 3, column: 3), to: (row: 8, column: 3)),\n            CellRange(from: (row: 4, column: 0), to: (row: 7, column: 2)),\n            CellRange(from: (row: 2, column: 4), to: (row: 5, column: 8)),\n            CellRange(from: (row: 9, column: 0), to: (row: 10, column: 5)),\n            CellRange(from: (row: 11, column: 2), to: (row: 12, column: 4))]\n}\n```\n\n\u003cimg src=\"Resources/MergedCells.png\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\n### Circular Scrolling\nYour table acquires infinite scroll just set `circularScrolling` property.\n\n#### Enable horizontal circular scrolling\n```swift\nspreadsheetView.circularScrolling = CircularScrolling.Configuration.horizontally\n```\n\n#### Enable vertical circular scrolling\n```swift\nspreadsheetView.circularScrolling = CircularScrolling.Configuration.vertically\n```\n\n#### Both\n```swift\nspreadsheetView.circularScrolling = CircularScrolling.Configuration.both\n```\n\n\u003cimg src=\"Resources/CircularScrolling.gif\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\nIf circular scrolling is enabled, you can set additional parameters that the option not to repeat column/row header and to extend column/row header to the left/top edges. `CircularScrolling.Configuration` is a builder pattern,  can easily select the appropriate combination by chaining properties.\n\n__e.g.__\n```swift\nspreadsheetView.circularScrolling = \n    CircularScrolling.Configuration.horizontally.columnHeaderNotRepeated\n```\n\n```swift\nspreadsheetView.circularScrolling = \n    CircularScrolling.Configuration.both.columnHeaderStartsFirstRow\n```\n\n### Customize gridlines, borders and cell spacing\nYou can customize the appearance of grid lines and borders of the cell. You can specify whether a cell has a grid line or border. Grid lines and borders can be displayed on the left, right, top, or bottom, or around all four sides of the cell.\n\nThe difference between gridlines and borders is that the gridlines are drawn at the center of the inter-cell spacing, but the borders are drawn to fit around the cell.\n\n#### Cell spacing\n\n\u003cimg src=\"Resources/IntercellSpacing.png\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\n```swift\nspreadsheetView.intercellSpacing = CGSize(width: 1, height: 1)\n```\n\n#### Gridlines\n\n\u003cimg src=\"Resources/Grid.png\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\n`SpreadsheetView`'s `gridStyle` property is applied to the entire table.\n```swift\nspreadsheetView.gridStyle = .solid(width: 1, color: .lightGray)\n```\n\nYou can set different `gridStyle` for each cell and each side of the cell. If you set cell's `gridStyle` property to` default`, `SpreadsheetView`'s` gridStyle` property will be applied. Specify `none` means the grid will not be drawn.\n```swift\ncell.gridlines.top = .solid(width: 1, color: .blue)\ncell.gridlines.left = .solid(width: 1, color: .blue)\ncell.gridlines.bottom = .none\ncell.gridlines.right = .none\n```\n\n#### Border\n\n\u003cimg src=\"Resources/Border.png\" style=\"width: 200px;\" width=\"200\"\u003e\u003c/img\u003e\n\nYou can set different `borderStyle` for each cell as well.\n\n```swift\ncell.borders.top = .solid(width: 1, color: .red)\ncell.borders.left = .solid(width: 1, color: .red)\ncell.borders.bottom = .solid(width: 1, color: .red)\ncell.borders.right = .solid(width: 1, color: .red)\n```\n\n## Author\nKishikawa Katsumi, kishikawakatsumi@mac.com\n\n## License\nSpreadsheetView is available under the MIT license. See the LICENSE file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbannzai%2Fspreadsheetview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbannzai%2Fspreadsheetview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbannzai%2Fspreadsheetview/lists"}