{"id":20620907,"url":"https://github.com/irons163/ircollectiontableviewmodel-swift","last_synced_at":"2025-06-13T08:06:02.479Z","repository":{"id":56915152,"uuid":"365109704","full_name":"irons163/IRCollectionTableViewModel-swift","owner":"irons163","description":"IRCollectionTableViewModel-swift is a powerful MVVM Tableview/CollectionView for iOS, which is flexible and can easy to handle and reuse.","archived":false,"fork":false,"pushed_at":"2021-05-10T06:29:23.000Z","size":131,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-13T08:05:56.714Z","etag":null,"topics":["collectionview","flexible","ios","mvvm","mvvm-architecture","mvvm-pattern","swift","tableview","tableview-collectionview"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/irons163.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-07T04:04:05.000Z","updated_at":"2023-05-17T00:39:50.000Z","dependencies_parsed_at":"2022-08-20T20:50:34.512Z","dependency_job_id":null,"html_url":"https://github.com/irons163/IRCollectionTableViewModel-swift","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/irons163/IRCollectionTableViewModel-swift","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irons163%2FIRCollectionTableViewModel-swift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irons163%2FIRCollectionTableViewModel-swift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irons163%2FIRCollectionTableViewModel-swift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irons163%2FIRCollectionTableViewModel-swift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/irons163","download_url":"https://codeload.github.com/irons163/IRCollectionTableViewModel-swift/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irons163%2FIRCollectionTableViewModel-swift/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259606867,"owners_count":22883556,"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":["collectionview","flexible","ios","mvvm","mvvm-architecture","mvvm-pattern","swift","tableview","tableview-collectionview"],"created_at":"2024-11-16T12:16:02.211Z","updated_at":"2025-06-13T08:06:02.447Z","avatar_url":"https://github.com/irons163.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Build Status](https://img.shields.io/badge/build-%20passing%20-brightgreen.svg)\n![Platform](https://img.shields.io/badge/Platform-%20iOS%20-blue.svg)\n\n# IRCollectionTableViewModel-swift \n\n- IRCollectionTableViewModel-swift is a powerful MVVM Tableview/CollectionView for iOS, which is flexible and can easy to handle and reuse.\n- The Objc version [IRCollectionTableViewModel](https://github.com/irons163/IRCollectionTableViewModel).\n\n## Features\n- MVVM structure.\n- Flexible, Reusable.\n\n## Install\n### Git\n- Git clone this project.\n- Copy this project into your own project.\n- Add the .xcodeproj into you  project and link it as embed framework.\n#### Options\n- You can remove the `demo` and `ScreenShots` folder.\n\n### Cocoapods\n- Add `pod 'IRCollectionTableViewModel-swift'`  in the `Podfile`\n- `pod install`\n\n## Introduction MVVM\n\n- Model--view--viewmodel (MVVM) is a software architectural pattern.\n- It has advantages more than the tranditional MVC architectural. Can improve the whole code strurcture.\n- More detail can see the MVVM wikipedia. [MVVM](https://en.wikipedia.org/wiki/Model–view–viewmodel)\n\n## Usage\n\n### Basic\n\n#### TableView\n\n- Create a new class `TableViewViewModel` extends `TableViewBasicViewModel` and `UITableViewDataSource`, and Import `IRCollectionTableViewModel-swift`\n```swift\nimport IRCollectionTableViewModel_swift\n\nclass TableViewViewModel: TableViewBasicViewModel, UITableViewDataSource {\n    ...\n}\n```\n\n- You can add your init method and register the cell inside\n\n```swift\ninit(tableView: UITableView) {\n    super.init()\n    items = []\n    \n    tableView.register(UINib.init(nibName: TableViewCell.identifier(), bundle: nil), forCellReuseIdentifier: TableViewCell.identifier())\n}\n```\n\n- Add  `update` method\n```swift\nfunc update() {\n    items.removeAll()\n    self.setupRows()\n}\n```\n\n- For setup `items`, other words, setup the sections/rows you want to show. Create `TableViewSectionItem`  and `TableViewRowItem`, `DemoSectionType`, `DemoRowType`\n```swift\nenum TableViewSectionType: NSInteger {\n    case DemoSection\n}\n\ninternal enum ProfileRowType : NSInteger {\n\n    case RowType_DemoRow\n}\n\nclass TableViewRowItem: RowBasicModelItem {\n    var newType: ProfileRowType = .RowType_DemoRow\n    override public var type: ProfileRowType.RawValue {\n        set {\n            self.newType = ProfileRowType(rawValue: newValue)!\n        }\n        get {\n            return newType.rawValue\n        }\n    }\n    \n    override init(type: RowType, title: String) {\n        super.init(type: type, title: title)\n    }\n}\n\nclass TableViewSectionItem: SectionBasicModelItem {\n    private var _sectionTitle: String?\n    private var _type: TableViewSectionType = .DemoSection\n    \n    override init(rowCount: UInt) {\n        super.init(rowCount: rowCount)\n    }\n    \n    override func sectionTitle() -\u003e String? {\n        return self._sectionTitle\n    }\n    \n    open func sectionTitle(_ sectionTitle: String) {\n        self._sectionTitle = sectionTitle\n    }\n    \n    override func type() -\u003e SectionType {\n        return self._type.rawValue\n    }\n    \n    open func type(_ type: TableViewSectionType) {\n        self._type = type\n    }\n}\n```\n\n- Setup `items`\n```swift\nfunc setupRows() {\n    var rowItems: [RowBasicModelItem] = []\n    rowItems.append(TableViewRowItem.init(type: ProfileRowType.RowType_DemoRow.rawValue, title: \"Demo Row\"))\n    rowItems.append(TableViewRowItem.init(type: ProfileRowType.RowType_DemoRow.rawValue, title: \"Demo Row\"))\n    editedTexts = []\n    for _ in rowItems {\n        editedTexts.append(\"\")\n    }\n    \n    let item = TableViewSectionItem.init(rowCount: UInt(rowItems.count))\n    item.type(.DemoSection)\n    item.sectionTitle(\"Demo Section\")\n    item.rows = rowItems\n    self.items.append(item)\n}\n```\n\n- Override `UITableViewDataSource`\n```swift\n// MARK: - UITableViewDataSource\n    func numberOfSections(in tableView: UITableView) -\u003e Int {\n        return items.count\n    }\n    \n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -\u003e Int {\n        return items[section].rowCount()\n    }\n    \n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -\u003e UITableViewCell {\n        let item = items[indexPath.section]\n        let row = item.rows[indexPath.row]\n        \n        switch row.type {\n        case ProfileRowType.RowType_DemoRow.rawValue:\n            do {\n                let cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.identifier(), for: indexPath) as! TableViewCell\n                cell.titleLabel.text = String.init(format: \"%@%ld\", row.title!, row.tagRange.location)\n                cell.editTextField.text = self.editedTexts[indexPath.row] as String\n                cell.editTextField.tag = row.tagRange.location\n                cell.editTextField.delegate = self\n                return cell\n            }\n        default:\n            break\n        }\n        return UITableViewCell.init()\n    }\n```\n\n- Use your view model `TableViewViewModel`\n```swift\nvar viewModel: TableViewViewModel?\n\nself.tableView.register(UINib.init(nibName: TableViewHeaderView.identifier(), bundle: nil), forHeaderFooterViewReuseIdentifier: TableViewHeaderView.identifier())\nviewModel = TableViewViewModel.init(tableView: self.tableView)\nself.tableView.dataSource = viewModel\nviewModel!.update()\n```\n\n#### CollectionView\n\n- Just the same way of `TableViewViewModel`. Create a new class `CustomCollectionViewModel` extends `TableViewBasicViewModel` and `UICollectionViewDataSource`.\n\n- You can add your init method and register the cell inside.\n\n- For setup `items`, other words, setup the sections/rows you want to show. Create `CustomCollectionSectionItem`  and `CustomCollectionRowItem`, `CustomCollectionSectionType`.\n\n- Override `UICollectionViewDataSource`.\n\n\n### Advanced settings\n\n#### Methos of TableViewBasicViewModel\n\n- `TableViewBasicViewModel` provides some usage methods\n\n```swift\n// MARK: - Public\npublic func getRowTypeWith(type: SectionType, row: NSInteger) -\u003e NSInteger\npublic func getSectionTitleinSection(section: NSInteger) -\u003e String?\npublic func getSectionLeftIconinSection(section: NSInteger) -\u003e UIImage?\npublic func getSectionTypeinSection(section: NSInteger) -\u003e SectionType\npublic func hideRows(hide: Bool, inSection section: NSInteger)\npublic func hiddenRowsinSection(section: NSInteger) -\u003e Bool\npublic func getIndexSetWithSectionType(sectionType: SectionType) -\u003e NSIndexSet?\npublic func getIndexPathWithSectionType(sectionType: SectionType, rowType: RowType) -\u003e NSIndexPath?\npublic func setupRowTag()\npublic func getIndexPathFromRowTag(rowTag: NSInteger) -\u003e NSIndexPath\n```\n#### Tag\n\n- Because the cells have reuse feature, somtimes we need to tag the cell/componenst if want to recognize the specific cell/components, thus  `IRCollectionTableViewModel` provides a tag feature\n\n- Setup tags by `setupRowTag`, it save the tag information in the `tagRange` which is in the `RowBasicModelItem`\n```swift\n- (void)setupRows {\n    ...\n    \n    self.setupRowTag()\n}\n```\n\n- Get tag\n```swift\nlet row = item.rows[indexPath.row]\nlet tag = row.tagRange.location\n```\n\n- Get indexPath by tag\n```swift\npublic func getIndexPathFromRowTag(rowTag: NSInteger) -\u003e NSIndexPath\n```\n\n- Sometimes you want to tag the UI components like `UITextField`, use `setTagRangeLength`\n```swift\nvar row = TableViewRowItem.init(type: ProfileRowType.RowType_DemoRow.rawValue, title: \"Demo Row\")\nrow.setTagRangeLength(2)\n\n...\n\nself.setupRowTag()\n```\n\n- Then get tags\n```swift\nlet row = item.rows[indexPath.row]\nlet tag1 = row.tagRange.location\nlet tag2 = row.tagRange.location + 1\n\ncell.textField1.tag = tag1\ncell.textField2.tag = tag2\n```\n\n- If you wnat to check the tags are mapping to the same index path\n```swift\nself.getIndexPathFromRowTag(tag1) == self.getIndexPathFromRowTag(tag2)\n```\n\nNow, you can easy to tag anyhing you want.\n\n\n#### Get Row Type\n\n- Get row type\n\n```swift\nself.getRowTypeWith(type: 0, row: 0)\n```\n\n#### Get Section Title\n\n- Get section title which set in the `SectionBasicModelItem`\n\n```swift\nself.getSectionTitleinSection(section: 0)\n```\n\n#### Get Section Left Icon\n\n- Get section icon which set in the `SectionBasicModelItem`\n\n```swift\nself.getSectionLeftIconinSection(section: 0)\n```\n\n#### Get Section Type\n\n- Get section type by section index\n\n```swift\nself.getSectionTypeinSection(section: 0)\n```\n\n#### Hide Rows\n\n- Hide rows for specific setion by `public func hideRows(hide: Bool, inSection section: NSInteger)`\n- Check hidden status by `public func hiddenRowsinSection(section: NSInteger) -\u003e Bool`\n\n```swift\nif self.hiddenRowsinSection(section: 0) {\n    self.hideRows(hide: false, inSection: 0)\n}\n```\n\n#### Get Index Set\n\n- Get index of section by section type\n\n```swift\nself.getIndexSetWithSectionType(sectionType: .DemoSection)\n```\n\n#### Get IndexPath\n\n- Get index path by section type and row type\n\n```swift\nself.getIndexPathWithSectionType(sectionType: .DemoSection, rowType: .RowType_DemoRow)\n```\n\n\n## Screenshots\n| TableView | CollectionView |\n|:---:|:---:|\n|![TableView](./ScreenShots/demo1.png)|![CollectionView](./ScreenShots/demo2.png)| \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firons163%2Fircollectiontableviewmodel-swift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firons163%2Fircollectiontableviewmodel-swift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firons163%2Fircollectiontableviewmodel-swift/lists"}