├── .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 | |  |  |  |  |
17 |
18 | | Separator Style | Table Style | Grouped Detail | Color Section |
19 | | --- | --- | --- | --- |
20 | |  |  |  |  |
21 |
22 | ## Operations
23 | | Multi Selection | Multi Selection 2| Unselectable Parts | Cell Editing |
24 | | --- | --- | --- | --- |
25 | |  |  |  |  |
26 |
27 |
28 | | Section Index | Context Menu | Swipe |
29 | | --- | --- | --- |
30 | |
|
|
|
31 |
32 | ## Customs
33 | | Single Accordion | Double Accordion |
34 | | --- | --- |
35 | |  |  |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------