Skip to content

Commit 9680293

Browse files
committed
Implement ListBindingSectionControllerSwiftWrapper
1 parent a9a3edd commit 9680293

13 files changed

+790
-91
lines changed

Example/Pods/Pods.xcodeproj/project.pbxproj

Lines changed: 88 additions & 88 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Example/RxIGListKit.xcodeproj/project.pbxproj

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
1616
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; };
1717
6F74EBFB4EE28130A371F329 /* Pods_RxIGListKit_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C7B474E1C8814C1B7D62E2A6 /* Pods_RxIGListKit_Tests.framework */; };
18+
841EA9082267264800A817AD /* ReorderableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EA9072267264800A817AD /* ReorderableViewController.swift */; };
19+
841EA90A2267275100A817AD /* ReorderableSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841EA9092267275100A817AD /* ReorderableSectionController.swift */; };
1820
842F4851224FBA2700719FC9 /* FeedSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842F4850224FBA2700719FC9 /* FeedSectionController.swift */; };
1921
84804A8B22492414000E26F4 /* CenterItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84804A8A22492414000E26F4 /* CenterItem.swift */; };
2022
84CE8A142259F29A00B2D86A /* DemosViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE8A132259F29A00B2D86A /* DemosViewController.swift */; };
@@ -35,6 +37,13 @@
3537
84CE8B79225A2E2800B2D86A /* StackedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE8B78225A2E2700B2D86A /* StackedViewController.swift */; };
3638
84CE8B7B225A2E4300B2D86A /* DisplaySectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE8B7A225A2E4200B2D86A /* DisplaySectionController.swift */; };
3739
84CE8B7F225A3B3800B2D86A /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE8B7E225A3B3800B2D86A /* Person.swift */; };
40+
84DEEE1F2261BE95003832BD /* CalendarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEEE1E2261BE95003832BD /* CalendarViewController.swift */; };
41+
84DEEE212261BEB5003832BD /* Month.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEEE202261BEB5003832BD /* Month.swift */; };
42+
84DEEE232261BECF003832BD /* MonthSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEEE222261BECF003832BD /* MonthSectionController.swift */; };
43+
84DEEE262261BF0D003832BD /* DayViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEEE242261BF0D003832BD /* DayViewModel.swift */; };
44+
84DEEE272261BF0D003832BD /* MonthTitleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEEE252261BF0D003832BD /* MonthTitleViewModel.swift */; };
45+
84DEEE2A2261BF33003832BD /* MonthTitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEEE282261BF32003832BD /* MonthTitleCell.swift */; };
46+
84DEEE2B2261BF33003832BD /* CalendarDayCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DEEE292261BF32003832BD /* CalendarDayCell.swift */; };
3847
84F30AD9225596B1008DA454 /* TailLoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F30AD8225596B1008DA454 /* TailLoadingViewController.swift */; };
3948
84F30ADC2255D2E6008DA454 /* SpinSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F30ADB2255D2E6008DA454 /* SpinSection.swift */; };
4049
84F30ADE2255D33D008DA454 /* LabelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F30ADD2255D33D008DA454 /* LabelSectionController.swift */; };
@@ -85,6 +94,8 @@
8594
607FACE51AFB9204008FA782 /* RxIGListKit_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RxIGListKit_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
8695
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
8796
607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
97+
841EA9072267264800A817AD /* ReorderableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReorderableViewController.swift; sourceTree = "<group>"; };
98+
841EA9092267275100A817AD /* ReorderableSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReorderableSectionController.swift; sourceTree = "<group>"; };
8899
842F4850224FBA2700719FC9 /* FeedSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedSectionController.swift; sourceTree = "<group>"; };
89100
84804A8A22492414000E26F4 /* CenterItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CenterItem.swift; sourceTree = "<group>"; };
90101
84CE8A132259F29A00B2D86A /* DemosViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DemosViewController.swift; sourceTree = "<group>"; };
@@ -106,6 +117,13 @@
106117
84CE8B7A225A2E4200B2D86A /* DisplaySectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisplaySectionController.swift; sourceTree = "<group>"; };
107118
84CE8B7E225A3B3800B2D86A /* Person.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Person.swift; sourceTree = "<group>"; };
108119
84D16942D43A4E79C666B015 /* RxIGListKit.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = RxIGListKit.podspec; path = ../RxIGListKit.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
120+
84DEEE1E2261BE95003832BD /* CalendarViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarViewController.swift; sourceTree = "<group>"; };
121+
84DEEE202261BEB5003832BD /* Month.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Month.swift; sourceTree = "<group>"; };
122+
84DEEE222261BECF003832BD /* MonthSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonthSectionController.swift; sourceTree = "<group>"; };
123+
84DEEE242261BF0D003832BD /* DayViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DayViewModel.swift; sourceTree = "<group>"; };
124+
84DEEE252261BF0D003832BD /* MonthTitleViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonthTitleViewModel.swift; sourceTree = "<group>"; };
125+
84DEEE282261BF32003832BD /* MonthTitleCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MonthTitleCell.swift; sourceTree = "<group>"; };
126+
84DEEE292261BF32003832BD /* CalendarDayCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarDayCell.swift; sourceTree = "<group>"; };
109127
84F30AD8225596B1008DA454 /* TailLoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TailLoadingViewController.swift; sourceTree = "<group>"; };
110128
84F30ADB2255D2E6008DA454 /* SpinSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinSection.swift; sourceTree = "<group>"; };
111129
84F30ADD2255D33D008DA454 /* LabelSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelSectionController.swift; sourceTree = "<group>"; };
@@ -269,6 +287,8 @@
269287
84CE8B622259F95600B2D86A /* SingleSectionStoryboardViewController.swift */,
270288
84CE8B72225A23F200B2D86A /* WorkingRangeViewController.swift */,
271289
84CE8B78225A2E2700B2D86A /* StackedViewController.swift */,
290+
84DEEE1E2261BE95003832BD /* CalendarViewController.swift */,
291+
841EA9072267264800A817AD /* ReorderableViewController.swift */,
272292
);
273293
name = ViewControllers;
274294
sourceTree = "<group>";
@@ -287,13 +307,17 @@
287307
84F30AF32256522B008DA454 /* ExpandableSectionController.swift */,
288308
84CE8B5E2259F52500B2D86A /* StoryboardLabelSectionController.swift */,
289309
84CE8B74225A240A00B2D86A /* WorkingRangeSectionController.swift */,
310+
84DEEE222261BECF003832BD /* MonthSectionController.swift */,
311+
841EA9092267275100A817AD /* ReorderableSectionController.swift */,
290312
);
291313
name = SectionControllers;
292314
sourceTree = "<group>";
293315
};
294316
84F30ADF2255D356008DA454 /* Views */ = {
295317
isa = PBXGroup;
296318
children = (
319+
84DEEE292261BF32003832BD /* CalendarDayCell.swift */,
320+
84DEEE282261BF32003832BD /* MonthTitleCell.swift */,
297321
84CE8B6C225A1EF100B2D86A /* FullWidthSelfSizingCell.swift */,
298322
84CE8B76225A24EB00B2D86A /* ImageCell.swift */,
299323
84CE8B6A225A1ECF00B2D86A /* ManuallySelfSizingCell.swift */,
@@ -313,9 +337,12 @@
313337
84F30AE622564CF5008DA454 /* Models */ = {
314338
isa = PBXGroup;
315339
children = (
340+
84DEEE202261BEB5003832BD /* Month.swift */,
316341
84CE8B66225A1E4B00B2D86A /* SelectionModel.swift */,
317342
84CE8B7E225A3B3800B2D86A /* Person.swift */,
318343
84F30AEB22564EB5008DA454 /* User.swift */,
344+
84DEEE242261BF0D003832BD /* DayViewModel.swift */,
345+
84DEEE252261BF0D003832BD /* MonthTitleViewModel.swift */,
319346
);
320347
name = Models;
321348
sourceTree = "<group>";
@@ -506,13 +533,17 @@
506533
isa = PBXSourcesBuildPhase;
507534
buildActionMask = 2147483647;
508535
files = (
536+
84DEEE2B2261BF33003832BD /* CalendarDayCell.swift in Sources */,
509537
84F30B0022579DCE008DA454 /* EmbeddedSectionController.swift in Sources */,
510538
84F30AE3225605AA008DA454 /* SearchViewController.swift in Sources */,
511539
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
512540
84CE8B5F2259F52500B2D86A /* StoryboardLabelSectionController.swift in Sources */,
513541
84F30AF8225652DB008DA454 /* DetailLabelCell.swift in Sources */,
514542
84F30AF622565290008DA454 /* UserSectionController.swift in Sources */,
515543
842F4851224FBA2700719FC9 /* FeedSectionController.swift in Sources */,
544+
841EA9082267264800A817AD /* ReorderableViewController.swift in Sources */,
545+
84DEEE2A2261BF33003832BD /* MonthTitleCell.swift in Sources */,
546+
841EA90A2267275100A817AD /* ReorderableSectionController.swift in Sources */,
516547
84CE8B75225A240A00B2D86A /* WorkingRangeSectionController.swift in Sources */,
517548
84CE8B632259F95600B2D86A /* SingleSectionStoryboardViewController.swift in Sources */,
518549
84F30AFA22579A23008DA454 /* NestedAdapterViewController.swift in Sources */,
@@ -541,11 +572,16 @@
541572
84CE8B6D225A1EF100B2D86A /* FullWidthSelfSizingCell.swift in Sources */,
542573
84F30B022257A609008DA454 /* EmptyViewController.swift in Sources */,
543574
84F30AEC22564EB5008DA454 /* User.swift in Sources */,
575+
84DEEE232261BECF003832BD /* MonthSectionController.swift in Sources */,
544576
84F30B062257A6C7008DA454 /* RemoveCell.swift in Sources */,
577+
84DEEE212261BEB5003832BD /* Month.swift in Sources */,
545578
84CE8B71225A1F1600B2D86A /* NibSelfSizingCell.swift in Sources */,
579+
84DEEE1F2261BE95003832BD /* CalendarViewController.swift in Sources */,
546580
84CE8B5B2259F47B00B2D86A /* StoryboardViewController.swift in Sources */,
581+
84DEEE262261BF0D003832BD /* DayViewModel.swift in Sources */,
547582
84F30ADE2255D33D008DA454 /* LabelSectionController.swift in Sources */,
548583
84F30AF42256522B008DA454 /* ExpandableSectionController.swift in Sources */,
584+
84DEEE272261BF0D003832BD /* MonthTitleViewModel.swift in Sources */,
549585
84F30AEA22564E98008DA454 /* GridSectionController.swift in Sources */,
550586
84F30AFC22579CE7008DA454 /* HorizontalSectionController.swift in Sources */,
551587
);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
Copyright (c) Facebook, Inc. and its affiliates.
3+
4+
The examples provided by Facebook are for non-commercial testing and evaluation
5+
purposes only. Facebook reserves all rights not expressly granted.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
10+
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
11+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
12+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13+
*/
14+
15+
import IGListKit
16+
import UIKit
17+
18+
final class CalendarDayCell: UICollectionViewCell {
19+
20+
lazy fileprivate var label: UILabel = {
21+
let view = UILabel()
22+
view.backgroundColor = .clear
23+
view.textAlignment = .center
24+
view.textColor = .black
25+
view.font = .boldSystemFont(ofSize: 16)
26+
view.layer.borderWidth = 2
27+
view.clipsToBounds = true
28+
self.contentView.addSubview(view)
29+
return view
30+
}()
31+
32+
lazy fileprivate var dotsLabel: UILabel = {
33+
let view = UILabel()
34+
view.backgroundColor = .clear
35+
view.textAlignment = .center
36+
view.textColor = .red
37+
view.font = .boldSystemFont(ofSize: 30)
38+
self.contentView.addSubview(view)
39+
return view
40+
}()
41+
42+
var text: String? {
43+
get {
44+
return label.text
45+
}
46+
set {
47+
label.text = newValue
48+
}
49+
}
50+
51+
var dots: String? {
52+
get {
53+
return dotsLabel.text
54+
}
55+
set {
56+
dotsLabel.text = newValue
57+
}
58+
}
59+
60+
override func layoutSubviews() {
61+
super.layoutSubviews()
62+
let bounds = contentView.bounds
63+
let half = bounds.height / 2
64+
label.frame = bounds
65+
label.layer.cornerRadius = half
66+
dotsLabel.frame = CGRect(x: 0, y: half - 10, width: bounds.width, height: half)
67+
}
68+
69+
}
70+
71+
extension CalendarDayCell: ListBindable {
72+
73+
func bindViewModel(_ viewModel: Any) {
74+
guard let viewModel = viewModel as? DayViewModel else { return }
75+
label.text = viewModel.day.description
76+
77+
label.layer.borderColor = viewModel.today ? UIColor.red.cgColor : UIColor.clear.cgColor
78+
label.backgroundColor = viewModel.selected ? UIColor.red.withAlphaComponent(0.3) : UIColor.clear
79+
80+
var dots = ""
81+
for _ in 0..<viewModel.appointments {
82+
dots += "."
83+
}
84+
dotsLabel.text = dots
85+
}
86+
87+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
Copyright (c) Facebook, Inc. and its affiliates.
3+
4+
The examples provided by Facebook are for non-commercial testing and evaluation
5+
purposes only. Facebook reserves all rights not expressly granted.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
10+
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
11+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
12+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13+
*/
14+
15+
import IGListKit
16+
import UIKit
17+
18+
final class CalendarViewController: UIViewController, ListAdapterDataSource {
19+
20+
lazy var adapter: ListAdapter = {
21+
return ListAdapter(updater: ListAdapterUpdater(), viewController: self)
22+
}()
23+
let collectionView = UICollectionView(
24+
frame: .zero,
25+
collectionViewLayout: ListCollectionViewLayout(stickyHeaders: false, topContentInset: 0, stretchToEdge: false)
26+
)
27+
28+
var months = [Month]()
29+
30+
override func viewDidLoad() {
31+
super.viewDidLoad()
32+
33+
let date = Date()
34+
let currentMonth = Calendar.current.component(.month, from: date)
35+
36+
let month = Month(
37+
name: DateFormatter().monthSymbols[currentMonth - 1],
38+
days: 30,
39+
appointments: [
40+
2: ["Hair"],
41+
4: ["Nails"],
42+
7: ["Doctor appt", "Pick up groceries"],
43+
12: ["Call back the cable company", "Find a babysitter"],
44+
13: ["Dinner at The Smith"],
45+
17: ["Buy running shoes", "Buy a fitbit", "Start running"],
46+
20: ["Call mom"],
47+
21: ["Contribute to IGListKit"],
48+
25: ["Interview"],
49+
26: ["Quit running", "Buy ice cream"]
50+
]
51+
)
52+
months.append(month)
53+
54+
view.addSubview(collectionView)
55+
adapter.collectionView = collectionView
56+
adapter.dataSource = self
57+
}
58+
59+
override func viewDidLayoutSubviews() {
60+
super.viewDidLayoutSubviews()
61+
collectionView.frame = view.bounds
62+
}
63+
64+
// MARK: ListAdapterDataSource
65+
66+
func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
67+
return months
68+
}
69+
70+
func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
71+
return MonthSectionController()
72+
}
73+
74+
func emptyView(for listAdapter: ListAdapter) -> UIView? { return nil }
75+
76+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
Copyright (c) Facebook, Inc. and its affiliates.
3+
4+
The examples provided by Facebook are for non-commercial testing and evaluation
5+
purposes only. Facebook reserves all rights not expressly granted.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
10+
FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
11+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
12+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13+
*/
14+
15+
import Foundation
16+
import IGListKit
17+
18+
final class DayViewModel {
19+
20+
let day: Int
21+
let today: Bool
22+
let selected: Bool
23+
let appointments: Int
24+
25+
init(day: Int, today: Bool, selected: Bool, appointments: Int) {
26+
self.day = day
27+
self.today = today
28+
self.selected = selected
29+
self.appointments = appointments
30+
}
31+
32+
}
33+
34+
extension DayViewModel: ListDiffable {
35+
36+
func diffIdentifier() -> NSObjectProtocol {
37+
return day as NSObjectProtocol
38+
}
39+
40+
func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
41+
if self === object { return true }
42+
guard let object = object as? DayViewModel else { return false }
43+
return today == object.today && selected == object.selected && appointments == object.appointments
44+
}
45+
46+
}

Example/RxIGListKit/DemosViewController.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,11 @@ final class DemosViewController: UIViewController, ListAdapterDataSource {
4545
controllerClass: WorkingRangeViewController.self),
4646
DemoItem(name: "Stacked Section Controllers",
4747
controllerClass: StackedViewController.self),
48-
/*
4948
DemoItem(name: "Calendar (auto diffing)",
5049
controllerClass: CalendarViewController.self),
51-
DemoItem(name: "Dependency Injection",
52-
controllerClass: AnnouncingDepsViewController.self),
5350
DemoItem(name: "Reorder Cells",
5451
controllerClass: ReorderableViewController.self),
52+
/*
5553
DemoItem(name: "Reorder Stacked Section Controllers",
5654
controllerClass: ReorderableStackedViewController.self)*/
5755
]

0 commit comments

Comments
 (0)