├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── CONTRIBUTING.ja.md ├── README.md └── TableSample ├── TableSample.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist └── TableSample ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── Base.lproj └── LaunchScreen.storyboard ├── Info.plist ├── Main.storyboard ├── SceneDelegate.swift ├── Tables ├── Customs │ ├── Customs.storyboard │ ├── CustomsIndexViewController.swift │ ├── DoubleAccordion │ │ ├── DoubleAccordionTableViewController.swift │ │ └── Parts │ │ │ ├── DoubleAccordionTableViewCell.swift │ │ │ ├── DoubleAccordionTableViewCell.xib │ │ │ ├── DoubleAccordionTableViewHeaderFooterView.swift │ │ │ └── DoubleAccordionTableViewHeaderFooterView.xib │ └── SingleAccordion │ │ ├── Parts │ │ ├── SingleAccordionTableViewHeaderFooterView.swift │ │ └── SingleAccordionTableViewHeaderFooterView.xib │ │ └── SingleAccordionTableViewController.swift ├── DefaultAppearances │ ├── Base.lproj │ │ └── DefaultAppearances.storyboard │ ├── CellAccessoryTypeTableViewController.swift │ ├── CellStyleTableViewController.swift │ ├── ColorCellTableViewController.swift │ ├── ColorSectionTableViewController.swift │ ├── DefaultAppearancesIndexViewController.swift │ ├── GroupedDetailViewController.swift │ ├── SelectedColorCellTableViewController.swift │ ├── SeparatorStyleViewController.swift │ └── TableStyleViewController.swift └── Operations │ ├── CellEditingTableViewController.swift │ ├── ContextMenuTableViewController.swift │ ├── MultiSelectionLeftTableViewController.swift │ ├── MultiSelectionTableViewController.swift │ ├── Operations.storyboard │ ├── OperationsIndexViewController.swift │ ├── SectionIndexTableViewController.swift │ ├── SwipeTableViewController.swift │ └── UnselectablePartsTableViewController.swift └── ViewController.swift /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | ## Group 4 | (DefaultAppearances, Operations, Customs) 5 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Summary 2 | 3 | ## Related Issue 4 | 5 | ## Check 6 | - [ ] build success! 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /CONTRIBUTING.ja.md: -------------------------------------------------------------------------------- 1 | # コントリビュート 2 | `UITableView` のサンプル集です。いつでもコントリビューション大歓迎です! 3 | 4 | フォルダ分けは下記の通り。 5 | 6 | * DefaultsAppearances -> カスタムクラスを使わずに見た目をいじったやつ 7 | * Operations -> カスタムクラスを使わずにやる操作系のやつ(選択・移動・削除など) 8 | * Customs -> カスタムクラスを使用してつくるやつ 9 | 10 | ## コントリビュートする方法 11 | 追加する場所に迷ったらCustoms に入れてください。 12 | 13 | Issueにあるやつか新たにIssueをたてて作業して下さい。 14 | 15 | 他の人と重複して作業してしまうことを防ぐために "🙋"などでいいのでコメントをしてください。 16 | 17 | (めっちゃDroidKaigiのやつ意識した🤐) 18 | 19 | ## 画面追加方法 20 | 該当のIndexViewControllerにStoryboardボタンを追加する 21 | 22 | その後は下記いずれかの方法(Storyboardでのコンフリクトが嫌な場合は2個目がおすすめ) 23 | 24 | * 該当のStoryboardに画面を追加してボタンをsegueでつなぐ 25 | * 新規でStoryboardを追加してIndexViewControllerにコードで遷移処理をかく 26 | 27 | Storyboardやxibなどファイルが複数になる場合はフォルダにまとめていただけるとありがたいです🙇‍♂️ 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TableSample 2 | Table View sample. 3 | 4 | ## Contributing 5 | I always welcome any and all contributions! 6 | 7 | Please see [CONTRIBUTING.ja.md](https://github.com/adventam10/TableSample/blob/master/CONTRIBUTING.ja.md) 8 | 9 | ## Development Environment 10 | * Xcode 11.3 11 | * Deployment Target iOS13.0 12 | 13 | ## Defaults Appearances 14 | | Cell Style | AccessoryType | Color Cell | Selected Color | 15 | | --- | --- | --- | --- | 16 | | ![cell_style](https://user-images.githubusercontent.com/34936885/77146220-e6213f80-6acd-11ea-8c17-d0f6aab8c353.png) | ![accessory](https://user-images.githubusercontent.com/34936885/77324781-9d31eb00-6d5a-11ea-9871-773cca1adb85.png) | ![color_cell](https://user-images.githubusercontent.com/34936885/77146520-90996280-6ace-11ea-9555-31437d8e5aa6.png) | ![selected_color_cell](https://user-images.githubusercontent.com/34936885/77146446-6051c400-6ace-11ea-9cc6-1138112b8ee8.png) | 17 | 18 | | Separator Style | Table Style | Grouped Detail | Color Section | 19 | | --- | --- | --- | --- | 20 | | ![separator_style](https://user-images.githubusercontent.com/34936885/77146464-69db2c00-6ace-11ea-860f-1952201852d2.png) | ![table_style](https://user-images.githubusercontent.com/34936885/77146480-7a8ba200-6ace-11ea-9124-4a306b23444d.png) | ![grouped_detail](https://user-images.githubusercontent.com/34936885/77146496-84ada080-6ace-11ea-83ac-2b65dfd31219.png) | ![color_section](https://user-images.githubusercontent.com/34936885/77158295-63f14500-6ae6-11ea-9d47-f03187baff34.png) | 21 | 22 | ## Operations 23 | | Multi Selection | Multi Selection 2| Unselectable Parts | Cell Editing | 24 | | --- | --- | --- | --- | 25 | | ![multi_selection](https://user-images.githubusercontent.com/34936885/77222594-0c131680-6b98-11ea-9b0d-06b3d6a0b718.png) | ![multi_selection_2](https://user-images.githubusercontent.com/34936885/77543310-dbf6ab00-6eea-11ea-96c1-df66da3069d5.png) | ![unselectable_parts](https://user-images.githubusercontent.com/34936885/77222599-18976f00-6b98-11ea-81b3-f0cfe25c3f93.png) | ![cell_editing](https://user-images.githubusercontent.com/34936885/77222606-25b45e00-6b98-11ea-80f7-031e4d312d36.png) | 26 | 27 | 28 | | Section Index | Context Menu | Swipe | 29 | | --- | --- | --- | 30 | | section_index | menu | swipe | 31 | 32 | ## Customs 33 | | Single Accordion | Double Accordion | 34 | | --- | --- | 35 | | ![single](https://user-images.githubusercontent.com/34936885/80277463-12158d80-872a-11ea-89b2-f648f411aef2.gif) | ![accordion](https://user-images.githubusercontent.com/34936885/80277474-2b1e3e80-872a-11ea-9f60-a965f889288d.gif) | -------------------------------------------------------------------------------- /TableSample/TableSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0E0EBC342452ABC400D986A5 /* SingleAccordionTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0EBC332452ABC400D986A5 /* SingleAccordionTableViewController.swift */; }; 11 | 0E0EBC362452AD9400D986A5 /* SingleAccordionTableViewHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E0EBC352452AD9400D986A5 /* SingleAccordionTableViewHeaderFooterView.swift */; }; 12 | 0E0EBC382452ADE900D986A5 /* SingleAccordionTableViewHeaderFooterView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0E0EBC372452ADE900D986A5 /* SingleAccordionTableViewHeaderFooterView.xib */; }; 13 | 0E1ED15D24247ED700714B52 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED15C24247ED700714B52 /* AppDelegate.swift */; }; 14 | 0E1ED15F24247ED700714B52 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED15E24247ED700714B52 /* SceneDelegate.swift */; }; 15 | 0E1ED16124247ED700714B52 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED16024247ED700714B52 /* ViewController.swift */; }; 16 | 0E1ED16424247ED700714B52 /* DefaultAppearances.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1ED16224247ED700714B52 /* DefaultAppearances.storyboard */; }; 17 | 0E1ED16624247ED800714B52 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E1ED16524247ED800714B52 /* Assets.xcassets */; }; 18 | 0E1ED16924247ED800714B52 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E1ED16724247ED800714B52 /* LaunchScreen.storyboard */; }; 19 | 0E1ED1742424861E00714B52 /* CellStyleTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED1732424861E00714B52 /* CellStyleTableViewController.swift */; }; 20 | 0E1ED1762424894400714B52 /* CellAccessoryTypeTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED1752424894400714B52 /* CellAccessoryTypeTableViewController.swift */; }; 21 | 0E1ED17824248D8800714B52 /* SeparatorStyleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED17724248D8800714B52 /* SeparatorStyleViewController.swift */; }; 22 | 0E1ED17A242494C300714B52 /* TableStyleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED179242494C300714B52 /* TableStyleViewController.swift */; }; 23 | 0E1ED17C24249A4100714B52 /* GroupedDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED17B24249A4100714B52 /* GroupedDetailViewController.swift */; }; 24 | 0E1ED17E24249DC000714B52 /* ColorCellTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED17D24249DC000714B52 /* ColorCellTableViewController.swift */; }; 25 | 0E1ED1802424A1A700714B52 /* SelectedColorCellTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E1ED17F2424A1A700714B52 /* SelectedColorCellTableViewController.swift */; }; 26 | 0E63F3842424D8380086D9CC /* ColorSectionTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E63F3832424D8380086D9CC /* ColorSectionTableViewController.swift */; }; 27 | 0E63F388242507AF0086D9CC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E63F387242507AF0086D9CC /* Main.storyboard */; }; 28 | 0E63F38A2425091B0086D9CC /* Operations.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E63F3892425091B0086D9CC /* Operations.storyboard */; }; 29 | 0E63F38C242512950086D9CC /* MultiSelectionTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E63F38B242512950086D9CC /* MultiSelectionTableViewController.swift */; }; 30 | 0E63F38E24251D3E0086D9CC /* UnselectablePartsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E63F38D24251D3E0086D9CC /* UnselectablePartsTableViewController.swift */; }; 31 | 0E6C0C1624335FF500395741 /* DoubleAccordionTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6C0C1524335FF500395741 /* DoubleAccordionTableViewController.swift */; }; 32 | 0E6C0C1A2433699800395741 /* DoubleAccordionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6C0C182433699800395741 /* DoubleAccordionTableViewCell.swift */; }; 33 | 0E6C0C1B2433699800395741 /* DoubleAccordionTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0E6C0C192433699800395741 /* DoubleAccordionTableViewCell.xib */; }; 34 | 0E6C0C1D24336D3000395741 /* DoubleAccordionTableViewHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6C0C1C24336D3000395741 /* DoubleAccordionTableViewHeaderFooterView.swift */; }; 35 | 0E6C0C1F24336D4C00395741 /* DoubleAccordionTableViewHeaderFooterView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 0E6C0C1E24336D4C00395741 /* DoubleAccordionTableViewHeaderFooterView.xib */; }; 36 | 0E741DB42428F35800D67FFA /* OperationsIndexViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E741DB32428F35800D67FFA /* OperationsIndexViewController.swift */; }; 37 | 0E741DB62428F37300D67FFA /* DefaultAppearancesIndexViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E741DB52428F37300D67FFA /* DefaultAppearancesIndexViewController.swift */; }; 38 | 0E741DB82428F38800D67FFA /* CustomsIndexViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E741DB72428F38800D67FFA /* CustomsIndexViewController.swift */; }; 39 | 0E741DBA2428FB0000D67FFA /* SwipeTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E741DB92428FB0000D67FFA /* SwipeTableViewController.swift */; }; 40 | 0E741DBC242A208600D67FFA /* SectionIndexTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E741DBB242A208600D67FFA /* SectionIndexTableViewController.swift */; }; 41 | 0E741DBE242B96FE00D67FFA /* MultiSelectionLeftTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E741DBD242B96FE00D67FFA /* MultiSelectionLeftTableViewController.swift */; }; 42 | 0EC9BC3D2425DF3C004C6264 /* Customs.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0EC9BC3C2425DF3C004C6264 /* Customs.storyboard */; }; 43 | 0EC9BC3F2425FB8A004C6264 /* ContextMenuTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC9BC3E2425FB8A004C6264 /* ContextMenuTableViewController.swift */; }; 44 | FAA3C55C2424E6BA000E70D6 /* CellEditingTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA3C55B2424E6BA000E70D6 /* CellEditingTableViewController.swift */; }; 45 | /* End PBXBuildFile section */ 46 | 47 | /* Begin PBXFileReference section */ 48 | 0E0EBC332452ABC400D986A5 /* SingleAccordionTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleAccordionTableViewController.swift; sourceTree = ""; }; 49 | 0E0EBC352452AD9400D986A5 /* SingleAccordionTableViewHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleAccordionTableViewHeaderFooterView.swift; sourceTree = ""; }; 50 | 0E0EBC372452ADE900D986A5 /* SingleAccordionTableViewHeaderFooterView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SingleAccordionTableViewHeaderFooterView.xib; sourceTree = ""; }; 51 | 0E1ED15924247ED700714B52 /* TableSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TableSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 0E1ED15C24247ED700714B52 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 53 | 0E1ED15E24247ED700714B52 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 54 | 0E1ED16024247ED700714B52 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 55 | 0E1ED16324247ED700714B52 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/DefaultAppearances.storyboard; sourceTree = ""; }; 56 | 0E1ED16524247ED800714B52 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 57 | 0E1ED16824247ED800714B52 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 58 | 0E1ED16A24247ED800714B52 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | 0E1ED1732424861E00714B52 /* CellStyleTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CellStyleTableViewController.swift; sourceTree = ""; }; 60 | 0E1ED1752424894400714B52 /* CellAccessoryTypeTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CellAccessoryTypeTableViewController.swift; sourceTree = ""; }; 61 | 0E1ED17724248D8800714B52 /* SeparatorStyleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorStyleViewController.swift; sourceTree = ""; }; 62 | 0E1ED179242494C300714B52 /* TableStyleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableStyleViewController.swift; sourceTree = ""; }; 63 | 0E1ED17B24249A4100714B52 /* GroupedDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupedDetailViewController.swift; sourceTree = ""; }; 64 | 0E1ED17D24249DC000714B52 /* ColorCellTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorCellTableViewController.swift; sourceTree = ""; }; 65 | 0E1ED17F2424A1A700714B52 /* SelectedColorCellTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedColorCellTableViewController.swift; sourceTree = ""; }; 66 | 0E63F3832424D8380086D9CC /* ColorSectionTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorSectionTableViewController.swift; sourceTree = ""; }; 67 | 0E63F387242507AF0086D9CC /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 68 | 0E63F3892425091B0086D9CC /* Operations.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Operations.storyboard; sourceTree = ""; }; 69 | 0E63F38B242512950086D9CC /* MultiSelectionTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiSelectionTableViewController.swift; sourceTree = ""; }; 70 | 0E63F38D24251D3E0086D9CC /* UnselectablePartsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnselectablePartsTableViewController.swift; sourceTree = ""; }; 71 | 0E6C0C1524335FF500395741 /* DoubleAccordionTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleAccordionTableViewController.swift; sourceTree = ""; }; 72 | 0E6C0C182433699800395741 /* DoubleAccordionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleAccordionTableViewCell.swift; sourceTree = ""; }; 73 | 0E6C0C192433699800395741 /* DoubleAccordionTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DoubleAccordionTableViewCell.xib; sourceTree = ""; }; 74 | 0E6C0C1C24336D3000395741 /* DoubleAccordionTableViewHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleAccordionTableViewHeaderFooterView.swift; sourceTree = ""; }; 75 | 0E6C0C1E24336D4C00395741 /* DoubleAccordionTableViewHeaderFooterView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DoubleAccordionTableViewHeaderFooterView.xib; sourceTree = ""; }; 76 | 0E741DB32428F35800D67FFA /* OperationsIndexViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationsIndexViewController.swift; sourceTree = ""; }; 77 | 0E741DB52428F37300D67FFA /* DefaultAppearancesIndexViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultAppearancesIndexViewController.swift; sourceTree = ""; }; 78 | 0E741DB72428F38800D67FFA /* CustomsIndexViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomsIndexViewController.swift; sourceTree = ""; }; 79 | 0E741DB92428FB0000D67FFA /* SwipeTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeTableViewController.swift; sourceTree = ""; }; 80 | 0E741DBB242A208600D67FFA /* SectionIndexTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionIndexTableViewController.swift; sourceTree = ""; }; 81 | 0E741DBD242B96FE00D67FFA /* MultiSelectionLeftTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiSelectionLeftTableViewController.swift; sourceTree = ""; }; 82 | 0EC9BC3C2425DF3C004C6264 /* Customs.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Customs.storyboard; sourceTree = ""; }; 83 | 0EC9BC3E2425FB8A004C6264 /* ContextMenuTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuTableViewController.swift; sourceTree = ""; }; 84 | FAA3C55B2424E6BA000E70D6 /* CellEditingTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CellEditingTableViewController.swift; sourceTree = ""; }; 85 | /* End PBXFileReference section */ 86 | 87 | /* Begin PBXFrameworksBuildPhase section */ 88 | 0E1ED15624247ED700714B52 /* Frameworks */ = { 89 | isa = PBXFrameworksBuildPhase; 90 | buildActionMask = 2147483647; 91 | files = ( 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 0E0EBC312452AB7800D986A5 /* SingleAccordion */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 0E0EBC322452AB9F00D986A5 /* Parts */, 102 | 0E0EBC332452ABC400D986A5 /* SingleAccordionTableViewController.swift */, 103 | ); 104 | path = SingleAccordion; 105 | sourceTree = ""; 106 | }; 107 | 0E0EBC322452AB9F00D986A5 /* Parts */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 0E0EBC352452AD9400D986A5 /* SingleAccordionTableViewHeaderFooterView.swift */, 111 | 0E0EBC372452ADE900D986A5 /* SingleAccordionTableViewHeaderFooterView.xib */, 112 | ); 113 | path = Parts; 114 | sourceTree = ""; 115 | }; 116 | 0E1ED15024247ED700714B52 = { 117 | isa = PBXGroup; 118 | children = ( 119 | 0E1ED15B24247ED700714B52 /* TableSample */, 120 | 0E1ED15A24247ED700714B52 /* Products */, 121 | ); 122 | sourceTree = ""; 123 | }; 124 | 0E1ED15A24247ED700714B52 /* Products */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 0E1ED15924247ED700714B52 /* TableSample.app */, 128 | ); 129 | name = Products; 130 | sourceTree = ""; 131 | }; 132 | 0E1ED15B24247ED700714B52 /* TableSample */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 0E1ED15C24247ED700714B52 /* AppDelegate.swift */, 136 | 0E1ED15E24247ED700714B52 /* SceneDelegate.swift */, 137 | 0E1ED17024247EF300714B52 /* Tables */, 138 | 0E1ED16024247ED700714B52 /* ViewController.swift */, 139 | 0E63F387242507AF0086D9CC /* Main.storyboard */, 140 | 0E1ED16524247ED800714B52 /* Assets.xcassets */, 141 | 0E1ED16724247ED800714B52 /* LaunchScreen.storyboard */, 142 | 0E1ED16A24247ED800714B52 /* Info.plist */, 143 | ); 144 | path = TableSample; 145 | sourceTree = ""; 146 | }; 147 | 0E1ED17024247EF300714B52 /* Tables */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 0EC9BC3B2425DF28004C6264 /* Customs */, 151 | 0E63F3862425071A0086D9CC /* Operations */, 152 | 0E63F385242506E40086D9CC /* DefaultAppearances */, 153 | ); 154 | path = Tables; 155 | sourceTree = ""; 156 | }; 157 | 0E63F385242506E40086D9CC /* DefaultAppearances */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 0E1ED16224247ED700714B52 /* DefaultAppearances.storyboard */, 161 | 0E741DB52428F37300D67FFA /* DefaultAppearancesIndexViewController.swift */, 162 | 0E1ED1752424894400714B52 /* CellAccessoryTypeTableViewController.swift */, 163 | 0E1ED17724248D8800714B52 /* SeparatorStyleViewController.swift */, 164 | 0E1ED179242494C300714B52 /* TableStyleViewController.swift */, 165 | 0E1ED17B24249A4100714B52 /* GroupedDetailViewController.swift */, 166 | 0E1ED17D24249DC000714B52 /* ColorCellTableViewController.swift */, 167 | 0E1ED17F2424A1A700714B52 /* SelectedColorCellTableViewController.swift */, 168 | 0E63F3832424D8380086D9CC /* ColorSectionTableViewController.swift */, 169 | 0E1ED1732424861E00714B52 /* CellStyleTableViewController.swift */, 170 | ); 171 | path = DefaultAppearances; 172 | sourceTree = ""; 173 | }; 174 | 0E63F3862425071A0086D9CC /* Operations */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 0E63F3892425091B0086D9CC /* Operations.storyboard */, 178 | 0E741DB32428F35800D67FFA /* OperationsIndexViewController.swift */, 179 | 0E63F38B242512950086D9CC /* MultiSelectionTableViewController.swift */, 180 | 0E741DBD242B96FE00D67FFA /* MultiSelectionLeftTableViewController.swift */, 181 | 0E63F38D24251D3E0086D9CC /* UnselectablePartsTableViewController.swift */, 182 | FAA3C55B2424E6BA000E70D6 /* CellEditingTableViewController.swift */, 183 | 0EC9BC3E2425FB8A004C6264 /* ContextMenuTableViewController.swift */, 184 | 0E741DB92428FB0000D67FFA /* SwipeTableViewController.swift */, 185 | 0E741DBB242A208600D67FFA /* SectionIndexTableViewController.swift */, 186 | ); 187 | path = Operations; 188 | sourceTree = ""; 189 | }; 190 | 0E6C0C1424335FBC00395741 /* DoubleAccordion */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 0E6C0C1524335FF500395741 /* DoubleAccordionTableViewController.swift */, 194 | 0E6C0C172433697400395741 /* Parts */, 195 | ); 196 | path = DoubleAccordion; 197 | sourceTree = ""; 198 | }; 199 | 0E6C0C172433697400395741 /* Parts */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 0E6C0C182433699800395741 /* DoubleAccordionTableViewCell.swift */, 203 | 0E6C0C192433699800395741 /* DoubleAccordionTableViewCell.xib */, 204 | 0E6C0C1C24336D3000395741 /* DoubleAccordionTableViewHeaderFooterView.swift */, 205 | 0E6C0C1E24336D4C00395741 /* DoubleAccordionTableViewHeaderFooterView.xib */, 206 | ); 207 | path = Parts; 208 | sourceTree = ""; 209 | }; 210 | 0EC9BC3B2425DF28004C6264 /* Customs */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | 0EC9BC3C2425DF3C004C6264 /* Customs.storyboard */, 214 | 0E741DB72428F38800D67FFA /* CustomsIndexViewController.swift */, 215 | 0E0EBC312452AB7800D986A5 /* SingleAccordion */, 216 | 0E6C0C1424335FBC00395741 /* DoubleAccordion */, 217 | ); 218 | path = Customs; 219 | sourceTree = ""; 220 | }; 221 | /* End PBXGroup section */ 222 | 223 | /* Begin PBXNativeTarget section */ 224 | 0E1ED15824247ED700714B52 /* TableSample */ = { 225 | isa = PBXNativeTarget; 226 | buildConfigurationList = 0E1ED16D24247ED800714B52 /* Build configuration list for PBXNativeTarget "TableSample" */; 227 | buildPhases = ( 228 | 0E1ED15524247ED700714B52 /* Sources */, 229 | 0E1ED15624247ED700714B52 /* Frameworks */, 230 | 0E1ED15724247ED700714B52 /* Resources */, 231 | ); 232 | buildRules = ( 233 | ); 234 | dependencies = ( 235 | ); 236 | name = TableSample; 237 | productName = TableSample; 238 | productReference = 0E1ED15924247ED700714B52 /* TableSample.app */; 239 | productType = "com.apple.product-type.application"; 240 | }; 241 | /* End PBXNativeTarget section */ 242 | 243 | /* Begin PBXProject section */ 244 | 0E1ED15124247ED700714B52 /* Project object */ = { 245 | isa = PBXProject; 246 | attributes = { 247 | LastSwiftUpdateCheck = 1130; 248 | LastUpgradeCheck = 1130; 249 | ORGANIZATIONNAME = am10; 250 | TargetAttributes = { 251 | 0E1ED15824247ED700714B52 = { 252 | CreatedOnToolsVersion = 11.3; 253 | }; 254 | }; 255 | }; 256 | buildConfigurationList = 0E1ED15424247ED700714B52 /* Build configuration list for PBXProject "TableSample" */; 257 | compatibilityVersion = "Xcode 9.3"; 258 | developmentRegion = en; 259 | hasScannedForEncodings = 0; 260 | knownRegions = ( 261 | en, 262 | Base, 263 | ); 264 | mainGroup = 0E1ED15024247ED700714B52; 265 | productRefGroup = 0E1ED15A24247ED700714B52 /* Products */; 266 | projectDirPath = ""; 267 | projectRoot = ""; 268 | targets = ( 269 | 0E1ED15824247ED700714B52 /* TableSample */, 270 | ); 271 | }; 272 | /* End PBXProject section */ 273 | 274 | /* Begin PBXResourcesBuildPhase section */ 275 | 0E1ED15724247ED700714B52 /* Resources */ = { 276 | isa = PBXResourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 0E6C0C1F24336D4C00395741 /* DoubleAccordionTableViewHeaderFooterView.xib in Resources */, 280 | 0E1ED16924247ED800714B52 /* LaunchScreen.storyboard in Resources */, 281 | 0EC9BC3D2425DF3C004C6264 /* Customs.storyboard in Resources */, 282 | 0E1ED16624247ED800714B52 /* Assets.xcassets in Resources */, 283 | 0E1ED16424247ED700714B52 /* DefaultAppearances.storyboard in Resources */, 284 | 0E0EBC382452ADE900D986A5 /* SingleAccordionTableViewHeaderFooterView.xib in Resources */, 285 | 0E6C0C1B2433699800395741 /* DoubleAccordionTableViewCell.xib in Resources */, 286 | 0E63F38A2425091B0086D9CC /* Operations.storyboard in Resources */, 287 | 0E63F388242507AF0086D9CC /* Main.storyboard in Resources */, 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | /* End PBXResourcesBuildPhase section */ 292 | 293 | /* Begin PBXSourcesBuildPhase section */ 294 | 0E1ED15524247ED700714B52 /* Sources */ = { 295 | isa = PBXSourcesBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | 0E741DB62428F37300D67FFA /* DefaultAppearancesIndexViewController.swift in Sources */, 299 | 0E6C0C1624335FF500395741 /* DoubleAccordionTableViewController.swift in Sources */, 300 | 0E63F3842424D8380086D9CC /* ColorSectionTableViewController.swift in Sources */, 301 | 0E741DB42428F35800D67FFA /* OperationsIndexViewController.swift in Sources */, 302 | 0E6C0C1D24336D3000395741 /* DoubleAccordionTableViewHeaderFooterView.swift in Sources */, 303 | 0E1ED17C24249A4100714B52 /* GroupedDetailViewController.swift in Sources */, 304 | 0E741DBC242A208600D67FFA /* SectionIndexTableViewController.swift in Sources */, 305 | 0EC9BC3F2425FB8A004C6264 /* ContextMenuTableViewController.swift in Sources */, 306 | 0E1ED16124247ED700714B52 /* ViewController.swift in Sources */, 307 | 0E1ED17A242494C300714B52 /* TableStyleViewController.swift in Sources */, 308 | 0E0EBC342452ABC400D986A5 /* SingleAccordionTableViewController.swift in Sources */, 309 | 0E0EBC362452AD9400D986A5 /* SingleAccordionTableViewHeaderFooterView.swift in Sources */, 310 | FAA3C55C2424E6BA000E70D6 /* CellEditingTableViewController.swift in Sources */, 311 | 0E1ED1742424861E00714B52 /* CellStyleTableViewController.swift in Sources */, 312 | 0E1ED15D24247ED700714B52 /* AppDelegate.swift in Sources */, 313 | 0E1ED17824248D8800714B52 /* SeparatorStyleViewController.swift in Sources */, 314 | 0E1ED1802424A1A700714B52 /* SelectedColorCellTableViewController.swift in Sources */, 315 | 0E741DB82428F38800D67FFA /* CustomsIndexViewController.swift in Sources */, 316 | 0E1ED15F24247ED700714B52 /* SceneDelegate.swift in Sources */, 317 | 0E1ED1762424894400714B52 /* CellAccessoryTypeTableViewController.swift in Sources */, 318 | 0E741DBA2428FB0000D67FFA /* SwipeTableViewController.swift in Sources */, 319 | 0E741DBE242B96FE00D67FFA /* MultiSelectionLeftTableViewController.swift in Sources */, 320 | 0E6C0C1A2433699800395741 /* DoubleAccordionTableViewCell.swift in Sources */, 321 | 0E63F38C242512950086D9CC /* MultiSelectionTableViewController.swift in Sources */, 322 | 0E1ED17E24249DC000714B52 /* ColorCellTableViewController.swift in Sources */, 323 | 0E63F38E24251D3E0086D9CC /* UnselectablePartsTableViewController.swift in Sources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | /* End PBXSourcesBuildPhase section */ 328 | 329 | /* Begin PBXVariantGroup section */ 330 | 0E1ED16224247ED700714B52 /* DefaultAppearances.storyboard */ = { 331 | isa = PBXVariantGroup; 332 | children = ( 333 | 0E1ED16324247ED700714B52 /* Base */, 334 | ); 335 | name = DefaultAppearances.storyboard; 336 | sourceTree = ""; 337 | }; 338 | 0E1ED16724247ED800714B52 /* LaunchScreen.storyboard */ = { 339 | isa = PBXVariantGroup; 340 | children = ( 341 | 0E1ED16824247ED800714B52 /* Base */, 342 | ); 343 | name = LaunchScreen.storyboard; 344 | sourceTree = ""; 345 | }; 346 | /* End PBXVariantGroup section */ 347 | 348 | /* Begin XCBuildConfiguration section */ 349 | 0E1ED16B24247ED800714B52 /* Debug */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | ALWAYS_SEARCH_USER_PATHS = NO; 353 | CLANG_ANALYZER_NONNULL = YES; 354 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 355 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 356 | CLANG_CXX_LIBRARY = "libc++"; 357 | CLANG_ENABLE_MODULES = YES; 358 | CLANG_ENABLE_OBJC_ARC = YES; 359 | CLANG_ENABLE_OBJC_WEAK = YES; 360 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 361 | CLANG_WARN_BOOL_CONVERSION = YES; 362 | CLANG_WARN_COMMA = YES; 363 | CLANG_WARN_CONSTANT_CONVERSION = YES; 364 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 365 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 366 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 367 | CLANG_WARN_EMPTY_BODY = YES; 368 | CLANG_WARN_ENUM_CONVERSION = YES; 369 | CLANG_WARN_INFINITE_RECURSION = YES; 370 | CLANG_WARN_INT_CONVERSION = YES; 371 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 372 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 373 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 374 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 375 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 376 | CLANG_WARN_STRICT_PROTOTYPES = YES; 377 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 378 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 379 | CLANG_WARN_UNREACHABLE_CODE = YES; 380 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 381 | COPY_PHASE_STRIP = NO; 382 | DEBUG_INFORMATION_FORMAT = dwarf; 383 | ENABLE_STRICT_OBJC_MSGSEND = YES; 384 | ENABLE_TESTABILITY = YES; 385 | GCC_C_LANGUAGE_STANDARD = gnu11; 386 | GCC_DYNAMIC_NO_PIC = NO; 387 | GCC_NO_COMMON_BLOCKS = YES; 388 | GCC_OPTIMIZATION_LEVEL = 0; 389 | GCC_PREPROCESSOR_DEFINITIONS = ( 390 | "DEBUG=1", 391 | "$(inherited)", 392 | ); 393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 394 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 395 | GCC_WARN_UNDECLARED_SELECTOR = YES; 396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 397 | GCC_WARN_UNUSED_FUNCTION = YES; 398 | GCC_WARN_UNUSED_VARIABLE = YES; 399 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 400 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 401 | MTL_FAST_MATH = YES; 402 | ONLY_ACTIVE_ARCH = YES; 403 | SDKROOT = iphoneos; 404 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 405 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 406 | }; 407 | name = Debug; 408 | }; 409 | 0E1ED16C24247ED800714B52 /* Release */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | ALWAYS_SEARCH_USER_PATHS = NO; 413 | CLANG_ANALYZER_NONNULL = YES; 414 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 415 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 416 | CLANG_CXX_LIBRARY = "libc++"; 417 | CLANG_ENABLE_MODULES = YES; 418 | CLANG_ENABLE_OBJC_ARC = YES; 419 | CLANG_ENABLE_OBJC_WEAK = YES; 420 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 421 | CLANG_WARN_BOOL_CONVERSION = YES; 422 | CLANG_WARN_COMMA = YES; 423 | CLANG_WARN_CONSTANT_CONVERSION = YES; 424 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 425 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 426 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 427 | CLANG_WARN_EMPTY_BODY = YES; 428 | CLANG_WARN_ENUM_CONVERSION = YES; 429 | CLANG_WARN_INFINITE_RECURSION = YES; 430 | CLANG_WARN_INT_CONVERSION = YES; 431 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 432 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 433 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 434 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 435 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 436 | CLANG_WARN_STRICT_PROTOTYPES = YES; 437 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 438 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 439 | CLANG_WARN_UNREACHABLE_CODE = YES; 440 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 441 | COPY_PHASE_STRIP = NO; 442 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 443 | ENABLE_NS_ASSERTIONS = NO; 444 | ENABLE_STRICT_OBJC_MSGSEND = YES; 445 | GCC_C_LANGUAGE_STANDARD = gnu11; 446 | GCC_NO_COMMON_BLOCKS = YES; 447 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 448 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 449 | GCC_WARN_UNDECLARED_SELECTOR = YES; 450 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 451 | GCC_WARN_UNUSED_FUNCTION = YES; 452 | GCC_WARN_UNUSED_VARIABLE = YES; 453 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 454 | MTL_ENABLE_DEBUG_INFO = NO; 455 | MTL_FAST_MATH = YES; 456 | SDKROOT = iphoneos; 457 | SWIFT_COMPILATION_MODE = wholemodule; 458 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 459 | VALIDATE_PRODUCT = YES; 460 | }; 461 | name = Release; 462 | }; 463 | 0E1ED16E24247ED800714B52 /* Debug */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 467 | CODE_SIGN_STYLE = Automatic; 468 | DEVELOPMENT_TEAM = H5QW7TLM9U; 469 | INFOPLIST_FILE = TableSample/Info.plist; 470 | LD_RUNPATH_SEARCH_PATHS = ( 471 | "$(inherited)", 472 | "@executable_path/Frameworks", 473 | ); 474 | PRODUCT_BUNDLE_IDENTIFIER = am10.TableSample; 475 | PRODUCT_NAME = "$(TARGET_NAME)"; 476 | SWIFT_VERSION = 5.0; 477 | TARGETED_DEVICE_FAMILY = "1,2"; 478 | }; 479 | name = Debug; 480 | }; 481 | 0E1ED16F24247ED800714B52 /* Release */ = { 482 | isa = XCBuildConfiguration; 483 | buildSettings = { 484 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 485 | CODE_SIGN_STYLE = Automatic; 486 | DEVELOPMENT_TEAM = H5QW7TLM9U; 487 | INFOPLIST_FILE = TableSample/Info.plist; 488 | LD_RUNPATH_SEARCH_PATHS = ( 489 | "$(inherited)", 490 | "@executable_path/Frameworks", 491 | ); 492 | PRODUCT_BUNDLE_IDENTIFIER = am10.TableSample; 493 | PRODUCT_NAME = "$(TARGET_NAME)"; 494 | SWIFT_VERSION = 5.0; 495 | TARGETED_DEVICE_FAMILY = "1,2"; 496 | }; 497 | name = Release; 498 | }; 499 | /* End XCBuildConfiguration section */ 500 | 501 | /* Begin XCConfigurationList section */ 502 | 0E1ED15424247ED700714B52 /* Build configuration list for PBXProject "TableSample" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 0E1ED16B24247ED800714B52 /* Debug */, 506 | 0E1ED16C24247ED800714B52 /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | 0E1ED16D24247ED800714B52 /* Build configuration list for PBXNativeTarget "TableSample" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 0E1ED16E24247ED800714B52 /* Debug */, 515 | 0E1ED16F24247ED800714B52 /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | /* End XCConfigurationList section */ 521 | }; 522 | rootObject = 0E1ED15124247ED700714B52 /* Project object */; 523 | } 524 | -------------------------------------------------------------------------------- /TableSample/TableSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TableSample/TableSample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TableSample/TableSample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | return true 19 | } 20 | 21 | // MARK: UISceneSession Lifecycle 22 | 23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 24 | // Called when a new scene session is being created. 25 | // Use this method to select a configuration to create the new scene with. 26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 27 | } 28 | 29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 30 | // Called when the user discards a scene session. 31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 33 | } 34 | 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /TableSample/TableSample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /TableSample/TableSample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TableSample/TableSample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TableSample/TableSample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /TableSample/TableSample/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 44 | 51 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /TableSample/TableSample/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | 16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 20 | guard let _ = (scene as? UIWindowScene) else { return } 21 | } 22 | 23 | func sceneDidDisconnect(_ scene: UIScene) { 24 | // Called as the scene is being released by the system. 25 | // This occurs shortly after the scene enters the background, or when its session is discarded. 26 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 28 | } 29 | 30 | func sceneDidBecomeActive(_ scene: UIScene) { 31 | // Called when the scene has moved from an inactive state to an active state. 32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 33 | } 34 | 35 | func sceneWillResignActive(_ scene: UIScene) { 36 | // Called when the scene will move from an active state to an inactive state. 37 | // This may occur due to temporary interruptions (ex. an incoming phone call). 38 | } 39 | 40 | func sceneWillEnterForeground(_ scene: UIScene) { 41 | // Called as the scene transitions from the background to the foreground. 42 | // Use this method to undo the changes made on entering the background. 43 | } 44 | 45 | func sceneDidEnterBackground(_ scene: UIScene) { 46 | // Called as the scene transitions from the foreground to the background. 47 | // Use this method to save data, release shared resources, and store enough scene-specific state information 48 | // to restore the scene back to its current state. 49 | } 50 | 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/Customs.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 44 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/CustomsIndexViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomsIndexViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/23. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CustomsIndexViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/DoubleAccordion/DoubleAccordionTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoubleAccordionTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/31. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DoubleAccordionTableViewController: UITableViewController { 12 | 13 | enum CellType { 14 | case directory(isExpanded: Bool) 15 | case file 16 | var isDirectory: Bool { 17 | switch self { 18 | case .directory: 19 | return true 20 | default: 21 | return false 22 | } 23 | } 24 | var isExpanded: Bool { 25 | switch self { 26 | case .directory(let isExpanded): 27 | return isExpanded 28 | default: 29 | return false 30 | } 31 | } 32 | } 33 | struct CellData { 34 | let name: String 35 | let directoryIndex: Int 36 | var cellType: CellType 37 | } 38 | 39 | var expandSectionSet = Set() 40 | var sections = ["AAA", "BBB", "CCC", "DDD", "EEE"] 41 | var tableDataList = [[CellData]]() 42 | override func viewDidLoad() { 43 | super.viewDidLoad() 44 | var dataList = [CellData]() 45 | let isExpanded = false 46 | dataList.append(.init(name: "A", directoryIndex: 0, cellType: .directory(isExpanded: isExpanded))) 47 | dataList.append(.init(name: "test_001.txt", directoryIndex: 0, cellType: .file)) 48 | dataList.append(.init(name: "test_002.txt", directoryIndex: 0, cellType: .file)) 49 | dataList.append(.init(name: "B", directoryIndex: 1, cellType: .directory(isExpanded: isExpanded))) 50 | dataList.append(.init(name: "test_003.txt", directoryIndex: 1, cellType: .file)) 51 | dataList.append(.init(name: "test_004.txt", directoryIndex: 1, cellType: .file)) 52 | dataList.append(.init(name: "C", directoryIndex: 2, cellType: .directory(isExpanded: isExpanded))) 53 | dataList.append(.init(name: "test_005.txt", directoryIndex: 2, cellType: .file)) 54 | dataList.append(.init(name: "test_006.txt", directoryIndex: 2, cellType: .file)) 55 | tableView.register(UINib(nibName: "DoubleAccordionTableViewCell", bundle: nil), forCellReuseIdentifier: "Cell") 56 | tableView.register(UINib.init(nibName: "DoubleAccordionTableViewHeaderFooterView", bundle: nil), forHeaderFooterViewReuseIdentifier: "Header") 57 | tableView.tableFooterView = UIView() 58 | // tableView.rowHeight = 44 59 | // sections.enumerated().map { offset, value in offset }.forEach { expandSectionSet.insert($0) } // 最初から開く場合 60 | sections.forEach { _ in tableDataList.append(dataList) } 61 | } 62 | 63 | // MARK: - Table view data source 64 | 65 | override func numberOfSections(in tableView: UITableView) -> Int { 66 | return sections.count 67 | } 68 | 69 | override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 70 | let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "Header") as! DoubleAccordionTableViewHeaderFooterView 71 | header.nameLabel.text = sections[section] 72 | header.section = section 73 | header.delegate = self 74 | return header 75 | } 76 | 77 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 78 | return expandSectionSet.contains(section) ? tableDataList[section].count : 0 79 | } 80 | 81 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 82 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! DoubleAccordionTableViewCell 83 | let data = tableDataList[indexPath.section][indexPath.row] 84 | cell.showData(data) 85 | return cell 86 | } 87 | 88 | override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 89 | let data = tableDataList[indexPath.section][indexPath.row] 90 | if data.cellType.isDirectory { 91 | return 44 92 | } 93 | let dataList = tableDataList[indexPath.section] 94 | let directory = dataList.filter { $0.cellType.isDirectory && $0.directoryIndex == data.directoryIndex }.first 95 | return directory?.cellType.isExpanded == true ? 44 : 0 96 | } 97 | 98 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 99 | let data = tableDataList[indexPath.section][indexPath.row] 100 | tableView.deselectRow(at: indexPath, animated: false) 101 | if !data.cellType.isDirectory { 102 | return 103 | } 104 | var updateElement = data 105 | updateElement.cellType = .directory(isExpanded: !data.cellType.isExpanded) 106 | tableDataList[indexPath.section][indexPath.row] = updateElement 107 | var indexPaths = [IndexPath]() 108 | tableDataList[indexPath.section].enumerated().forEach { offset, value in 109 | if value.directoryIndex == data.directoryIndex { 110 | indexPaths.append(IndexPath(row: offset, section: indexPath.section) ) 111 | } 112 | } 113 | tableView.reloadRows(at: indexPaths, with: .automatic) 114 | } 115 | } 116 | 117 | extension DoubleAccordionTableViewController: DoubleAccordionTableViewHeaderFooterViewDelegate { 118 | func doubleAccordionTableViewHeaderFooterView(_ header: DoubleAccordionTableViewHeaderFooterView, section: Int) { 119 | if expandSectionSet.contains(section) { 120 | expandSectionSet.remove(section) 121 | } else { 122 | expandSectionSet.insert(section) 123 | } 124 | tableView.reloadSections([section], with: .automatic) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/DoubleAccordion/Parts/DoubleAccordionTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoubleAccordionTableViewCell.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/31. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DoubleAccordionTableViewCell: UITableViewCell { 12 | 13 | @IBOutlet weak private var leadingConstraint: NSLayoutConstraint! 14 | @IBOutlet weak private var nameLabel: UILabel! 15 | @IBOutlet weak private var iconImageView: UIImageView! 16 | 17 | func showData(_ data: DoubleAccordionTableViewController.CellData) { 18 | nameLabel.text = data.name 19 | iconImageView.image = data.cellType.isDirectory ? UIImage(systemName: "folder.fill") : UIImage(systemName: "doc.text") 20 | leadingConstraint.constant = data.cellType.isDirectory ? 32 : 48 21 | separatorInset = .init(top: 0, left: data.cellType.isDirectory ? 16 : 32, bottom: 0, right: 0) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/DoubleAccordion/Parts/DoubleAccordionTableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/DoubleAccordion/Parts/DoubleAccordionTableViewHeaderFooterView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoubleAccordionTableViewHeaderFooterView.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/31. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol DoubleAccordionTableViewHeaderFooterViewDelegate: AnyObject { 12 | func doubleAccordionTableViewHeaderFooterView(_ header: DoubleAccordionTableViewHeaderFooterView, section: Int) 13 | } 14 | 15 | class DoubleAccordionTableViewHeaderFooterView: UITableViewHeaderFooterView { 16 | 17 | weak var delegate: DoubleAccordionTableViewHeaderFooterViewDelegate? 18 | @IBOutlet weak var nameLabel: UILabel! 19 | var section = 0 20 | 21 | override func awakeFromNib() { 22 | contentView.backgroundColor = .systemBackground 23 | } 24 | 25 | @IBAction private func didTap(_ sender: Any) { 26 | delegate?.doubleAccordionTableViewHeaderFooterView(self, section: section) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/DoubleAccordion/Parts/DoubleAccordionTableViewHeaderFooterView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/SingleAccordion/Parts/SingleAccordionTableViewHeaderFooterView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingleAccordionTableViewHeaderFooterView.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/04/24. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol SingleAccordionTableViewHeaderFooterViewDelegate: AnyObject { 12 | func singleAccordionTableViewHeaderFooterView(_ header: SingleAccordionTableViewHeaderFooterView, section: Int) 13 | } 14 | 15 | class SingleAccordionTableViewHeaderFooterView: UITableViewHeaderFooterView { 16 | 17 | weak var delegate: SingleAccordionTableViewHeaderFooterViewDelegate? 18 | @IBOutlet weak var nameLabel: UILabel! 19 | var section = 0 20 | 21 | override func awakeFromNib() { 22 | contentView.backgroundColor = .systemBackground 23 | } 24 | 25 | @IBAction private func didTap(_ sender: Any) { 26 | delegate?.singleAccordionTableViewHeaderFooterView(self, section: section) 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/SingleAccordion/Parts/SingleAccordionTableViewHeaderFooterView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Customs/SingleAccordion/SingleAccordionTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SingleAccordionTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/04/24. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SingleAccordionTableViewController: UITableViewController { 12 | 13 | struct CellData { 14 | let name: String 15 | } 16 | 17 | var expandSectionSet = Set() 18 | var tableDataList = [[CellData]]() 19 | var sections = ["AAA", "BBB", "CCC", "DDD", "EEE"] 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | 23 | tableDataList.append([.init(name: "test_001.txt"), 24 | .init(name: "test_002.txt"), 25 | .init(name: "test_003.txt")]) 26 | tableDataList.append([.init(name: "test_004.txt"), 27 | .init(name: "test_005.txt"), 28 | .init(name: "test_006.txt")]) 29 | tableDataList.append([.init(name: "test_007.txt"), 30 | .init(name: "test_008.txt")]) 31 | tableDataList.append([.init(name: "test_009.txt"), 32 | .init(name: "test_010.txt"), 33 | .init(name: "test_011.txt")]) 34 | tableDataList.append([.init(name: "test_012.txt"), 35 | .init(name: "test_013.txt")]) 36 | 37 | tableView.register(UINib(nibName: "SingleAccordionTableViewHeaderFooterView", bundle: nil), forHeaderFooterViewReuseIdentifier: "Header") 38 | } 39 | 40 | // MARK: - Table view data source 41 | 42 | override func numberOfSections(in tableView: UITableView) -> Int { 43 | return sections.count 44 | } 45 | 46 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 47 | return expandSectionSet.contains(section) ? tableDataList[section].count : 0 48 | } 49 | 50 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 51 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 52 | cell.textLabel?.text = tableDataList[indexPath.section][indexPath.row].name 53 | return cell 54 | } 55 | 56 | override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 57 | let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "Header") as! SingleAccordionTableViewHeaderFooterView 58 | header.section = section 59 | header.nameLabel.text = sections[section] 60 | header.delegate = self 61 | return header 62 | } 63 | } 64 | 65 | extension SingleAccordionTableViewController: SingleAccordionTableViewHeaderFooterViewDelegate { 66 | func singleAccordionTableViewHeaderFooterView(_ header: SingleAccordionTableViewHeaderFooterView, section: Int) { 67 | if expandSectionSet.contains(section) { 68 | expandSectionSet.remove(section) 69 | } else { 70 | expandSectionSet.insert(section) 71 | } 72 | tableView.reloadSections([section], with: .automatic) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/CellAccessoryTypeTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CellAccessoryTypeTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CellAccessoryTypeTableViewController: UITableViewController { 12 | 13 | struct CellData { 14 | let title: String 15 | let accessoryType: UITableViewCell.AccessoryType 16 | let color: UIColor 17 | } 18 | 19 | let tableDataList: [CellData] = [ 20 | .init(title: "None", accessoryType: .none, color: .systemYellow), 21 | .init(title: "DetailButton", accessoryType: .detailButton, color: .systemRed), 22 | .init(title: "DetailDisclosureButton", accessoryType: .detailDisclosureButton, color: .systemOrange), 23 | .init(title: "DisclosureIndicator", accessoryType: .disclosureIndicator, color: .systemPurple), 24 | .init(title: "Checkmark", accessoryType: .checkmark, color: .systemGreen) 25 | ] 26 | 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | 30 | } 31 | 32 | // MARK: - Table view data source 33 | override func numberOfSections(in tableView: UITableView) -> Int { 34 | return 2 35 | } 36 | 37 | override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 38 | return section == 0 ? "Default" : "Color" 39 | } 40 | 41 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 42 | return tableDataList.count 43 | } 44 | 45 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 46 | let cellData = tableDataList[indexPath.row] 47 | let identifier = indexPath.section == 0 ? "Cell" : "Color" 48 | let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath) 49 | cell.textLabel?.text = cellData.title 50 | cell.accessoryType = cellData.accessoryType 51 | if indexPath.section == 1 { 52 | cell.tintColor = cellData.color 53 | } 54 | return cell 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/CellStyleTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CellStyleTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CellStyleTableViewController: UITableViewController { 12 | 13 | enum CellType: String { 14 | case basic 15 | case left 16 | case right 17 | case subtitle 18 | } 19 | struct CellData { 20 | let title: String 21 | let detail: String? 22 | let type: CellType 23 | let imageName: String? 24 | } 25 | 26 | let tableDataList: [CellData] = [ 27 | .init(title: "Basic", detail: "Detail", type: .basic, imageName: nil), 28 | .init(title: "Basic", detail: "Detail", type: .basic, imageName: "person.crop.square.fill"), 29 | .init(title: "Left", detail: "Detail", type: .left, imageName: nil), 30 | .init(title: "Left", detail: "Detail", type: .left, imageName: "person.crop.square.fill"), 31 | .init(title: "Right", detail: "Detail", type: .right, imageName: nil), 32 | .init(title: "Right", detail: "Detail", type: .right, imageName: "person.crop.square.fill"), 33 | .init(title: "Subtitle", detail: "Detail", type: .subtitle, imageName: nil), 34 | .init(title: "Subtitle", detail: "Detail", type: .subtitle, imageName: "person.crop.square.fill") 35 | ] 36 | 37 | override func viewDidLoad() { 38 | super.viewDidLoad() 39 | } 40 | 41 | // MARK: - Table view data source 42 | 43 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 44 | return tableDataList.count 45 | } 46 | 47 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 48 | let cellData = tableDataList[indexPath.row] 49 | let cell = tableView.dequeueReusableCell(withIdentifier: cellData.type.rawValue, for: indexPath) 50 | cell.textLabel?.text = cellData.title 51 | cell.detailTextLabel?.text = cellData.detail 52 | cell.imageView?.image = cellData.imageName.flatMap { UIImage.init(systemName: $0) } 53 | // 画像表示のseparatorInsetをあわせる場合separatorInsetを設定する 54 | // cell.separatorInset = .zero // .init(top: 0, left: 15.0, bottom: 0, right: 0) 55 | // もしくはviewDidLoadとかでtableView.separatorInsetを設定する 56 | return cell 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/ColorCellTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorCellTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ColorCellTableViewController: UITableViewController { 12 | 13 | let tableDataList: [UIColor] = [ 14 | .systemRed, 15 | .systemOrange, 16 | .systemYellow, 17 | .systemGreen, 18 | .systemTeal, 19 | .systemBlue, 20 | .systemPurple 21 | ] 22 | 23 | override func viewDidLoad() { 24 | super.viewDidLoad() 25 | tableView.separatorColor = .white 26 | } 27 | 28 | // MARK: - Table view data source 29 | 30 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 31 | return tableDataList.count 32 | } 33 | 34 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 35 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 36 | if cell.backgroundView == nil { 37 | cell.backgroundView = UIView() 38 | } 39 | cell.textLabel?.text = "Row: \(indexPath.row)" 40 | cell.textLabel?.textColor = .white 41 | cell.backgroundView?.backgroundColor = tableDataList[indexPath.row] 42 | return cell 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/ColorSectionTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorSectionTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ColorSectionTableViewController: UITableViewController { 12 | 13 | let tableDataList: [UIColor] = [ 14 | .systemRed, 15 | .systemOrange, 16 | .systemYellow, 17 | .systemGreen, 18 | .systemTeal, 19 | .systemBlue, 20 | .systemPurple 21 | ] 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | } 25 | 26 | // MARK: - Table view data source 27 | 28 | override func numberOfSections(in tableView: UITableView) -> Int { 29 | // #warning Incomplete implementation, return the number of sections 30 | return tableDataList.count 31 | } 32 | 33 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 34 | return 1 35 | } 36 | 37 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 38 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 39 | cell.textLabel?.text = "Row: \(indexPath.row)" 40 | return cell 41 | } 42 | 43 | override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 44 | var header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") 45 | if header == nil { 46 | header = UITableViewHeaderFooterView(reuseIdentifier: "header") 47 | } 48 | if header?.backgroundView == nil { 49 | header?.backgroundView = UIView() 50 | } 51 | header?.textLabel?.text = "section header \(section)" 52 | header?.backgroundView?.backgroundColor = tableDataList[section] 53 | header?.textLabel?.textColor = .white 54 | return header 55 | } 56 | 57 | override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { 58 | var footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: "footer") 59 | if footer == nil { 60 | footer = UITableViewHeaderFooterView(reuseIdentifier: "footer") 61 | } 62 | if footer?.backgroundView == nil { 63 | footer?.backgroundView = UIView() 64 | } 65 | footer?.textLabel?.text = "section footer \(section)" 66 | footer?.backgroundView?.backgroundColor = tableDataList.reversed()[section] 67 | footer?.textLabel?.textColor = .white 68 | return footer 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/DefaultAppearancesIndexViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DefaultAppearancesIndexViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/23. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DefaultAppearancesIndexViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/GroupedDetailViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GroupedDetailViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class GroupedDetailViewController: UIViewController { 12 | 13 | @IBOutlet var tableViews: [UITableView]! 14 | let tableDataList = [Int](repeating: 0, count: 5) 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | // Do any additional setup after loading the view. 19 | tableViews.forEach { 20 | $0.dataSource = self 21 | $0.delegate = self 22 | } 23 | } 24 | } 25 | 26 | extension GroupedDetailViewController: UITableViewDataSource { 27 | func numberOfSections(in tableView: UITableView) -> Int { 28 | return 2 29 | } 30 | 31 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 32 | return tableDataList.count 33 | } 34 | 35 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 36 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 37 | cell.textLabel?.text = "Row: \(indexPath.row)" 38 | return cell 39 | } 40 | 41 | func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { 42 | return "section footer \(section)" 43 | } 44 | } 45 | 46 | extension GroupedDetailViewController: UITableViewDelegate { 47 | func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 48 | var header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") 49 | if header == nil { 50 | header = UITableViewHeaderFooterView(reuseIdentifier: "header") 51 | } 52 | header?.textLabel?.text = "section header \(section)" 53 | header?.detailTextLabel?.text = "detail" 54 | return header 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/SelectedColorCellTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SelectedColorCellTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SelectedColorCellTableViewController: UITableViewController { 12 | 13 | struct CellData { 14 | let title: String 15 | let color: UIColor 16 | } 17 | let tableDataList: [CellData] = [ 18 | .init(title: "Red", color: .systemRed), 19 | .init(title: "Orange", color: .systemOrange), 20 | .init(title: "Yellow", color: .systemYellow), 21 | .init(title: "Green", color: .systemGreen), 22 | .init(title: "Teal", color: .systemTeal), 23 | .init(title: "Blue", color: .systemBlue), 24 | .init(title: "Purple", color: .systemPurple) 25 | ] 26 | 27 | override func viewDidLoad() { 28 | super.viewDidLoad() 29 | } 30 | 31 | // MARK: - Table view data source 32 | 33 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 34 | return tableDataList.count 35 | } 36 | 37 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 38 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 39 | let cellData = tableDataList[indexPath.row] 40 | cell.textLabel?.text = cellData.title 41 | cell.textLabel?.highlightedTextColor = .white 42 | let v = UIView() 43 | v.backgroundColor = cellData.color 44 | cell.selectedBackgroundView = v 45 | return cell 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/SeparatorStyleViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SeparatorStyleViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SeparatorStyleViewController: UIViewController { 12 | 13 | @IBOutlet var tableViews: [UITableView]! 14 | let tableDataList = [Int](repeating: 0, count: 5) 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | // Do any additional setup after loading the view. 19 | tableViews.forEach { 20 | $0.dataSource = self 21 | // 区切り線のinsetと色設定 22 | // $0.separatorColor = .blue 23 | // $0.separatorInset = .init(top: 0, left: 30, bottom: 0, right: 0) 24 | } 25 | } 26 | } 27 | 28 | extension SeparatorStyleViewController: UITableViewDataSource { 29 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 30 | return tableDataList.count 31 | } 32 | 33 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 34 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 35 | cell.textLabel?.text = "Row: \(indexPath.row)" 36 | // セルごとのinset設定はできるが色設定はできない 37 | // cell.separatorInset = .zero 38 | return cell 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/DefaultAppearances/TableStyleViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableStyleViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TableStyleViewController: UIViewController { 12 | 13 | @IBOutlet var tableViews: [UITableView]! 14 | let tableDataList = [Int](repeating: 0, count: 5) 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | // Do any additional setup after loading the view. 19 | tableViews.forEach { 20 | $0.dataSource = self 21 | $0.delegate = self 22 | } 23 | } 24 | } 25 | 26 | extension TableStyleViewController: UITableViewDataSource { 27 | func numberOfSections(in tableView: UITableView) -> Int { 28 | return 2 29 | } 30 | 31 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 32 | return tableDataList.count 33 | } 34 | 35 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 36 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 37 | cell.textLabel?.text = "Row: \(indexPath.row)" 38 | return cell 39 | } 40 | 41 | func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 42 | return "section header \(section)" 43 | } 44 | 45 | func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { 46 | return "section footer \(section)" 47 | } 48 | } 49 | 50 | extension TableStyleViewController: UITableViewDelegate { 51 | // セクションの文字色変えたい場合 52 | // func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { 53 | // (view as? UITableViewHeaderFooterView)?.textLabel?.textColor = .red 54 | // } 55 | // 56 | // func tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { 57 | // (view as? UITableViewHeaderFooterView)?.textLabel?.textColor = .blue 58 | // } 59 | } 60 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/CellEditingTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CellEditingTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by macbook on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CellEditingTableViewController: UITableViewController { 12 | // 色々ぶつかる項目があるが目を瞑る 13 | public struct EditMode : OptionSet { 14 | let rawValue: UInt 15 | static let uneditable = EditMode(rawValue: 1 << 0) 16 | static let movable = EditMode(rawValue: 1 << 1) 17 | static let deletable = EditMode(rawValue: 1 << 2) 18 | static let addable = EditMode(rawValue: 2 << 3) 19 | var title: String { 20 | if self.contains(.uneditable) { 21 | return "Not Editable" 22 | } 23 | if self.contains(.movable) && self.contains(.deletable) { 24 | return "Movable & Deletable" 25 | } 26 | if self.contains(.movable) && self.contains(.addable) { 27 | return "Movable & Addable" 28 | } 29 | if self.contains(.movable) { 30 | return "Movable" 31 | } 32 | if self.contains(.deletable) { 33 | return "Deletable" 34 | } 35 | if self.contains(.addable) { 36 | return "Addable" 37 | } 38 | return "" 39 | } 40 | } 41 | 42 | struct CellData { 43 | let editMode: EditMode 44 | } 45 | 46 | var tableDataList: [CellData] = [ 47 | .init(editMode: [.uneditable]), 48 | .init(editMode: [.movable]), 49 | .init(editMode: [.deletable]), 50 | .init(editMode: [.addable]), 51 | .init(editMode: [.movable, .deletable]), 52 | .init(editMode: [.movable, .addable]), 53 | ] 54 | 55 | override func viewDidLoad() { 56 | super.viewDidLoad() 57 | navigationItem.rightBarButtonItem = editButtonItem 58 | // tableView.isEditing = true // 初期表示で編集モードにしたい場合 59 | // tableView.allowsSelectionDuringEditing = true // 編集モードの時も選択を有効にしたい場合 60 | } 61 | 62 | // MARK: - Table view data source 63 | 64 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 65 | return tableDataList.count 66 | } 67 | 68 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 69 | let cellData = tableDataList[indexPath.row] 70 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 71 | cell.textLabel?.text = cellData.editMode.title 72 | return cell 73 | } 74 | 75 | override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 76 | let cellData = tableDataList[indexPath.row] 77 | return !cellData.editMode.contains(.uneditable) 78 | } 79 | 80 | override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 81 | let cellData = tableDataList[indexPath.row] 82 | return cellData.editMode.contains(.movable) 83 | } 84 | 85 | override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle { 86 | let cellData = tableDataList[indexPath.row] 87 | if cellData.editMode.contains(.uneditable) { 88 | return .none 89 | } 90 | if cellData.editMode.contains(.deletable) { 91 | return .delete 92 | } 93 | if cellData.editMode.contains(.addable) { 94 | return .insert 95 | } 96 | return .none 97 | } 98 | 99 | override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { 100 | let element = tableDataList[sourceIndexPath.row] 101 | tableDataList.remove(at: sourceIndexPath.row) 102 | tableDataList.insert(element, at: destinationIndexPath.row) 103 | } 104 | 105 | override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath { 106 | let cellData = tableDataList[proposedDestinationIndexPath.row] 107 | return cellData.editMode.contains(.uneditable) ? sourceIndexPath : proposedDestinationIndexPath 108 | } 109 | 110 | override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 111 | if editingStyle == .delete { 112 | tableDataList.remove(at: indexPath.row) 113 | tableView.beginUpdates() 114 | tableView.deleteRows(at: [indexPath], with: .automatic) 115 | tableView.endUpdates() 116 | } 117 | if editingStyle == .insert { 118 | tableDataList.insert(CellData(editMode: [.deletable, .movable]), at: indexPath.row + 1) 119 | tableView.beginUpdates() 120 | tableView.insertRows(at: [IndexPath(row: indexPath.row + 1, section: 0)], with: .automatic) 121 | tableView.endUpdates() 122 | } 123 | } 124 | 125 | // 編集モードの時にインデントを無効にする場合(削除・追加ボタンが有る場合は効かない) 126 | // override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool { 127 | // return false 128 | // } 129 | } 130 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/ContextMenuTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContextMenuTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/21. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ContextMenuTableViewController: UITableViewController { 12 | 13 | struct Menu : OptionSet { 14 | let rawValue: UInt 15 | static let share = Menu(rawValue: 1 << 0) 16 | static let copy = Menu(rawValue: 1 << 1) 17 | var title: String { 18 | var titles = [String]() 19 | if self.contains(.share) { 20 | titles.append("Share") 21 | } 22 | if self.contains(.copy) { 23 | titles.append("Copy") 24 | } 25 | return titles.joined(separator: " & ") 26 | } 27 | } 28 | 29 | let tableDataList: [Menu] = [ 30 | .share, 31 | .copy, 32 | [.share, .copy] 33 | ] 34 | 35 | override func viewDidLoad() { 36 | super.viewDidLoad() 37 | } 38 | 39 | // MARK: - Table view data source 40 | 41 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 42 | return tableDataList.count 43 | } 44 | 45 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 46 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 47 | cell.textLabel?.text = "Row: \(indexPath.row) \(tableDataList[indexPath.row].title)" 48 | return cell 49 | } 50 | 51 | // Deprecated 52 | // tableView(_:shouldShowMenuForRowAt:) -> Bool 53 | // tableView(_:canPerformAction:forRowAt:withSender:) -> Bool 54 | // tableView(_:performAction:forRowAt:withSender:) 55 | override func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { 56 | let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] actions -> UIMenu? in 57 | return self?.makeMenu(for: indexPath) 58 | } 59 | return configuration 60 | } 61 | } 62 | 63 | extension ContextMenuTableViewController { 64 | private func makeMenu(for indexPath: IndexPath) -> UIMenu { 65 | let menu = tableDataList[indexPath.row] 66 | var actions = [UIAction]() 67 | if menu.contains(.share) { 68 | let share = UIAction(title: "Share", image: UIImage(systemName: "square.and.arrow.up"), 69 | identifier: nil) 70 | { [weak self] action in 71 | self?.share(at: indexPath) 72 | } 73 | actions.append(share) 74 | } 75 | if menu.contains(.copy) { 76 | let copy = UIAction(title: "Copy", image: UIImage(systemName: "doc.on.doc"), 77 | identifier: nil) 78 | { [weak self] action in 79 | self?.copy(at: indexPath) 80 | } 81 | actions.append(copy) 82 | } 83 | return UIMenu(__title: "Menu", image: nil, identifier: nil, children: actions) 84 | } 85 | 86 | private func copy(at indexPath: IndexPath) { 87 | if let cell = tableView.cellForRow(at: indexPath) { 88 | UIPasteboard.general.string = cell.textLabel?.text 89 | } 90 | } 91 | 92 | private func share(at indexPath: IndexPath) { 93 | guard let cell = tableView.cellForRow(at: indexPath), 94 | let text = cell.textLabel?.text else { 95 | return 96 | } 97 | let controller = UIActivityViewController(activityItems: [text], 98 | applicationActivities: nil) 99 | controller.popoverPresentationController?.sourceView = cell 100 | present(controller, animated: true, completion: nil) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/MultiSelectionLeftTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiSelectionLeftTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/25. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MultiSelectionLeftTableViewController: UITableViewController { 12 | 13 | var tableDataList = [Int](repeating: 0, count: 20) 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | tableView.isEditing = true 17 | tableView.allowsMultipleSelection = true 18 | tableView.allowsMultipleSelectionDuringEditing = true 19 | } 20 | 21 | // MARK: - Table view data source 22 | 23 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 24 | return tableDataList.count 25 | } 26 | 27 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 28 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 29 | cell.textLabel?.text = "Row: \(indexPath.row)" 30 | return cell 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/MultiSelectionTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MultiSelectionTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/21. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MultiSelectionTableViewController: UITableViewController { 12 | 13 | var tableDataList = [Int](repeating: 0, count: 20) 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | tableView.allowsMultipleSelection = true 17 | } 18 | 19 | // MARK: - Table view data source 20 | 21 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 22 | return tableDataList.count 23 | } 24 | 25 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 26 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 27 | cell.textLabel?.text = "Row: \(indexPath.row)" 28 | cell.accessoryType = tableView.indexPathsForSelectedRows?.contains(indexPath) == true ? .checkmark : .none 29 | cell.selectionStyle = .none // 選択時に背景色を変えないため 30 | return cell 31 | } 32 | 33 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 34 | if let cell = tableView.cellForRow(at: indexPath) { 35 | cell.accessoryType = .checkmark 36 | } 37 | } 38 | 39 | override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 40 | if let cell = tableView.cellForRow(at: indexPath) { 41 | cell.accessoryType = .none 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/Operations.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 44 | 51 | 58 | 65 | 72 | 79 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/OperationsIndexViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OperationsIndexViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/23. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class OperationsIndexViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/SectionIndexTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SectionIndexTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/24. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SectionIndexTableViewController: UIViewController { 12 | 13 | @IBOutlet weak var defaultTableView: UITableView! { 14 | didSet { 15 | defaultTableView.dataSource = self 16 | } 17 | } 18 | @IBOutlet weak var colorTableView: UITableView! { 19 | didSet { 20 | colorTableView.dataSource = self 21 | colorTableView.sectionIndexColor = .white 22 | colorTableView.sectionIndexBackgroundColor = .systemPurple 23 | colorTableView.sectionIndexTrackingBackgroundColor = .systemRed 24 | } 25 | } 26 | var tableDataList = [Int](repeating: 0, count: 20) 27 | var sections = [Int](1...20) 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | } 31 | } 32 | 33 | extension SectionIndexTableViewController: UITableViewDataSource { 34 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 35 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 36 | cell.textLabel?.text = "Row: \(indexPath.row)" 37 | return cell 38 | } 39 | 40 | func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 41 | return "Section: \(sections[section])" 42 | } 43 | 44 | func numberOfSections(in tableView: UITableView) -> Int { 45 | return sections.count 46 | } 47 | 48 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 49 | return tableDataList.count 50 | } 51 | 52 | func sectionIndexTitles(for tableView: UITableView) -> [String]? { 53 | return [UITableView.indexSearch] + sections.map { "\($0)" } 54 | } 55 | 56 | func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int { 57 | if title == UITableView.indexSearch { 58 | return 0 59 | } 60 | return index - 1 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/SwipeTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/23. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SwipeTableViewController: UITableViewController { 12 | enum CellData: CaseIterable{ 13 | case `default` 14 | case custom 15 | case onlyRight 16 | case onlyLeft 17 | case none 18 | case fullSwipe 19 | case many 20 | var title: String { 21 | switch self { 22 | case .default: 23 | return "Default" 24 | case .custom: 25 | return "Custom" 26 | case .onlyRight: 27 | return "Only Right Menu" 28 | case .onlyLeft: 29 | return "Only Left Menu" 30 | case .none: 31 | return "None" 32 | case .fullSwipe: 33 | return "performsFirstActionWithFullSwipe is false" 34 | case .many: 35 | return "Add 7 items" 36 | } 37 | } 38 | } 39 | 40 | let tableDataList = CellData.allCases 41 | override func viewDidLoad() { 42 | super.viewDidLoad() 43 | } 44 | 45 | // MARK: - Table view data source 46 | 47 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 48 | return tableDataList.count 49 | } 50 | 51 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 52 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 53 | cell.textLabel?.text = tableDataList[indexPath.row].title 54 | return cell 55 | } 56 | 57 | override func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { 58 | let cellData = tableDataList[indexPath.row] 59 | switch cellData { 60 | case .default: 61 | return makeDefaultLeadingAction() 62 | case .custom: 63 | return makeCustomLeadingAction() 64 | case .onlyRight: 65 | return nil 66 | case .onlyLeft: 67 | return makeOnlyLeftLeadingAction() 68 | case .none: 69 | return nil 70 | case .fullSwipe: 71 | return makeFullSwipeLeadingAction() 72 | case .many: 73 | return makeManyAction() 74 | } 75 | } 76 | 77 | override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { 78 | let cellData = tableDataList[indexPath.row] 79 | switch cellData { 80 | case .default: 81 | return makeDefaultTrailingAction() 82 | case .custom: 83 | return makeCustomTrailingAction() 84 | case .onlyRight: 85 | return makeOnlyRightTrailingAction() 86 | case .onlyLeft: 87 | return nil 88 | case .none: 89 | return nil 90 | case .fullSwipe: 91 | return makeFullSwipeTrailingAction() 92 | case .many: 93 | return makeManyAction() 94 | } 95 | } 96 | } 97 | 98 | extension SwipeTableViewController { 99 | private func makeDefaultLeadingAction() -> UISwipeActionsConfiguration { 100 | let normalAction = UIContextualAction(style: .normal, title: "Normal") { 101 | [weak self] (action, view, completionHandler) in 102 | self?.showAlert(message: "Normal") 103 | completionHandler(true) 104 | } 105 | let destructiveAction = UIContextualAction(style: .destructive, title: "Destructive") { 106 | [weak self] (action, view, completionHandler) in 107 | self?.showAlert(message: "Destructive") 108 | completionHandler(true) 109 | } 110 | let configuration = UISwipeActionsConfiguration(actions: [normalAction, destructiveAction]) 111 | return configuration 112 | } 113 | 114 | private func makeDefaultTrailingAction() -> UISwipeActionsConfiguration { 115 | let normalAction = UIContextualAction(style: .normal, title: "Normal") { 116 | [weak self] (action, view, completionHandler) in 117 | self?.showAlert(message: "Normal") 118 | completionHandler(true) 119 | } 120 | let destructiveAction = UIContextualAction(style: .destructive, title: "Destructive") { 121 | [weak self] (action, view, completionHandler) in 122 | self?.showAlert(message: "Destructive") 123 | completionHandler(true) 124 | } 125 | let configuration = UISwipeActionsConfiguration(actions: [normalAction, destructiveAction]) 126 | return configuration 127 | } 128 | 129 | private func makeCustomLeadingAction() -> UISwipeActionsConfiguration { 130 | let action = UIContextualAction(style: .normal, title: "Normal") { 131 | [weak self] (action, view, completionHandler) in 132 | self?.showAlert(message: "Pencil") 133 | completionHandler(true) 134 | } 135 | action.backgroundColor = .systemBlue 136 | action.image = UIImage(systemName: "pencil.circle.fill") 137 | let configuration = UISwipeActionsConfiguration(actions: [action]) 138 | return configuration 139 | } 140 | 141 | private func makeCustomTrailingAction() -> UISwipeActionsConfiguration { 142 | let action = UIContextualAction(style: .destructive, title: "Destructive") { 143 | [weak self] (action, view, completionHandler) in 144 | self?.showAlert(message: "Trash") 145 | completionHandler(true) 146 | } 147 | action.backgroundColor = .systemOrange 148 | action.image = UIImage(systemName: "trash.fill") 149 | let configuration = UISwipeActionsConfiguration(actions: [action]) 150 | return configuration 151 | } 152 | 153 | private func makeOnlyRightTrailingAction() -> UISwipeActionsConfiguration { 154 | let action = UIContextualAction(style: .normal, title: "Right") { 155 | [weak self] (action, view, completionHandler) in 156 | self?.showAlert(message: "Only Right Trailing Action!") 157 | completionHandler(true) 158 | } 159 | let configuration = UISwipeActionsConfiguration(actions: [action]) 160 | return configuration 161 | } 162 | 163 | private func makeOnlyLeftLeadingAction() -> UISwipeActionsConfiguration { 164 | let action = UIContextualAction(style: .normal, title: "Left") { 165 | [weak self] (action, view, completionHandler) in 166 | self?.showAlert(message: "Only Left Leading Action!") 167 | completionHandler(true) 168 | } 169 | let configuration = UISwipeActionsConfiguration(actions: [action]) 170 | return configuration 171 | } 172 | 173 | private func makeFullSwipeLeadingAction() -> UISwipeActionsConfiguration { 174 | let action = UIContextualAction(style: .normal, title: "FullSwipe") { 175 | [weak self] (action, view, completionHandler) in 176 | self?.showAlert(message: "Full Swipe Leading Action!") 177 | completionHandler(true) 178 | } 179 | let configuration = UISwipeActionsConfiguration(actions: [action]) 180 | configuration.performsFirstActionWithFullSwipe = false 181 | return configuration 182 | } 183 | 184 | private func makeFullSwipeTrailingAction() -> UISwipeActionsConfiguration { 185 | let action = UIContextualAction(style: .normal, title: "FullSwipe") { 186 | [weak self] (action, view, completionHandler) in 187 | self?.showAlert(message: "Full Swipe Trailing Action!") 188 | completionHandler(true) 189 | } 190 | let configuration = UISwipeActionsConfiguration(actions: [action]) 191 | configuration.performsFirstActionWithFullSwipe = false 192 | return configuration 193 | } 194 | 195 | private func makeManyAction() -> UISwipeActionsConfiguration { 196 | let action1 = makeManyAction(at: 1, color: .systemRed) 197 | let action2 = makeManyAction(at: 2, color: .systemOrange) 198 | let action3 = makeManyAction(at: 3, color: .systemYellow) 199 | let action4 = makeManyAction(at: 4, color: .systemGreen) 200 | let action5 = makeManyAction(at: 5, color: .systemTeal) 201 | let action6 = makeManyAction(at: 6, color: .systemBlue) 202 | let action7 = makeManyAction(at: 7, color: .systemPurple) 203 | let configuration = UISwipeActionsConfiguration(actions: [action1, action2, action3, 204 | action4, action5, action6, action7]) 205 | configuration.performsFirstActionWithFullSwipe = false 206 | return configuration 207 | } 208 | 209 | private func makeManyAction(at index: Int, color: UIColor) -> UIContextualAction { 210 | let action = UIContextualAction(style: .normal, title: "Item\(index)") { 211 | [weak self] (action, view, completionHandler) in 212 | self?.showAlert(message: "Item\(index) Action!") 213 | completionHandler(true) 214 | } 215 | action.backgroundColor = color 216 | return action 217 | } 218 | 219 | private func showAlert(message: String) { 220 | let alertController = UIAlertController(title: "", message: message, preferredStyle: .alert) 221 | let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil) 222 | alertController.addAction(defaultAction) 223 | present(alertController, animated: true, completion: nil) 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /TableSample/TableSample/Tables/Operations/UnselectablePartsTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UnselectablePartsTableViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/21. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class UnselectablePartsTableViewController: UITableViewController { 12 | 13 | struct CellData { 14 | let title: String 15 | let selectable: Bool 16 | } 17 | 18 | let tableDataList: [CellData] = [ 19 | .init(title: "Selectable", selectable: true), 20 | .init(title: "Selectable", selectable: true), 21 | .init(title: "Unselectable", selectable: false), 22 | .init(title: "Selectable", selectable: true), 23 | .init(title: "Unselectable", selectable: false) 24 | ] 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | } 28 | 29 | // MARK: - Table view data source 30 | 31 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 32 | return tableDataList.count 33 | } 34 | 35 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 36 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 37 | let cellData = tableDataList[indexPath.row] 38 | cell.textLabel?.text = cellData.title 39 | cell.selectionStyle = cellData.selectable ? .default : .none // noneだけだとselect自体はできる 40 | return cell 41 | } 42 | 43 | override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { 44 | let cellData = tableDataList[indexPath.row] 45 | return cellData.selectable ? indexPath : nil // cell.selectionStyle = .noneだけだとselect自体はできる 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /TableSample/TableSample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // TableSample 4 | // 5 | // Created by am10 on 2020/03/20. 6 | // Copyright © 2020 am10. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view. 16 | } 17 | } 18 | --------------------------------------------------------------------------------