From f8b53a5d9b15760c7243e8dad1aa2a041e7ca0fb Mon Sep 17 00:00:00 2001 From: Dylan Shine Date: Thu, 31 May 2018 16:32:10 -0400 Subject: [PATCH] 2.0.0 (#9) * Begin Implementing 2.0.0, Fixing issue related to header size * Update Example to use UIScreen.main.bounds.width to calculate image height * Update Unit tests for OKTableViewSection * Add Estimated Height for OKTableViewSectionComponent * Update Unit test for test_reloadSection_reloadsSectionOfTableView() * Update function declaration for setting heights for OKTableViewRow, update unit tests * Update ReadMe to reflect 2.0.0 changes * Update README for grammatical error --- .../project.pbxproj | 16 +- .../ActionButtonsTableViewRow.swift | 2 +- .../ContentFeedViewController.swift | 13 +- .../PostTableViewSectionFactory.swift | 17 +- .../ImageTableViewRow.swift | 4 +- .../PostTableViewSection.swift | 17 +- ...tTableViewSectionHeaderViewComponent.swift | 30 + Example/Podfile.lock | 4 +- .../OKTableViewLiaison.podspec.json | 4 +- Example/Pods/Manifest.lock | 4 +- Example/Pods/Pods.xcodeproj/project.pbxproj | 366 +++---- .../OKTableViewLiaison/Info.plist | 2 +- .../Tests/OKTableViewLiaison+UnitTests.swift | 949 ++++++++++-------- Example/Tests/OKTableViewRow+UnitTests.swift | 29 +- .../Tests/OKTableViewSection+UnitTests.swift | 216 ++-- ...KTableViewSectionComponent+UnitTests.swift | 131 +++ Example/Tests/TestTableViewRow.swift | 14 +- Example/Tests/TestTableViewSection.swift | 22 - .../Tests/TestTableViewSectionComponent.swift | 12 + OKTableViewLiaison.podspec | 2 +- ... OKTableViewSectionComponentCommand.swift} | 4 +- ...bleViewSectionComponentDisplayOption.swift | 44 + ... => OKTableViewSectionComponentView.swift} | 2 +- ...ectionSupplementaryViewDisplayOption.swift | 34 - .../OKTableViewLiaison+Pagination.swift | 2 +- .../Liaison/OKTableViewLiaison+Row.swift | 1 - .../Liaison/OKTableViewLiaison+Section.swift | 27 +- ...TableViewLiaison+UITableViewDelegate.swift | 18 +- .../Classes/Liaison/OKTableViewLiaison.swift | 6 +- .../OKAnyTableViewRow.swift | 0 .../OKAnyTableViewSectionComponent.swift | 15 + .../Rows/OKPaginationTableViewRow.swift | 4 +- .../Classes/Rows/OKTableViewRow.swift | 15 +- .../Sections/OKAnyTableViewSection.swift | 77 -- .../OKPaginationTableViewSection.swift | 2 +- .../Sections/OKPlainTableViewSection.swift | 16 - .../Classes/Sections/OKTableViewSection.swift | 193 ++-- .../OKTableViewSectionComponent.swift | 112 +++ README.md | 68 +- 39 files changed, 1341 insertions(+), 1153 deletions(-) create mode 100644 Example/OKTableViewLiaison/PostTableViewSectionHeaderViewComponent.swift create mode 100644 Example/Tests/OKTableViewSectionComponent+UnitTests.swift delete mode 100644 Example/Tests/TestTableViewSection.swift create mode 100644 Example/Tests/TestTableViewSectionComponent.swift rename OKTableViewLiaison/Classes/Enums/{OKTableViewSectionCommand.swift => OKTableViewSectionComponentCommand.swift} (69%) create mode 100644 OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentDisplayOption.swift rename OKTableViewLiaison/Classes/Enums/{OKTableViewSectionSupplementaryView.swift => OKTableViewSectionComponentView.swift} (82%) delete mode 100644 OKTableViewLiaison/Classes/Enums/OKTableViewSectionSupplementaryViewDisplayOption.swift rename OKTableViewLiaison/Classes/{Rows => Protocols}/OKAnyTableViewRow.swift (100%) create mode 100644 OKTableViewLiaison/Classes/Protocols/OKAnyTableViewSectionComponent.swift delete mode 100644 OKTableViewLiaison/Classes/Sections/OKAnyTableViewSection.swift delete mode 100644 OKTableViewLiaison/Classes/Sections/OKPlainTableViewSection.swift create mode 100644 OKTableViewLiaison/Classes/Sections/OKTableViewSectionComponent.swift diff --git a/Example/OKTableViewLiaison.xcodeproj/project.pbxproj b/Example/OKTableViewLiaison.xcodeproj/project.pbxproj index 9240d0b..b4e488b 100644 --- a/Example/OKTableViewLiaison.xcodeproj/project.pbxproj +++ b/Example/OKTableViewLiaison.xcodeproj/project.pbxproj @@ -31,10 +31,12 @@ FC6E84EC207EB29000BF0E58 /* PostTableViewSectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = FC6E84E8207EB29000BF0E58 /* PostTableViewSectionHeaderView.xib */; }; FC6E84EE207EB29800BF0E58 /* TextTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC6E84ED207EB29800BF0E58 /* TextTableViewRow.swift */; }; FC6E84F1207EB2B600BF0E58 /* PostTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC6E84F0207EB2B600BF0E58 /* PostTableViewSection.swift */; }; + FCAF2A4F20BEF74000DAD378 /* PostTableViewSectionHeaderViewComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAF2A4E20BEF74000DAD378 /* PostTableViewSectionHeaderViewComponent.swift */; }; + FCAF2A5120BEFD1000DAD378 /* TestTableViewSectionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAF2A5020BEFD1000DAD378 /* TestTableViewSectionComponent.swift */; }; + FCAF2A5320BF094500DAD378 /* OKTableViewSectionComponent+UnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCAF2A5220BF094500DAD378 /* OKTableViewSectionComponent+UnitTests.swift */; }; FCF38FE3207EAEB300E119FB /* TestTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF38FDE207EAEB300E119FB /* TestTableViewRow.swift */; }; FCF38FE4207EAEB300E119FB /* TestTableViewLiaisonPaginationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF38FDF207EAEB300E119FB /* TestTableViewLiaisonPaginationDelegate.swift */; }; FCF38FE5207EAEB300E119FB /* TestTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF38FE0207EAEB300E119FB /* TestTableViewCell.swift */; }; - FCF38FE6207EAEB300E119FB /* TestTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF38FE1207EAEB300E119FB /* TestTableViewSection.swift */; }; FCF38FE7207EAEB300E119FB /* UITableView+SwizzleTesting.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF38FE2207EAEB300E119FB /* UITableView+SwizzleTesting.swift */; }; FCF38FEB207EAF5500E119FB /* OKTableViewSection+UnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF38FE8207EAF5400E119FB /* OKTableViewSection+UnitTests.swift */; }; FCF38FEC207EAF5500E119FB /* OKTableViewRow+UnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCF38FE9207EAF5400E119FB /* OKTableViewRow+UnitTests.swift */; }; @@ -87,10 +89,12 @@ FC6E84E8207EB29000BF0E58 /* PostTableViewSectionHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PostTableViewSectionHeaderView.xib; sourceTree = ""; }; FC6E84ED207EB29800BF0E58 /* TextTableViewRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextTableViewRow.swift; sourceTree = ""; }; FC6E84F0207EB2B600BF0E58 /* PostTableViewSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostTableViewSection.swift; sourceTree = ""; }; + FCAF2A4E20BEF74000DAD378 /* PostTableViewSectionHeaderViewComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTableViewSectionHeaderViewComponent.swift; sourceTree = ""; }; + FCAF2A5020BEFD1000DAD378 /* TestTableViewSectionComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestTableViewSectionComponent.swift; sourceTree = ""; }; + FCAF2A5220BF094500DAD378 /* OKTableViewSectionComponent+UnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OKTableViewSectionComponent+UnitTests.swift"; sourceTree = ""; }; FCF38FDE207EAEB300E119FB /* TestTableViewRow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestTableViewRow.swift; sourceTree = ""; }; FCF38FDF207EAEB300E119FB /* TestTableViewLiaisonPaginationDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestTableViewLiaisonPaginationDelegate.swift; sourceTree = ""; }; FCF38FE0207EAEB300E119FB /* TestTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestTableViewCell.swift; sourceTree = ""; }; - FCF38FE1207EAEB300E119FB /* TestTableViewSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestTableViewSection.swift; sourceTree = ""; }; FCF38FE2207EAEB300E119FB /* UITableView+SwizzleTesting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+SwizzleTesting.swift"; sourceTree = ""; }; FCF38FE8207EAF5400E119FB /* OKTableViewSection+UnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OKTableViewSection+UnitTests.swift"; sourceTree = ""; }; FCF38FE9207EAF5400E119FB /* OKTableViewRow+UnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OKTableViewRow+UnitTests.swift"; sourceTree = ""; }; @@ -172,6 +176,7 @@ FCF38FEA207EAF5500E119FB /* OKTableViewLiaison+UnitTests.swift */, FCF38FE9207EAF5400E119FB /* OKTableViewRow+UnitTests.swift */, FCF38FE8207EAF5400E119FB /* OKTableViewSection+UnitTests.swift */, + FCAF2A5220BF094500DAD378 /* OKTableViewSectionComponent+UnitTests.swift */, FCF38FDD207EAE9900E119FB /* Fixtures */, 607FACE91AFB9204008FA782 /* Supporting Files */, ); @@ -271,6 +276,7 @@ isa = PBXGroup; children = ( FC6E84F0207EB2B600BF0E58 /* PostTableViewSection.swift */, + FCAF2A4E20BEF74000DAD378 /* PostTableViewSectionHeaderViewComponent.swift */, ); name = Sections; sourceTree = ""; @@ -281,7 +287,7 @@ FCF38FE0207EAEB300E119FB /* TestTableViewCell.swift */, FCF38FDF207EAEB300E119FB /* TestTableViewLiaisonPaginationDelegate.swift */, FCF38FDE207EAEB300E119FB /* TestTableViewRow.swift */, - FCF38FE1207EAEB300E119FB /* TestTableViewSection.swift */, + FCAF2A5020BEFD1000DAD378 /* TestTableViewSectionComponent.swift */, FCF38FE2207EAEB300E119FB /* UITableView+SwizzleTesting.swift */, ); name = Fixtures; @@ -479,6 +485,7 @@ FC6E84E9207EB29000BF0E58 /* PostTableViewSectionHeaderView.swift in Sources */, FC6E84EE207EB29800BF0E58 /* TextTableViewRow.swift in Sources */, FC6E84F1207EB2B600BF0E58 /* PostTableViewSection.swift in Sources */, + FCAF2A4F20BEF74000DAD378 /* PostTableViewSectionHeaderViewComponent.swift in Sources */, FC4A048920AB3B3700B692EC /* ImageTableViewRow.swift in Sources */, FC6E84E4207EB28100BF0E58 /* ImageTableViewCell.swift in Sources */, FC6E84E2207EB28100BF0E58 /* ActionButtonsTableViewCell.swift in Sources */, @@ -497,14 +504,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FCAF2A5120BEFD1000DAD378 /* TestTableViewSectionComponent.swift in Sources */, FCF38FE3207EAEB300E119FB /* TestTableViewRow.swift in Sources */, FCF38FE5207EAEB300E119FB /* TestTableViewCell.swift in Sources */, FCF38FE4207EAEB300E119FB /* TestTableViewLiaisonPaginationDelegate.swift in Sources */, - FCF38FE6207EAEB300E119FB /* TestTableViewSection.swift in Sources */, FCF38FEB207EAF5500E119FB /* OKTableViewSection+UnitTests.swift in Sources */, FCF38FE7207EAEB300E119FB /* UITableView+SwizzleTesting.swift in Sources */, FCF38FED207EAF5500E119FB /* OKTableViewLiaison+UnitTests.swift in Sources */, FCF38FEC207EAF5500E119FB /* OKTableViewRow+UnitTests.swift in Sources */, + FCAF2A5320BF094500DAD378 /* OKTableViewSectionComponent+UnitTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/OKTableViewLiaison/ActionButtonsTableViewRow.swift b/Example/OKTableViewLiaison/ActionButtonsTableViewRow.swift index cc4c846..1e1fb09 100644 --- a/Example/OKTableViewLiaison/ActionButtonsTableViewRow.swift +++ b/Example/OKTableViewLiaison/ActionButtonsTableViewRow.swift @@ -14,7 +14,7 @@ final class ActionButtonsTableViewRow: OKTableViewRow PostTableViewSection { - return PostTableViewSectionFactory.section(for: post, width: tableView.frame.width) + .map(PostTableViewSectionFactory.section(for:)) } override func viewDidLoad() { @@ -28,10 +24,9 @@ final class ContentFeedViewController: UIViewController { refreshControl.addTarget(self, action: #selector(refreshSections), for: .valueChanged) tableView.addSubview(refreshControl) - + liaison.paginationDelegate = self liaison.liaise(tableView: tableView) - liaison.append(sections: initialSections) } @@ -55,7 +50,7 @@ extension ContentFeedViewController: OKTableViewLiaisonPaginationDelegate { liaison.scroll(to: indexPath) let sections = Post.paginatedPosts() - .map(section(for:)) + .map(PostTableViewSectionFactory.section(for:)) DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.liaison.append(sections: sections) diff --git a/Example/OKTableViewLiaison/Factories/PostTableViewSectionFactory.swift b/Example/OKTableViewLiaison/Factories/PostTableViewSectionFactory.swift index 8f6eb1d..c5bc4d5 100644 --- a/Example/OKTableViewLiaison/Factories/PostTableViewSectionFactory.swift +++ b/Example/OKTableViewLiaison/Factories/PostTableViewSectionFactory.swift @@ -11,14 +11,15 @@ import OKTableViewLiaison enum PostTableViewSectionFactory { - static func section(for post: Post, width: CGFloat) -> PostTableViewSection { - let rows: [OKAnyTableViewRow] = [ImageTableViewRow(image: post.content, - width: width), - ActionButtonsTableViewRow(), - TextTableViewRowFactory.likesRow(numberOfLikes: post.numberOfLikes), - TextTableViewRowFactory.captionRow(user: post.user.username, caption: post.caption), - TextTableViewRowFactory.commentRow(commentCount: post.numberOfComments), - TextTableViewRowFactory.timeRow(numberOfSeconds: post.timePosted)] + static func section(for post: Post) -> PostTableViewSection { + let rows: [OKAnyTableViewRow] = [ + ImageTableViewRow(image: post.content), + ActionButtonsTableViewRow(), + TextTableViewRowFactory.likesRow(numberOfLikes: post.numberOfLikes), + TextTableViewRowFactory.captionRow(user: post.user.username, caption: post.caption), + TextTableViewRowFactory.commentRow(commentCount: post.numberOfComments), + TextTableViewRowFactory.timeRow(numberOfSeconds: post.timePosted) + ] return PostTableViewSection(user: post.user, rows: rows) } diff --git a/Example/OKTableViewLiaison/ImageTableViewRow.swift b/Example/OKTableViewLiaison/ImageTableViewRow.swift index 0b14f39..dc2404b 100644 --- a/Example/OKTableViewLiaison/ImageTableViewRow.swift +++ b/Example/OKTableViewLiaison/ImageTableViewRow.swift @@ -11,13 +11,13 @@ import OKTableViewLiaison final class ImageTableViewRow: OKTableViewRow { - init(image: UIImage, width: CGFloat) { + init(image: UIImage) { super.init(image, registrationType: ImageTableViewRow.defaultNibRegistrationType) set(height: .height) { image -> CGFloat in let ratio = image.size.width / image.size.height - return width / ratio + return UIScreen.main.bounds.width / ratio } set(command: .configuration) { cell, image, indexPath in diff --git a/Example/OKTableViewLiaison/PostTableViewSection.swift b/Example/OKTableViewLiaison/PostTableViewSection.swift index abf5ee1..5074feb 100644 --- a/Example/OKTableViewLiaison/PostTableViewSection.swift +++ b/Example/OKTableViewLiaison/PostTableViewSection.swift @@ -9,23 +9,10 @@ import UIKit import OKTableViewLiaison -final class PostTableViewSection: OKTableViewSection { +final class PostTableViewSection: OKTableViewSection { init(user: User, rows: [OKAnyTableViewRow] = []) { - - super.init(user, rows: rows, supplementaryViewDisplay: .header(registrationType: PostTableViewSection.defaultHeaderNibRegistrationType)) - - setHeight(for: .header, value: 70) - - setHeader(command: .configuration) { header, user, section in - header.imageView.image = user.avatar - header.imageView.layer.borderColor = UIColor.gray.cgColor - header.imageView.layer.borderWidth = 1 - - header.titleLabel.text = user.username - header.titleLabel.font = .systemFont(ofSize: 13, weight: .medium) - header.titleLabel.textColor = .black - } + super.init(rows: rows, componentDisplayOption: .header(component: PostTableViewSectionHeaderViewComponent(user: user))) } } diff --git a/Example/OKTableViewLiaison/PostTableViewSectionHeaderViewComponent.swift b/Example/OKTableViewLiaison/PostTableViewSectionHeaderViewComponent.swift new file mode 100644 index 0000000..6f09fba --- /dev/null +++ b/Example/OKTableViewLiaison/PostTableViewSectionHeaderViewComponent.swift @@ -0,0 +1,30 @@ +// +// PostTableViewSectionHeaderViewComponent.swift +// OKTableViewLiaison_Example +// +// Created by Dylan Shine on 5/30/18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit +import OKTableViewLiaison + +final class PostTableViewSectionHeaderViewComponent: OKTableViewSectionComponent { + + public init(user: User) { + + super.init(user, registrationType: PostTableViewSectionHeaderViewComponent.defaultNibRegistrationType) + + set(height: .height, 70) + + set(command: .configuration) { view, user, section in + view.imageView.image = user.avatar + view.imageView.layer.borderColor = UIColor.gray.cgColor + view.imageView.layer.borderWidth = 1 + + view.titleLabel.text = user.username + view.titleLabel.font = .systemFont(ofSize: 13, weight: .medium) + view.titleLabel.textColor = .black + } + } +} diff --git a/Example/Podfile.lock b/Example/Podfile.lock index aeaccb3..1360a28 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - OKTableViewLiaison (1.4.0) + - OKTableViewLiaison (2.0.0) DEPENDENCIES: - OKTableViewLiaison (from `../`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - OKTableViewLiaison: 1f5b71721c98b4a3141a0a32d0c73296c2c21e61 + OKTableViewLiaison: 8eeb53b4d8b9bf21d5b0c1aed856923c3e1d82cb PODFILE CHECKSUM: 9150dd9310401db4896273bd584c73be0d2714d2 diff --git a/Example/Pods/Local Podspecs/OKTableViewLiaison.podspec.json b/Example/Pods/Local Podspecs/OKTableViewLiaison.podspec.json index 23e13d0..d6360ae 100644 --- a/Example/Pods/Local Podspecs/OKTableViewLiaison.podspec.json +++ b/Example/Pods/Local Podspecs/OKTableViewLiaison.podspec.json @@ -1,6 +1,6 @@ { "name": "OKTableViewLiaison", - "version": "1.4.0", + "version": "2.0.0", "license": { "type": "MIT", "file": "LICENSE" @@ -13,7 +13,7 @@ }, "source": { "git": "https://github.com/okcupid/OKTableViewLiaison.git", - "tag": "1.4.0" + "tag": "2.0.0" }, "platforms": { "ios": "9.0" diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index aeaccb3..1360a28 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -1,5 +1,5 @@ PODS: - - OKTableViewLiaison (1.4.0) + - OKTableViewLiaison (2.0.0) DEPENDENCIES: - OKTableViewLiaison (from `../`) @@ -9,7 +9,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - OKTableViewLiaison: 1f5b71721c98b4a3141a0a32d0c73296c2c21e61 + OKTableViewLiaison: 8eeb53b4d8b9bf21d5b0c1aed856923c3e1d82cb PODFILE CHECKSUM: 9150dd9310401db4896273bd584c73be0d2714d2 diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 8b2995c..eeb4fbc 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,41 +7,41 @@ objects = { /* Begin PBXBuildFile section */ - 00C1794809B69E5C6CE2DB925EBF5B57 /* OKTableViewSectionSupplementaryViewDisplayOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F42F59DC941A4492C4D3FBE7B58AB22 /* OKTableViewSectionSupplementaryViewDisplayOption.swift */; }; - 07C4E0DF1C3513AEAEB63A4B48BC6EC6 /* OKTableViewLiaison+Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CE0AE87982C419BBA44EC3EBDD56FA7 /* OKTableViewLiaison+Pagination.swift */; }; - 172CB4D5799E74DAED12C92B7F38CC8C /* Array+SafeAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 037631C73E9A60A953770F86E9693B64 /* Array+SafeAccess.swift */; }; - 1E45D507FC088AFA6E1810312DB40901 /* OKTableViewSectionSupplementaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0411C11D2E1B0716E5F2B137B05DB0 /* OKTableViewSectionSupplementaryView.swift */; }; + 01B54344300D7209F67A346D72064BD6 /* Array+IndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8E751CC2569A8D2BC0336671632CA21 /* Array+IndexPath.swift */; }; + 17EAAFFC9F2B142134A3D4B5F97C1A12 /* OKTableViewLiaisonPaginationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013D6D701942D44FA434B4AE746BE9D9 /* OKTableViewLiaisonPaginationDelegate.swift */; }; + 1B00905F83B948E1B26FE9047DAF6D26 /* OKTableViewRowCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DD48FC81602C983B892C6105D85366A /* OKTableViewRowCommand.swift */; }; + 1B7A22EEB31348856974888B7261ADEA /* OKTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D03753A24C94AA1E5AB5BF7661849C16 /* OKTableViewSection.swift */; }; 2690043E759F0AA8404D647D1134EC90 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; - 2B4915F654A05B54762062B0F762612B /* OKPaginationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D7F51674FAECB8FF355ADC242260F3 /* OKPaginationTableViewCell.swift */; }; - 342C9074ECD4F4CCFE5EBD664E28C905 /* OKTableViewLiaison.swift in Sources */ = {isa = PBXBuildFile; fileRef = D032827B83566188A842E38273730B94 /* OKTableViewLiaison.swift */; }; - 450526DEC50E17F514294A9FC3456FDA /* OKTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4D0E0A26A60968B02913145CA9A381 /* OKTableViewSection.swift */; }; - 4B12D9973AD3ADE81D6934707CCB2AD2 /* OKAnyTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80C2B35916E39C0662EF8D8A772B7C06 /* OKAnyTableViewSection.swift */; }; - 550F3DB25F743BF3E664EC003A88DE8E /* OKTableViewLiaison+UITableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099CA19DBFA45582410DC89895986F19 /* OKTableViewLiaison+UITableViewDataSource.swift */; }; + 456A6EDD76A7CC38F40E8D204F46DF7E /* OKTableViewPrefetchCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CB40B7482723F2F846EEF4FAEBD087E /* OKTableViewPrefetchCommand.swift */; }; + 486D2ABC38A9F7439590D92C7F5C8F4C /* OKTableViewLiaison+UITableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8D005AF17B59B138EBACDC6A496D9F9 /* OKTableViewLiaison+UITableViewDataSource.swift */; }; + 51E323F44C8B7DFEDE445BEEB04582DB /* OKPaginationTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D84F52E8BB5649FE3CE2815A3B29BEAA /* OKPaginationTableViewSection.swift */; }; 5667A496A77DF9C309AE0370E9A56050 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; - 56AD0B26B10F304BAB5D38AFB9A5476A /* OKTableViewRowCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60DE387B941752AF876895200DB0D21 /* OKTableViewRowCommand.swift */; }; - 5F27C078CB3FD9477A1A22C79D8A8D9C /* OKTableViewLiaison-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = EAB3CDB6D6FD4F6C17A3C2E87927FDC7 /* OKTableViewLiaison-dummy.m */; }; - 692B7897C7A6CD041A516B4C06C53862 /* OKTableViewRegistrationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5203669EC3B9D82AE5155EEAFE4BA8B /* OKTableViewRegistrationType.swift */; }; - 717F9AFA0AB8112B84FB06DDE6757F9C /* Array+IndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B22B766797D9465F7B40AEF4EC3269F9 /* Array+IndexPath.swift */; }; - 77677C4911A09196B1032D992C9D527C /* OKTableViewLiaison+Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CD1BB89940140E89966CC0E35C1C5EB /* OKTableViewLiaison+Section.swift */; }; + 5867716CE10B28692659EA3A640BFF56 /* OKAnyTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21C29E2CB2E396FC4972CF5FA36A17E1 /* OKAnyTableViewRow.swift */; }; + 587094A5DF0C25F375029B0848784CA2 /* OKTableViewSectionComponentCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C7BBAAC0CF8CF9ED383C04CF718E8F /* OKTableViewSectionComponentCommand.swift */; }; + 5D6BA4CC383BC7640B29AC16EFE24773 /* OKTableViewSectionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45107EDC7FCB13DCE30CF0C9F0F3DBF2 /* OKTableViewSectionComponent.swift */; }; + 6A30FB635EEFF4A6F2B07E80CAFF5717 /* OKTableViewLiaison+Row.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9213C72D0E30081D1918FF2F1A362FF /* OKTableViewLiaison+Row.swift */; }; + 6D41673076525ACB78F8B460D9CC15F2 /* OKTableViewRegistrationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF7DE0837CB8ED8E07DA73C08E2FD087 /* OKTableViewRegistrationType.swift */; }; + 71F6D85984412B1720E2B87AB600DAA4 /* OKTableViewLiaison+Pagination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B090087810D716A2F940B1CD632DA7 /* OKTableViewLiaison+Pagination.swift */; }; + 72216124DA7B84721DC09883D71E9FE8 /* OKPaginationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70A303DCE5E0C23A0CC4747C3549AC14 /* OKPaginationTableViewCell.swift */; }; + 79986A0365644909FE904C218033779B /* OKTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72653247738D80D558234B3DB4CA408D /* OKTableViewRow.swift */; }; 7F80E3F25EF4FD5217A178520F6B08B6 /* Pods-OKTableViewLiaison_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 762AA2BDE76E494AD5924915EC323DA0 /* Pods-OKTableViewLiaison_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 84798FCE9D7180F2B1CA55AFF6E16BF5 /* OKTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ECF408137DF8A574EC82BB5D00D176F /* OKTableViewRow.swift */; }; - 84E5393D8109BC2155627E498B928132 /* OKPaginationTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACAF0955E26848CD160A1705AE2B8EB2 /* OKPaginationTableViewRow.swift */; }; - 889D17CD2B263127DEB060705104374B /* OKPlainTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9D47A1B4B3164B5704438DE75D0431E /* OKPlainTableViewSection.swift */; }; - 925042F981E5E9087B475A999D1FB8F7 /* OKTableViewLiaison+Row.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED1A0F45195B08155B4D20A250492CB /* OKTableViewLiaison+Row.swift */; }; - 981047491BBFF1169F9B42C9E5EBA2B3 /* OKTableViewSectionCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95FECFC4B44858E00EE1E218331F2683 /* OKTableViewSectionCommand.swift */; }; + 90C0BF26F3D417BFCF0A1F11B37B98B6 /* OKTableViewLiaison-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 74E6A8AA40DC88B780CEC79F7A2BBB51 /* OKTableViewLiaison-dummy.m */; }; 9EB40B48915DB68F53817317A8C56D20 /* Pods-OKTableViewLiaison_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C62B2624620079E4726DA81A37918337 /* Pods-OKTableViewLiaison_Example-dummy.m */; }; A2C71CC0D87F8F291307F07647C047E6 /* Pods-OKTableViewLiaison_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 801F26815AE27E4B0668D17C65A2B382 /* Pods-OKTableViewLiaison_Tests-dummy.m */; }; + A6F92D029A51784FFEA6202BC67D59BC /* OKTableViewLiaison+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DFC84727F0EC49B641A8153A0210F9 /* OKTableViewLiaison+UITableViewDelegate.swift */; }; + A7E9DE850A028EAA29C0318077711DBD /* OKAnyTableViewSectionComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F66785443E1C3F11B91C88AC269D6CC /* OKAnyTableViewSectionComponent.swift */; }; + AA60C1B10768E526B0363F9425B67053 /* OKTableViewLiaison.swift in Sources */ = {isa = PBXBuildFile; fileRef = 352CADF3A564673CB859EAA37BF3BB1F /* OKTableViewLiaison.swift */; }; + AD5DACB2354F1B1A530CC9ED9FE6891C /* OKPaginationTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B411223C9A0AE4D3EC8FFCACB4F421D /* OKPaginationTableViewRow.swift */; }; B2BA3096E8E03F4271ED10E482798110 /* Pods-OKTableViewLiaison_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 088B97E35E3B3CEE3147D5CD3A737B7F /* Pods-OKTableViewLiaison_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BB5B7B127432FF5C6F1E2DAA9D65282B /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A04359AAF2C470863111D085512326 /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift */; }; - C7C7845AFD4C2010A691AC2AA7563CBC /* OKTableViewHeightType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E886AB44F18BCD5D0480D4E3791C8E /* OKTableViewHeightType.swift */; }; - C94F97E6C757FB36B431891313F642E5 /* OKTableViewLiaison+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C729C187F3CA11C29E24C66E72848E9 /* OKTableViewLiaison+UITableViewDelegate.swift */; }; - D22A79AB0A7A5A69BBF173E554FD04AF /* OKTableViewLiaisonPaginationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53A0419ABA8E3A4346F9426994A29B23 /* OKTableViewLiaisonPaginationDelegate.swift */; }; - DB13F401040FB5AA4D838F7F8099344A /* OKAnyTableViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE04C8A84ADE104739D24B0278B12D6B /* OKAnyTableViewRow.swift */; }; + BE81A2671D1B8FCE23D97FD9CD7B86BE /* Array+SafeAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988110A2FA354EDD69ABC921690EE2CE /* Array+SafeAccess.swift */; }; + C1378C7FCA09FC7448021927A7D51DBD /* OKTableViewHeightType.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA787EDE0A9AF27B47871C3853B27593 /* OKTableViewHeightType.swift */; }; + C92D28FA9C922F1859ECEEB0C933C8F5 /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9440DB5089AF1C2D17A5723BB15C9CC /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift */; }; + CD1204377D1BF4EA8EB74B9FE83F4189 /* OKTableViewSectionComponentDisplayOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A395DE3DC673BE7CEE411D36B8581C /* OKTableViewSectionComponentDisplayOption.swift */; }; + DB3EC78D8080753420E053872B14A9E1 /* UIView+Nib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5700639C38BA4BFC0F05C48BA4B08B60 /* UIView+Nib.swift */; }; E1F1E36A44359EE4A76C81118272C432 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; - E9FC8C14C51D53C4DA0DE9E072692A55 /* OKTableViewPrefetchCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4F9A2A2032094B1321AD395314982C /* OKTableViewPrefetchCommand.swift */; }; - F1558CD0ADAC58853C5F6E930557AC7B /* UIView+Nib.swift in Sources */ = {isa = PBXBuildFile; fileRef = D31B0656D51D766ECCB859E094DA4853 /* UIView+Nib.swift */; }; - F6448E46B801A2CE3047497C99FCFAFE /* OKTableViewLiaison-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B959F3D1E3BA32627850E3D928DA5574 /* OKTableViewLiaison-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - FACD24B6FF61E015B7D59C9E48CD64DC /* OKPaginationTableViewSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4728DEDAE4C2E8312CF55E760A01C6BC /* OKPaginationTableViewSection.swift */; }; + F38E71DD738F73B353F64E0FE99924C8 /* OKTableViewSectionComponentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E46A4CABE1813D4987E1BD6FB6863A3 /* OKTableViewSectionComponentView.swift */; }; + F6448E46B801A2CE3047497C99FCFAFE /* OKTableViewLiaison-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6426368AA68672B5AF364931C3AC9CD0 /* OKTableViewLiaison-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F6E44F69CDEA987984C000254C37C772 /* OKTableViewLiaison+Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86A691913FF7D14D0212D92EAB32BE10 /* OKTableViewLiaison+Section.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -62,66 +62,66 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 037631C73E9A60A953770F86E9693B64 /* Array+SafeAccess.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "Array+SafeAccess.swift"; sourceTree = ""; }; + 013D6D701942D44FA434B4AE746BE9D9 /* OKTableViewLiaisonPaginationDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewLiaisonPaginationDelegate.swift; sourceTree = ""; }; + 02B090087810D716A2F940B1CD632DA7 /* OKTableViewLiaison+Pagination.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+Pagination.swift"; sourceTree = ""; }; 088B97E35E3B3CEE3147D5CD3A737B7F /* Pods-OKTableViewLiaison_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-OKTableViewLiaison_Example-umbrella.h"; sourceTree = ""; }; - 099CA19DBFA45582410DC89895986F19 /* OKTableViewLiaison+UITableViewDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+UITableViewDataSource.swift"; sourceTree = ""; }; + 0CB40B7482723F2F846EEF4FAEBD087E /* OKTableViewPrefetchCommand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewPrefetchCommand.swift; sourceTree = ""; }; + 0F66785443E1C3F11B91C88AC269D6CC /* OKAnyTableViewSectionComponent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKAnyTableViewSectionComponent.swift; sourceTree = ""; }; 1A1A0AD1D8002495FEFE6B9A5371938C /* Pods-OKTableViewLiaison_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OKTableViewLiaison_Example-acknowledgements.plist"; sourceTree = ""; }; - 1CE0AE87982C419BBA44EC3EBDD56FA7 /* OKTableViewLiaison+Pagination.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+Pagination.swift"; sourceTree = ""; }; + 1B411223C9A0AE4D3EC8FFCACB4F421D /* OKPaginationTableViewRow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKPaginationTableViewRow.swift; sourceTree = ""; }; 1F10628F8BDFD9C06C61D3BBC8665549 /* Pods-OKTableViewLiaison_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-OKTableViewLiaison_Tests-frameworks.sh"; sourceTree = ""; }; - 31A04359AAF2C470863111D085512326 /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+UITableViewDataSourcePrefetching.swift"; sourceTree = ""; }; - 3C729C187F3CA11C29E24C66E72848E9 /* OKTableViewLiaison+UITableViewDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+UITableViewDelegate.swift"; sourceTree = ""; }; - 3C85172F41F9AB3481A4D1B7049B1BE9 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; + 21C29E2CB2E396FC4972CF5FA36A17E1 /* OKAnyTableViewRow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKAnyTableViewRow.swift; sourceTree = ""; }; + 2C8203F23D3CD377E39EE29F3551D273 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; + 352CADF3A564673CB859EAA37BF3BB1F /* OKTableViewLiaison.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewLiaison.swift; sourceTree = ""; }; + 3B928CDF2EE635B54E942CF0A14F9AD6 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; 3E9F3A5DA8E689E0AE1804DE852E0317 /* Pods-OKTableViewLiaison_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-OKTableViewLiaison_Example-resources.sh"; sourceTree = ""; }; - 3F42F59DC941A4492C4D3FBE7B58AB22 /* OKTableViewSectionSupplementaryViewDisplayOption.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSectionSupplementaryViewDisplayOption.swift; sourceTree = ""; }; 41813B4632FD43AB08EE6A4D4A941D73 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 43A395DE3DC673BE7CEE411D36B8581C /* OKTableViewSectionComponentDisplayOption.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSectionComponentDisplayOption.swift; sourceTree = ""; }; 43E9A556E8D1B9A5C81F2663EE4381C4 /* OKTableViewLiaison.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = OKTableViewLiaison.framework; path = OKTableViewLiaison.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4728DEDAE4C2E8312CF55E760A01C6BC /* OKPaginationTableViewSection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKPaginationTableViewSection.swift; sourceTree = ""; }; - 53A0419ABA8E3A4346F9426994A29B23 /* OKTableViewLiaisonPaginationDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewLiaisonPaginationDelegate.swift; sourceTree = ""; }; + 45107EDC7FCB13DCE30CF0C9F0F3DBF2 /* OKTableViewSectionComponent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSectionComponent.swift; sourceTree = ""; }; + 5700639C38BA4BFC0F05C48BA4B08B60 /* UIView+Nib.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIView+Nib.swift"; sourceTree = ""; }; 5C9D84FD35DD3C1FE8DB84E3D7ECE6D2 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 5D5704BE7155FE7B15862A1BDC2E7A25 /* OKTableViewLiaison-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OKTableViewLiaison-prefix.pch"; sourceTree = ""; }; - 5F29FA4654BA183B137A1937CA25E62C /* OKTableViewLiaison.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; path = OKTableViewLiaison.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 6426368AA68672B5AF364931C3AC9CD0 /* OKTableViewLiaison-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OKTableViewLiaison-umbrella.h"; sourceTree = ""; }; + 652E4A441274D252B322C363D00FA92F /* OKTableViewLiaison-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OKTableViewLiaison-prefix.pch"; sourceTree = ""; }; 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 6CD1BB89940140E89966CC0E35C1C5EB /* OKTableViewLiaison+Section.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+Section.swift"; sourceTree = ""; }; 6E8ED08629BCB0FB182AC38A29BD7AF8 /* Pods-OKTableViewLiaison_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-OKTableViewLiaison_Example.modulemap"; sourceTree = ""; }; + 70A303DCE5E0C23A0CC4747C3549AC14 /* OKPaginationTableViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKPaginationTableViewCell.swift; sourceTree = ""; }; + 72653247738D80D558234B3DB4CA408D /* OKTableViewRow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewRow.swift; sourceTree = ""; }; + 74E6A8AA40DC88B780CEC79F7A2BBB51 /* OKTableViewLiaison-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "OKTableViewLiaison-dummy.m"; sourceTree = ""; }; 762AA2BDE76E494AD5924915EC323DA0 /* Pods-OKTableViewLiaison_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-OKTableViewLiaison_Tests-umbrella.h"; sourceTree = ""; }; + 7AF03249C83F365BD31EA59EA2DE5EEF /* OKTableViewLiaison.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = OKTableViewLiaison.xcconfig; sourceTree = ""; }; + 7DD48FC81602C983B892C6105D85366A /* OKTableViewRowCommand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewRowCommand.swift; sourceTree = ""; }; + 7E46A4CABE1813D4987E1BD6FB6863A3 /* OKTableViewSectionComponentView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSectionComponentView.swift; sourceTree = ""; }; 801F26815AE27E4B0668D17C65A2B382 /* Pods-OKTableViewLiaison_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-OKTableViewLiaison_Tests-dummy.m"; sourceTree = ""; }; - 80C2B35916E39C0662EF8D8A772B7C06 /* OKAnyTableViewSection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKAnyTableViewSection.swift; sourceTree = ""; }; + 86A691913FF7D14D0212D92EAB32BE10 /* OKTableViewLiaison+Section.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+Section.swift"; sourceTree = ""; }; 8AF22AEBD5D95C44895FD06C7B99E7C8 /* Pods-OKTableViewLiaison_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OKTableViewLiaison_Example.debug.xcconfig"; sourceTree = ""; }; 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 95FECFC4B44858E00EE1E218331F2683 /* OKTableViewSectionCommand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSectionCommand.swift; sourceTree = ""; }; - 9ECF408137DF8A574EC82BB5D00D176F /* OKTableViewRow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewRow.swift; sourceTree = ""; }; + 988110A2FA354EDD69ABC921690EE2CE /* Array+SafeAccess.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "Array+SafeAccess.swift"; sourceTree = ""; }; + 9E902CF4DDF71E06D78B2A3D88A0BD07 /* OKTableViewLiaison.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; path = OKTableViewLiaison.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; A15F680637C1FD4EBAD21EB78390715D /* Pods-OKTableViewLiaison_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-OKTableViewLiaison_Example-frameworks.sh"; sourceTree = ""; }; - A61CB4FE2C120B6B8646C28295DEB824 /* OKTableViewLiaison.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = OKTableViewLiaison.modulemap; sourceTree = ""; }; - ACAF0955E26848CD160A1705AE2B8EB2 /* OKPaginationTableViewRow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKPaginationTableViewRow.swift; sourceTree = ""; }; - AED1A0F45195B08155B4D20A250492CB /* OKTableViewLiaison+Row.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+Row.swift"; sourceTree = ""; }; B0071D3D037ED2C84039DFB2154BCA9B /* Pods-OKTableViewLiaison_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-OKTableViewLiaison_Tests.modulemap"; sourceTree = ""; }; - B22B766797D9465F7B40AEF4EC3269F9 /* Array+IndexPath.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "Array+IndexPath.swift"; sourceTree = ""; }; - B2E429530E4E06EBF0A166917C3AC0BD /* OKTableViewLiaison.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = OKTableViewLiaison.xcconfig; sourceTree = ""; }; - B60DE387B941752AF876895200DB0D21 /* OKTableViewRowCommand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewRowCommand.swift; sourceTree = ""; }; - B6E886AB44F18BCD5D0480D4E3791C8E /* OKTableViewHeightType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewHeightType.swift; sourceTree = ""; }; + B3C7BBAAC0CF8CF9ED383C04CF718E8F /* OKTableViewSectionComponentCommand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSectionComponentCommand.swift; sourceTree = ""; }; B729AAD39384357F40390D66DD96EBD7 /* Pods-OKTableViewLiaison_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OKTableViewLiaison_Tests.release.xcconfig"; sourceTree = ""; }; - B959F3D1E3BA32627850E3D928DA5574 /* OKTableViewLiaison-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "OKTableViewLiaison-umbrella.h"; sourceTree = ""; }; C62B2624620079E4726DA81A37918337 /* Pods-OKTableViewLiaison_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-OKTableViewLiaison_Example-dummy.m"; sourceTree = ""; }; C6D58EF5E88A5DB3AD50DCD490ED5F8E /* Pods-OKTableViewLiaison_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-OKTableViewLiaison_Tests-acknowledgements.plist"; sourceTree = ""; }; - C9D47A1B4B3164B5704438DE75D0431E /* OKPlainTableViewSection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKPlainTableViewSection.swift; sourceTree = ""; }; - CBFD6048103B6BA821A20F3FABB29C49 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D032827B83566188A842E38273730B94 /* OKTableViewLiaison.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewLiaison.swift; sourceTree = ""; }; - D0D7F51674FAECB8FF355ADC242260F3 /* OKPaginationTableViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKPaginationTableViewCell.swift; sourceTree = ""; }; - D31B0656D51D766ECCB859E094DA4853 /* UIView+Nib.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "UIView+Nib.swift"; sourceTree = ""; }; - DD4D0E0A26A60968B02913145CA9A381 /* OKTableViewSection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSection.swift; sourceTree = ""; }; - DD4F9A2A2032094B1321AD395314982C /* OKTableViewPrefetchCommand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewPrefetchCommand.swift; sourceTree = ""; }; - DE04C8A84ADE104739D24B0278B12D6B /* OKAnyTableViewRow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKAnyTableViewRow.swift; sourceTree = ""; }; + CA787EDE0A9AF27B47871C3853B27593 /* OKTableViewHeightType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewHeightType.swift; sourceTree = ""; }; + D03753A24C94AA1E5AB5BF7661849C16 /* OKTableViewSection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSection.swift; sourceTree = ""; }; + D84F52E8BB5649FE3CE2815A3B29BEAA /* OKPaginationTableViewSection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKPaginationTableViewSection.swift; sourceTree = ""; }; + D8E751CC2569A8D2BC0336671632CA21 /* Array+IndexPath.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "Array+IndexPath.swift"; sourceTree = ""; }; + D9440DB5089AF1C2D17A5723BB15C9CC /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+UITableViewDataSourcePrefetching.swift"; sourceTree = ""; }; E33EB9F82999F4BF1DECD3F83D5B4E3E /* Pods-OKTableViewLiaison_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OKTableViewLiaison_Example.release.xcconfig"; sourceTree = ""; }; E70A5B3AE0375111E92DE9CF4F5D7E19 /* Pods_OKTableViewLiaison_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_OKTableViewLiaison_Example.framework; path = "Pods-OKTableViewLiaison_Example.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - EA86862BFDB8B8656638C2D800B8CDBA /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; - EAB3CDB6D6FD4F6C17A3C2E87927FDC7 /* OKTableViewLiaison-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "OKTableViewLiaison-dummy.m"; sourceTree = ""; }; + E721B607138F949A1BCFDE78139ADC9A /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E8D005AF17B59B138EBACDC6A496D9F9 /* OKTableViewLiaison+UITableViewDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+UITableViewDataSource.swift"; sourceTree = ""; }; EB9D437D2F1EFA5DDCB15AEA47CC06B1 /* Pods-OKTableViewLiaison_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-OKTableViewLiaison_Tests.debug.xcconfig"; sourceTree = ""; }; EE05F59DD160A094DBF2160B64B860DC /* Pods-OKTableViewLiaison_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-OKTableViewLiaison_Tests-acknowledgements.markdown"; sourceTree = ""; }; EFA0E73D296F1AA8459DD1E42A98D65B /* Pods-OKTableViewLiaison_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-OKTableViewLiaison_Example-acknowledgements.markdown"; sourceTree = ""; }; F302F04D66835CB1A1D8D549B1344639 /* Pods-OKTableViewLiaison_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-OKTableViewLiaison_Tests-resources.sh"; sourceTree = ""; }; F4F4CA26649ED4C795F31DC7DBB17C8A /* Pods_OKTableViewLiaison_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_OKTableViewLiaison_Tests.framework; path = "Pods-OKTableViewLiaison_Tests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - F5203669EC3B9D82AE5155EEAFE4BA8B /* OKTableViewRegistrationType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewRegistrationType.swift; sourceTree = ""; }; - FD0411C11D2E1B0716E5F2B137B05DB0 /* OKTableViewSectionSupplementaryView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewSectionSupplementaryView.swift; sourceTree = ""; }; + F8DFC84727F0EC49B641A8153A0210F9 /* OKTableViewLiaison+UITableViewDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+UITableViewDelegate.swift"; sourceTree = ""; }; + F9213C72D0E30081D1918FF2F1A362FF /* OKTableViewLiaison+Row.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "OKTableViewLiaison+Row.swift"; sourceTree = ""; }; + FE1BE17D09355A39E53BB24F87072C7A /* OKTableViewLiaison.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = OKTableViewLiaison.modulemap; sourceTree = ""; }; + FF7DE0837CB8ED8E07DA73C08E2FD087 /* OKTableViewRegistrationType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OKTableViewRegistrationType.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -152,70 +152,86 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 1C605E0C80A2980A80F72FCAE02BF1A6 /* Protocols */ = { + 02DCFBBFAEEAA1BA7CBECE5538BF5B10 /* OKTableViewLiaison */ = { isa = PBXGroup; children = ( - 53A0419ABA8E3A4346F9426994A29B23 /* OKTableViewLiaisonPaginationDelegate.swift */, + 2DFF8F0D947EDFC1790B1FF38A8DBFCA /* Enums */, + 2964D6DE373F259CE5C1E2A69FC21E4D /* Extensions */, + C6CB15394066C9675C9BCC6CE2E03AEA /* Liaison */, + F58836939040FF806E7B35DCE5C82630 /* Pod */, + CCCA99CDE40E13C49E8407ADF83667AB /* Protocols */, + 5D79E4679494C64FFCFFFF6F9821199C /* Rows */, + 34690C098A91DC6F8CF7E0259D2EC535 /* Sections */, + 8C152C3B9E1C1E4DC001612EE2313AB1 /* Support Files */, + 3345EA5DDCC5200FADDB2B78EF0A4193 /* Views */, ); - name = Protocols; - path = OKTableViewLiaison/Classes/Protocols; + name = OKTableViewLiaison; + path = ../..; sourceTree = ""; }; - 2101E307246DC25FD3A5597F51DE82DE /* Views */ = { + 2964D6DE373F259CE5C1E2A69FC21E4D /* Extensions */ = { isa = PBXGroup; children = ( - D0D7F51674FAECB8FF355ADC242260F3 /* OKPaginationTableViewCell.swift */, + D8E751CC2569A8D2BC0336671632CA21 /* Array+IndexPath.swift */, + 988110A2FA354EDD69ABC921690EE2CE /* Array+SafeAccess.swift */, + 5700639C38BA4BFC0F05C48BA4B08B60 /* UIView+Nib.swift */, ); - name = Views; - path = OKTableViewLiaison/Classes/Views; + name = Extensions; + path = OKTableViewLiaison/Classes/Extensions; sourceTree = ""; }; - 416F33206DA85B126E2079DB97106970 /* Pod */ = { + 2DFF8F0D947EDFC1790B1FF38A8DBFCA /* Enums */ = { isa = PBXGroup; children = ( - 3C85172F41F9AB3481A4D1B7049B1BE9 /* LICENSE */, - 5F29FA4654BA183B137A1937CA25E62C /* OKTableViewLiaison.podspec */, - EA86862BFDB8B8656638C2D800B8CDBA /* README.md */, + CA787EDE0A9AF27B47871C3853B27593 /* OKTableViewHeightType.swift */, + 0CB40B7482723F2F846EEF4FAEBD087E /* OKTableViewPrefetchCommand.swift */, + FF7DE0837CB8ED8E07DA73C08E2FD087 /* OKTableViewRegistrationType.swift */, + 7DD48FC81602C983B892C6105D85366A /* OKTableViewRowCommand.swift */, + B3C7BBAAC0CF8CF9ED383C04CF718E8F /* OKTableViewSectionComponentCommand.swift */, + 43A395DE3DC673BE7CEE411D36B8581C /* OKTableViewSectionComponentDisplayOption.swift */, + 7E46A4CABE1813D4987E1BD6FB6863A3 /* OKTableViewSectionComponentView.swift */, ); - name = Pod; + name = Enums; + path = OKTableViewLiaison/Classes/Enums; sourceTree = ""; }; - 45D198E82D14AC8C5328A6686DD284C4 /* Targets Support Files */ = { + 3345EA5DDCC5200FADDB2B78EF0A4193 /* Views */ = { isa = PBXGroup; children = ( - 90BCDD45CDB7CBBA0E46834E9D74ED2E /* Pods-OKTableViewLiaison_Example */, - BCC81612EF9B41EB38E3AEBDD9EC1A72 /* Pods-OKTableViewLiaison_Tests */, + 70A303DCE5E0C23A0CC4747C3549AC14 /* OKPaginationTableViewCell.swift */, ); - name = "Targets Support Files"; + name = Views; + path = OKTableViewLiaison/Classes/Views; sourceTree = ""; }; - 4ACE8957B51A8B043EB6FECC57DD7870 /* Sections */ = { + 34690C098A91DC6F8CF7E0259D2EC535 /* Sections */ = { isa = PBXGroup; children = ( - 80C2B35916E39C0662EF8D8A772B7C06 /* OKAnyTableViewSection.swift */, - 4728DEDAE4C2E8312CF55E760A01C6BC /* OKPaginationTableViewSection.swift */, - C9D47A1B4B3164B5704438DE75D0431E /* OKPlainTableViewSection.swift */, - DD4D0E0A26A60968B02913145CA9A381 /* OKTableViewSection.swift */, + D84F52E8BB5649FE3CE2815A3B29BEAA /* OKPaginationTableViewSection.swift */, + D03753A24C94AA1E5AB5BF7661849C16 /* OKTableViewSection.swift */, + 45107EDC7FCB13DCE30CF0C9F0F3DBF2 /* OKTableViewSectionComponent.swift */, ); name = Sections; path = OKTableViewLiaison/Classes/Sections; sourceTree = ""; }; - 545F19B52A0C04C55054D0C2232B3859 /* OKTableViewLiaison */ = { + 45D198E82D14AC8C5328A6686DD284C4 /* Targets Support Files */ = { isa = PBXGroup; children = ( - FA04B2149595265E2A4AF17CCE2473BF /* Enums */, - DD39AC66A6D455F2184A4A1D76C09EA3 /* Extensions */, - F20B8BC62476FBE6B9DE00EE37391989 /* Liaison */, - 416F33206DA85B126E2079DB97106970 /* Pod */, - 1C605E0C80A2980A80F72FCAE02BF1A6 /* Protocols */, - C95978C5CCEB2B43E67ABDB54E65B8C7 /* Rows */, - 4ACE8957B51A8B043EB6FECC57DD7870 /* Sections */, - BA53C22D62009F45756D855BA234FCB8 /* Support Files */, - 2101E307246DC25FD3A5597F51DE82DE /* Views */, + 90BCDD45CDB7CBBA0E46834E9D74ED2E /* Pods-OKTableViewLiaison_Example */, + BCC81612EF9B41EB38E3AEBDD9EC1A72 /* Pods-OKTableViewLiaison_Tests */, ); - name = OKTableViewLiaison; - path = ../..; + name = "Targets Support Files"; + sourceTree = ""; + }; + 5D79E4679494C64FFCFFFF6F9821199C /* Rows */ = { + isa = PBXGroup; + children = ( + 1B411223C9A0AE4D3EC8FFCACB4F421D /* OKPaginationTableViewRow.swift */, + 72653247738D80D558234B3DB4CA408D /* OKTableViewRow.swift */, + ); + name = Rows; + path = OKTableViewLiaison/Classes/Rows; sourceTree = ""; }; 7DB346D0F39D3F0E887471402A8071AB = { @@ -229,6 +245,20 @@ ); sourceTree = ""; }; + 8C152C3B9E1C1E4DC001612EE2313AB1 /* Support Files */ = { + isa = PBXGroup; + children = ( + E721B607138F949A1BCFDE78139ADC9A /* Info.plist */, + FE1BE17D09355A39E53BB24F87072C7A /* OKTableViewLiaison.modulemap */, + 7AF03249C83F365BD31EA59EA2DE5EEF /* OKTableViewLiaison.xcconfig */, + 74E6A8AA40DC88B780CEC79F7A2BBB51 /* OKTableViewLiaison-dummy.m */, + 652E4A441274D252B322C363D00FA92F /* OKTableViewLiaison-prefix.pch */, + 6426368AA68672B5AF364931C3AC9CD0 /* OKTableViewLiaison-umbrella.h */, + ); + name = "Support Files"; + path = "Example/Pods/Target Support Files/OKTableViewLiaison"; + sourceTree = ""; + }; 90BCDD45CDB7CBBA0E46834E9D74ED2E /* Pods-OKTableViewLiaison_Example */ = { isa = PBXGroup; children = ( @@ -257,20 +287,6 @@ name = Products; sourceTree = ""; }; - BA53C22D62009F45756D855BA234FCB8 /* Support Files */ = { - isa = PBXGroup; - children = ( - CBFD6048103B6BA821A20F3FABB29C49 /* Info.plist */, - A61CB4FE2C120B6B8646C28295DEB824 /* OKTableViewLiaison.modulemap */, - B2E429530E4E06EBF0A166917C3AC0BD /* OKTableViewLiaison.xcconfig */, - EAB3CDB6D6FD4F6C17A3C2E87927FDC7 /* OKTableViewLiaison-dummy.m */, - 5D5704BE7155FE7B15862A1BDC2E7A25 /* OKTableViewLiaison-prefix.pch */, - B959F3D1E3BA32627850E3D928DA5574 /* OKTableViewLiaison-umbrella.h */, - ); - name = "Support Files"; - path = "Example/Pods/Target Support Files/OKTableViewLiaison"; - sourceTree = ""; - }; BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { isa = PBXGroup; children = ( @@ -297,72 +313,56 @@ path = "Target Support Files/Pods-OKTableViewLiaison_Tests"; sourceTree = ""; }; - C95978C5CCEB2B43E67ABDB54E65B8C7 /* Rows */ = { + C6CB15394066C9675C9BCC6CE2E03AEA /* Liaison */ = { isa = PBXGroup; children = ( - DE04C8A84ADE104739D24B0278B12D6B /* OKAnyTableViewRow.swift */, - ACAF0955E26848CD160A1705AE2B8EB2 /* OKPaginationTableViewRow.swift */, - 9ECF408137DF8A574EC82BB5D00D176F /* OKTableViewRow.swift */, + 352CADF3A564673CB859EAA37BF3BB1F /* OKTableViewLiaison.swift */, + 02B090087810D716A2F940B1CD632DA7 /* OKTableViewLiaison+Pagination.swift */, + F9213C72D0E30081D1918FF2F1A362FF /* OKTableViewLiaison+Row.swift */, + 86A691913FF7D14D0212D92EAB32BE10 /* OKTableViewLiaison+Section.swift */, + E8D005AF17B59B138EBACDC6A496D9F9 /* OKTableViewLiaison+UITableViewDataSource.swift */, + D9440DB5089AF1C2D17A5723BB15C9CC /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift */, + F8DFC84727F0EC49B641A8153A0210F9 /* OKTableViewLiaison+UITableViewDelegate.swift */, ); - name = Rows; - path = OKTableViewLiaison/Classes/Rows; + name = Liaison; + path = OKTableViewLiaison/Classes/Liaison; sourceTree = ""; }; - D35AF013A5F0BAD4F32504907A52519E /* iOS */ = { + CCCA99CDE40E13C49E8407ADF83667AB /* Protocols */ = { isa = PBXGroup; children = ( - 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */, + 21C29E2CB2E396FC4972CF5FA36A17E1 /* OKAnyTableViewRow.swift */, + 0F66785443E1C3F11B91C88AC269D6CC /* OKAnyTableViewSectionComponent.swift */, + 013D6D701942D44FA434B4AE746BE9D9 /* OKTableViewLiaisonPaginationDelegate.swift */, ); - name = iOS; + name = Protocols; + path = OKTableViewLiaison/Classes/Protocols; sourceTree = ""; }; - DD39AC66A6D455F2184A4A1D76C09EA3 /* Extensions */ = { + D35AF013A5F0BAD4F32504907A52519E /* iOS */ = { isa = PBXGroup; children = ( - B22B766797D9465F7B40AEF4EC3269F9 /* Array+IndexPath.swift */, - 037631C73E9A60A953770F86E9693B64 /* Array+SafeAccess.swift */, - D31B0656D51D766ECCB859E094DA4853 /* UIView+Nib.swift */, + 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */, ); - name = Extensions; - path = OKTableViewLiaison/Classes/Extensions; + name = iOS; sourceTree = ""; }; E111D39C8429175BA0C522426CFF2256 /* Development Pods */ = { isa = PBXGroup; children = ( - 545F19B52A0C04C55054D0C2232B3859 /* OKTableViewLiaison */, + 02DCFBBFAEEAA1BA7CBECE5538BF5B10 /* OKTableViewLiaison */, ); name = "Development Pods"; sourceTree = ""; }; - F20B8BC62476FBE6B9DE00EE37391989 /* Liaison */ = { + F58836939040FF806E7B35DCE5C82630 /* Pod */ = { isa = PBXGroup; children = ( - D032827B83566188A842E38273730B94 /* OKTableViewLiaison.swift */, - 1CE0AE87982C419BBA44EC3EBDD56FA7 /* OKTableViewLiaison+Pagination.swift */, - AED1A0F45195B08155B4D20A250492CB /* OKTableViewLiaison+Row.swift */, - 6CD1BB89940140E89966CC0E35C1C5EB /* OKTableViewLiaison+Section.swift */, - 099CA19DBFA45582410DC89895986F19 /* OKTableViewLiaison+UITableViewDataSource.swift */, - 31A04359AAF2C470863111D085512326 /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift */, - 3C729C187F3CA11C29E24C66E72848E9 /* OKTableViewLiaison+UITableViewDelegate.swift */, + 2C8203F23D3CD377E39EE29F3551D273 /* LICENSE */, + 9E902CF4DDF71E06D78B2A3D88A0BD07 /* OKTableViewLiaison.podspec */, + 3B928CDF2EE635B54E942CF0A14F9AD6 /* README.md */, ); - name = Liaison; - path = OKTableViewLiaison/Classes/Liaison; - sourceTree = ""; - }; - FA04B2149595265E2A4AF17CCE2473BF /* Enums */ = { - isa = PBXGroup; - children = ( - B6E886AB44F18BCD5D0480D4E3791C8E /* OKTableViewHeightType.swift */, - DD4F9A2A2032094B1321AD395314982C /* OKTableViewPrefetchCommand.swift */, - F5203669EC3B9D82AE5155EEAFE4BA8B /* OKTableViewRegistrationType.swift */, - B60DE387B941752AF876895200DB0D21 /* OKTableViewRowCommand.swift */, - 95FECFC4B44858E00EE1E218331F2683 /* OKTableViewSectionCommand.swift */, - FD0411C11D2E1B0716E5F2B137B05DB0 /* OKTableViewSectionSupplementaryView.swift */, - 3F42F59DC941A4492C4D3FBE7B58AB22 /* OKTableViewSectionSupplementaryViewDisplayOption.swift */, - ); - name = Enums; - path = OKTableViewLiaison/Classes/Enums; + name = Pod; sourceTree = ""; }; /* End PBXGroup section */ @@ -417,7 +417,7 @@ isa = PBXNativeTarget; buildConfigurationList = A37160788B509CB856D9F38276471747 /* Build configuration list for PBXNativeTarget "OKTableViewLiaison" */; buildPhases = ( - F5146B4236D469D0467B41D1B6705E1C /* Sources */, + 72A517E37F73B698E910F5142B76CBDC /* Sources */, CC9BF9EF74D56A5C33656B33DA4F2D57 /* Frameworks */, 4C6D3544BC46D2DB3B4D998982FAC3F3 /* Headers */, ); @@ -493,37 +493,37 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - F5146B4236D469D0467B41D1B6705E1C /* Sources */ = { + 72A517E37F73B698E910F5142B76CBDC /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 717F9AFA0AB8112B84FB06DDE6757F9C /* Array+IndexPath.swift in Sources */, - 172CB4D5799E74DAED12C92B7F38CC8C /* Array+SafeAccess.swift in Sources */, - DB13F401040FB5AA4D838F7F8099344A /* OKAnyTableViewRow.swift in Sources */, - 4B12D9973AD3ADE81D6934707CCB2AD2 /* OKAnyTableViewSection.swift in Sources */, - 2B4915F654A05B54762062B0F762612B /* OKPaginationTableViewCell.swift in Sources */, - 84E5393D8109BC2155627E498B928132 /* OKPaginationTableViewRow.swift in Sources */, - FACD24B6FF61E015B7D59C9E48CD64DC /* OKPaginationTableViewSection.swift in Sources */, - 889D17CD2B263127DEB060705104374B /* OKPlainTableViewSection.swift in Sources */, - C7C7845AFD4C2010A691AC2AA7563CBC /* OKTableViewHeightType.swift in Sources */, - 07C4E0DF1C3513AEAEB63A4B48BC6EC6 /* OKTableViewLiaison+Pagination.swift in Sources */, - 925042F981E5E9087B475A999D1FB8F7 /* OKTableViewLiaison+Row.swift in Sources */, - 77677C4911A09196B1032D992C9D527C /* OKTableViewLiaison+Section.swift in Sources */, - 550F3DB25F743BF3E664EC003A88DE8E /* OKTableViewLiaison+UITableViewDataSource.swift in Sources */, - BB5B7B127432FF5C6F1E2DAA9D65282B /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift in Sources */, - C94F97E6C757FB36B431891313F642E5 /* OKTableViewLiaison+UITableViewDelegate.swift in Sources */, - 5F27C078CB3FD9477A1A22C79D8A8D9C /* OKTableViewLiaison-dummy.m in Sources */, - 342C9074ECD4F4CCFE5EBD664E28C905 /* OKTableViewLiaison.swift in Sources */, - D22A79AB0A7A5A69BBF173E554FD04AF /* OKTableViewLiaisonPaginationDelegate.swift in Sources */, - E9FC8C14C51D53C4DA0DE9E072692A55 /* OKTableViewPrefetchCommand.swift in Sources */, - 692B7897C7A6CD041A516B4C06C53862 /* OKTableViewRegistrationType.swift in Sources */, - 84798FCE9D7180F2B1CA55AFF6E16BF5 /* OKTableViewRow.swift in Sources */, - 56AD0B26B10F304BAB5D38AFB9A5476A /* OKTableViewRowCommand.swift in Sources */, - 450526DEC50E17F514294A9FC3456FDA /* OKTableViewSection.swift in Sources */, - 981047491BBFF1169F9B42C9E5EBA2B3 /* OKTableViewSectionCommand.swift in Sources */, - 1E45D507FC088AFA6E1810312DB40901 /* OKTableViewSectionSupplementaryView.swift in Sources */, - 00C1794809B69E5C6CE2DB925EBF5B57 /* OKTableViewSectionSupplementaryViewDisplayOption.swift in Sources */, - F1558CD0ADAC58853C5F6E930557AC7B /* UIView+Nib.swift in Sources */, + 01B54344300D7209F67A346D72064BD6 /* Array+IndexPath.swift in Sources */, + BE81A2671D1B8FCE23D97FD9CD7B86BE /* Array+SafeAccess.swift in Sources */, + 5867716CE10B28692659EA3A640BFF56 /* OKAnyTableViewRow.swift in Sources */, + A7E9DE850A028EAA29C0318077711DBD /* OKAnyTableViewSectionComponent.swift in Sources */, + 72216124DA7B84721DC09883D71E9FE8 /* OKPaginationTableViewCell.swift in Sources */, + AD5DACB2354F1B1A530CC9ED9FE6891C /* OKPaginationTableViewRow.swift in Sources */, + 51E323F44C8B7DFEDE445BEEB04582DB /* OKPaginationTableViewSection.swift in Sources */, + C1378C7FCA09FC7448021927A7D51DBD /* OKTableViewHeightType.swift in Sources */, + 71F6D85984412B1720E2B87AB600DAA4 /* OKTableViewLiaison+Pagination.swift in Sources */, + 6A30FB635EEFF4A6F2B07E80CAFF5717 /* OKTableViewLiaison+Row.swift in Sources */, + F6E44F69CDEA987984C000254C37C772 /* OKTableViewLiaison+Section.swift in Sources */, + 486D2ABC38A9F7439590D92C7F5C8F4C /* OKTableViewLiaison+UITableViewDataSource.swift in Sources */, + C92D28FA9C922F1859ECEEB0C933C8F5 /* OKTableViewLiaison+UITableViewDataSourcePrefetching.swift in Sources */, + A6F92D029A51784FFEA6202BC67D59BC /* OKTableViewLiaison+UITableViewDelegate.swift in Sources */, + 90C0BF26F3D417BFCF0A1F11B37B98B6 /* OKTableViewLiaison-dummy.m in Sources */, + AA60C1B10768E526B0363F9425B67053 /* OKTableViewLiaison.swift in Sources */, + 17EAAFFC9F2B142134A3D4B5F97C1A12 /* OKTableViewLiaisonPaginationDelegate.swift in Sources */, + 456A6EDD76A7CC38F40E8D204F46DF7E /* OKTableViewPrefetchCommand.swift in Sources */, + 6D41673076525ACB78F8B460D9CC15F2 /* OKTableViewRegistrationType.swift in Sources */, + 79986A0365644909FE904C218033779B /* OKTableViewRow.swift in Sources */, + 1B00905F83B948E1B26FE9047DAF6D26 /* OKTableViewRowCommand.swift in Sources */, + 1B7A22EEB31348856974888B7261ADEA /* OKTableViewSection.swift in Sources */, + 5D6BA4CC383BC7640B29AC16EFE24773 /* OKTableViewSectionComponent.swift in Sources */, + 587094A5DF0C25F375029B0848784CA2 /* OKTableViewSectionComponentCommand.swift in Sources */, + CD1204377D1BF4EA8EB74B9FE83F4189 /* OKTableViewSectionComponentDisplayOption.swift in Sources */, + F38E71DD738F73B353F64E0FE99924C8 /* OKTableViewSectionComponentView.swift in Sources */, + DB3EC78D8080753420E053872B14A9E1 /* UIView+Nib.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -680,7 +680,7 @@ }; 8C6443D0BE5496879D6728BD5A6A9558 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B2E429530E4E06EBF0A166917C3AC0BD /* OKTableViewLiaison.xcconfig */; + baseConfigurationReference = 7AF03249C83F365BD31EA59EA2DE5EEF /* OKTableViewLiaison.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -782,7 +782,7 @@ }; D895C7E2F6A484D623983737B47F5EE8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B2E429530E4E06EBF0A166917C3AC0BD /* OKTableViewLiaison.xcconfig */; + baseConfigurationReference = 7AF03249C83F365BD31EA59EA2DE5EEF /* OKTableViewLiaison.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; diff --git a/Example/Pods/Target Support Files/OKTableViewLiaison/Info.plist b/Example/Pods/Target Support Files/OKTableViewLiaison/Info.plist index 7b6b52a..0a12077 100644 --- a/Example/Pods/Target Support Files/OKTableViewLiaison/Info.plist +++ b/Example/Pods/Target Support Files/OKTableViewLiaison/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.4.0 + 2.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Tests/OKTableViewLiaison+UnitTests.swift b/Example/Tests/OKTableViewLiaison+UnitTests.swift index 5e9ee71..4dead9c 100644 --- a/Example/Tests/OKTableViewLiaison+UnitTests.swift +++ b/Example/Tests/OKTableViewLiaison+UnitTests.swift @@ -12,32 +12,32 @@ import XCTest final class OKTableViewLiaison_UnitTests: XCTestCase { var liaison: OKTableViewLiaison! var tableView: UITableView! - + override func setUp() { super.setUp() liaison = OKTableViewLiaison() tableView = UITableView() liaison.liaise(tableView: tableView) } - + func test_tableViewRetain_doesNotStronglyReferenceTableView() { let tableView = UITableView() let initial = CFGetRetainCount(tableView) liaison.liaise(tableView: tableView) let current = CFGetRetainCount(tableView) - + XCTAssertEqual(initial, current) } - + func test_paginationDelegateRetain_doesNotStronglyReferencePaginationDelegate() { let delegate = TestTableViewLiaisonPaginationDelegate() let initial = CFGetRetainCount(delegate) liaison.paginationDelegate = delegate let current = CFGetRetainCount(delegate) - + XCTAssertEqual(initial, current) } - + func test_configure_setsDelegateAndDataSource() { XCTAssert(tableView.delegate === liaison) XCTAssert(tableView.dataSource === liaison) @@ -45,7 +45,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { XCTAssert(tableView.prefetchDataSource === liaison) } } - + func test_detachTableView_removesDelegateAndDataSource() { liaison.detachTableView() XCTAssert(tableView.delegate == nil) @@ -54,149 +54,165 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { XCTAssert(tableView.prefetchDataSource == nil) } } - + func test_toggleIsEditing_togglesTableViewEditingMode() { tableView.isEditing = true liaison.toggleIsEditing() - + XCTAssertFalse(tableView.isEditing) } - + func test_init_initializesWithSections() { - let sections = [TestTableViewSection(), TestTableViewSection()] + let sections = [OKTableViewSection(), OKTableViewSection()] let liaison = OKTableViewLiaison(sections: sections) liaison.liaise(tableView: tableView) XCTAssertEqual(tableView.numberOfSections, 2) } - + func test_appendSection_addsSectionToTableView() { XCTAssertEqual(tableView.numberOfSections, 0) - - let section = TestTableViewSection() + + let section = OKTableViewSection() liaison.append(section: section) XCTAssertEqual(tableView.numberOfSections, 1) XCTAssert(liaison.sections.first === section) } - + func test_appendSections_addsSectionsToTableView() { XCTAssertEqual(tableView.numberOfSections, 0) - - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() + + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() liaison.append(sections: [section1, section2]) - + XCTAssertEqual(tableView.numberOfSections, 2) XCTAssert(liaison.sections.first === section1) XCTAssert(liaison.sections.last === section2) } - + func test_insertSection_insertsSectionIntoTableView() { - let section1 = TestTableViewSection() + let section1 = OKTableViewSection() liaison.append(section: section1) XCTAssertEqual(tableView.numberOfSections, 1) - - let section2 = TestTableViewSection() + + let section2 = OKTableViewSection() liaison.insert(section: section2, at: 0) - + XCTAssertEqual(tableView.numberOfSections, 2) XCTAssert(liaison.sections.first === section2) } - + + func test_insertSections_insertsSectionsIntoTableView() { + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + let section3 = OKTableViewSection() + let section4 = OKTableViewSection() + liaison.append(sections: [section1, section2]) + + liaison.insert(sections: [section3, section4], startingAt: 1) + + XCTAssertEqual(tableView.numberOfSections, 4) + XCTAssert(liaison.sections.first === section1) + XCTAssert(liaison.sections.last === section2) + } + func test_deleteSection_removesSectionFromTableView() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - - liaison.append(section: section1) - liaison.append(section: section2) + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + + liaison.append(sections: [section1, section2]) liaison.deleteSection(at: 0) - + XCTAssertEqual(tableView.numberOfSections, 1) XCTAssert(liaison.sections.first === section2) } - + func test_replaceSection_replacesSectionOfTableView() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + liaison.append(section: section1) liaison.replaceSection(at: 0, with: section2) XCTAssertEqual(tableView.numberOfSections, 1) XCTAssert(liaison.sections.first === section2) } - + func test_moveSection_moveSectionOfTableView() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - let section3 = TestTableViewSection() - - liaison.append(section: section1) - liaison.append(section: section2) - liaison.append(section: section3) + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + let section3 = OKTableViewSection() + + liaison.append(sections: [section1, section2, section3]) liaison.moveSection(at: 0, to: 2) - + XCTAssert(liaison.sections.first === section2) XCTAssert(liaison.sections.last === section1) } - + func test_reloadSection_reloadsSectionOfTableView() { - let section = TestTableViewSection.create() + + let header = TestTableViewSectionComponent() + header.set(height: .estimatedHeight, 15) var capturedHeader: UITableViewHeaderFooterView? + let string = "Test" - section.setHeader(command: .configuration) { (header, _, index) in - header.accessibilityIdentifier = string - capturedHeader = header + header.set(command: .configuration) { view, _, _ in + view.accessibilityIdentifier = string + capturedHeader = view } + + let section = OKTableViewSection(componentDisplayOption: .header(component: header)) liaison.append(section: section) - tableView.reloadData() + liaison.reloadData() capturedHeader?.accessibilityIdentifier = "Changed" - + liaison.reloadSection(at: 0) XCTAssertEqual(capturedHeader?.accessibilityIdentifier, string) } - + func test_clearSections_removesAllSectionsFromTableView() { - - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - let section3 = TestTableViewSection() - + + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + let section3 = OKTableViewSection() + liaison.append(sections: [section1, section2, section3]) liaison.clearSections() - + XCTAssertEqual(tableView.numberOfSections, 0) XCTAssertEqual(liaison.sections.count, 0) } - + func test_clearSections_removesAllSectionsFromTableViewAndAppendsNewSections() { - - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - let section3 = TestTableViewSection() - let section4 = TestTableViewSection() - let section5 = TestTableViewSection() + + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + let section3 = OKTableViewSection() + let section4 = OKTableViewSection() + let section5 = OKTableViewSection() liaison.append(sections: [section1, section2, section3]) liaison.clearSections(replacedBy: [section4, section5]) - + XCTAssertEqual(tableView.numberOfSections, 2) XCTAssertEqual(liaison.sections.count, 2) XCTAssert(liaison.sections.first === section4) XCTAssert(liaison.sections.last === section5) } - + func test_appendRow_appendsRowToSection() { - let section = TestTableViewSection() + let section = OKTableViewSection() let row = TestTableViewRow() - + var inserted = false var actualIndexPath: IndexPath? let expectedIndexPath = IndexPath(row: 0, section: 0) @@ -204,26 +220,26 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { inserted = true actualIndexPath = indexPath } - + liaison.append(section: section) - + XCTAssert(section.rows.count == 0) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.append(row: row) } - + XCTAssert(section.rows.count == 1) XCTAssertEqual(inserted, true) XCTAssertEqual(actualIndexPath, expectedIndexPath) } - + func test_appendRows_appendsRowsToSection() { - let section = TestTableViewSection() + let section = OKTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() - + var insertedRow1 = false var actualIndexPathRow1: IndexPath? let expectedIndexPathRow1 = IndexPath(row: 0, section: 0) @@ -231,7 +247,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { insertedRow1 = true actualIndexPathRow1 = indexPath } - + var insertedRow2 = false var actualIndexPathRow2: IndexPath? let expectedIndexPathRow2 = IndexPath(row: 1, section: 0) @@ -241,56 +257,57 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { } liaison.append(section: section) - + XCTAssert(section.rows.count == 0) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.append(rows: [row1, row2]) } - + XCTAssert(section.rows.count == 2) XCTAssertEqual(insertedRow1, true) XCTAssertEqual(insertedRow2, true) XCTAssertEqual(actualIndexPathRow1, expectedIndexPathRow1) XCTAssertEqual(actualIndexPathRow2, expectedIndexPathRow2) } - + func test_insertRow_insertsRowIntoSection() { - let section = TestTableViewSection() + let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() - + + let section = OKTableViewSection(rows: [row1, row2]) + liaison.append(section: section) - liaison.append(rows: [row1, row2]) - + let expectedIndexPath = IndexPath(row: 0, section: 0) var insertedRow = false var actualIndexPathRow: IndexPath? - + row3.set(command: .insert) { (_, _, indexPath) in insertedRow = true actualIndexPathRow = indexPath } - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.insert(row: row3, at: expectedIndexPath) } - + XCTAssert(section.rows.first === row3) XCTAssertEqual(insertedRow, true) XCTAssertEqual(actualIndexPathRow, expectedIndexPath) } - + func test_deleteRows_removesRowsFromTableView() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() - + let row1IndexPath = IndexPath(row: 0, section: 0) var deletedRow1 = false var actualIndexPathRow1: IndexPath? @@ -298,7 +315,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { deletedRow1 = true actualIndexPathRow1 = indexPath } - + let row3IndexPath = IndexPath(row: 0, section: 1) var deletedRow3 = false var actualIndexPathRow3: IndexPath? @@ -310,12 +327,12 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { liaison.append(sections: [section1, section2]) liaison.append(rows: [row1, row2]) liaison.append(row: row3, to: 1) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.deleteRows(at: [row1IndexPath, row3IndexPath]) } - + XCTAssertEqual(section1.rows.count, 1) XCTAssertEqual(section2.rows.count, 0) XCTAssertEqual(deletedRow1, true) @@ -323,12 +340,11 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { XCTAssertEqual(actualIndexPathRow1, row1IndexPath) XCTAssertEqual(actualIndexPathRow3, row3IndexPath) } - + func test_deleteRow_removesRowFromSection() { - let section = TestTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() - + let expectedIndexPath = IndexPath(row: 0, section: 0) var deletedRow = false var actualIndexPathRow: IndexPath? @@ -337,80 +353,78 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { actualIndexPathRow = indexPath } + let section = OKTableViewSection.init(rows: [row1, row2]) liaison.append(section: section) - liaison.append(rows: [row1, row2]) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.deleteRow(at: expectedIndexPath) } - + XCTAssert(section.rows.count == 1) XCTAssert(section.rows.first === row2) XCTAssertEqual(deletedRow, true) XCTAssertEqual(actualIndexPathRow, expectedIndexPath) } - + func test_reloadRows_reloadsRowsInSection() { - let section = TestTableViewSection() - let row = TestTableViewRow.create() - + let row = TestTableViewRow() + var reloaded = false row.set(command: .reload) { (_, _, _) in reloaded = true } - + + let section = OKTableViewSection(rows: [row]) + liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.reloadRows(at: [IndexPath(row: 0, section: 0)]) } let count = tableView.callCounts[.reloadRows] - + XCTAssertEqual(count, 1) XCTAssertEqual(reloaded, true) } - + func test_replaceRow_replaceRowInSection() { - let section = TestTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() - + var deleted = false row1.set(command: .delete) { (_, _, _) in deleted = true } - + var inserted = false row2.set(command: .insert) { (_, _, _) in inserted = true } - + + let section = OKTableViewSection(rows: [row1]) liaison.append(section: section) - liaison.append(row: row1) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.replaceRow(at: IndexPath(row: 0, section: 0), with: row2) } - + XCTAssert(section.rows.count == 1) XCTAssert(section.rows.first === row2) XCTAssertEqual(deleted, true) XCTAssertEqual(inserted, true) } - + func test_moveRow_withinSameSection() { - let section = TestTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() - + var moved = false var actualDestination: IndexPath? let destination = IndexPath(row: 2, section: 0) @@ -419,31 +433,31 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { actualDestination = indexPath } + let section = OKTableViewSection(rows: [row1, row2, row3]) liaison.append(section: section) - liaison.append(rows: [row1, row2, row3]) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.moveRow(from: IndexPath(row: 0, section: 0), to: destination) } - + XCTAssert(section.rows.first === row2) XCTAssert(section.rows.last === row1) XCTAssertEqual(moved, true) XCTAssertEqual(actualDestination, destination) } - + func test_moveRow_intoDifferentSection() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() let row4 = TestTableViewRow() let row5 = TestTableViewRow() - + var moved = false var actualDestination: IndexPath? let destination = IndexPath(row: 2, section: 1) @@ -451,7 +465,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { moved = true actualDestination = indexPath } - + liaison.append(section: section1) liaison.append(section: section2) @@ -462,7 +476,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { tableView.performInSwizzledEnvironment { liaison.moveRow(from: IndexPath(row: 0, section: 0), to: destination) } - + XCTAssert(section1.rows.count == 2) XCTAssert(section1.rows.first === row2) XCTAssert(section2.rows.count == 3) @@ -470,13 +484,13 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { XCTAssertEqual(moved, true) XCTAssertEqual(actualDestination, destination) } - + func test_swapRow_withinSameSection() { - let section = TestTableViewSection() + let section = OKTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() - + var sourceMoved = false var swappedSourceIndexPath: IndexPath? let sourceIndexPath = IndexPath(row: 0, section: 0) @@ -484,7 +498,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { sourceMoved = true swappedSourceIndexPath = indexPath } - + var destinationMoved = false var swappedDestinationIndexPath: IndexPath? let destinationIndexPath = IndexPath(row: 2, section: 0) @@ -492,7 +506,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { destinationMoved = true swappedDestinationIndexPath = indexPath } - + liaison.append(section: section) liaison.append(rows: [row1, row2, row3]) @@ -500,7 +514,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { tableView.performInSwizzledEnvironment { liaison.swapRow(from: sourceIndexPath, to: destinationIndexPath) } - + XCTAssert(section.rows.first === row3) XCTAssert(section.rows.last === row1) XCTAssertEqual(sourceMoved, true) @@ -509,16 +523,16 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { XCTAssertEqual(swappedDestinationIndexPath, sourceIndexPath) } - + func test_swapRow_intoDifferentSection() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() let row4 = TestTableViewRow() - + var sourceMoved = false var swappedSourceIndexPath: IndexPath? let sourceIndexPath = IndexPath(row: 0, section: 0) @@ -526,7 +540,7 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { sourceMoved = true swappedSourceIndexPath = indexPath } - + var destinationMoved = false var swappedDestinationIndexPath: IndexPath? let destinationIndexPath = IndexPath(row: 1, section: 1) @@ -534,18 +548,18 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { destinationMoved = true swappedDestinationIndexPath = indexPath } - + liaison.append(section: section1) liaison.append(section: section2) - + liaison.append(rows: [row1, row2]) liaison.append(rows: [row3, row4], to: 1) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.swapRow(from: sourceIndexPath, to: destinationIndexPath) } - + XCTAssert(section1.rows.first === row4) XCTAssert(section2.rows.last === row1) XCTAssertEqual(sourceMoved, true) @@ -553,314 +567,300 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { XCTAssertEqual(swappedSourceIndexPath, destinationIndexPath) XCTAssertEqual(swappedDestinationIndexPath, sourceIndexPath) } - + func test_tableViewCellForRow_createsCorrectCellForRow() { - let section = TestTableViewSection() - - let row = TestTableViewRow.create() + let section = OKTableViewSection() + + let row = TestTableViewRow() let string = "Test" row.set(command: .configuration) { (cell, _, indexPath) in cell.accessibilityIdentifier = string } - + liaison.append(section: section) liaison.append(row: row) - + let cell = liaison.tableView(tableView, cellForRowAt: IndexPath(row: 0, section: 0)) - + XCTAssertEqual(cell.accessibilityIdentifier, string) - + } - + func test_numberOfSectionsInTableView_returnsCorrectAmountOfSections() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - - liaison.append(section: section1) - liaison.append(section: section2) + let section1 = OKTableViewSection() + let section2 = OKTableViewSection() + + liaison.append(sections: [section1, section2]) let count = liaison.numberOfSections(in: tableView) - + XCTAssertEqual(count, 2) } - + func test_tableViewNumberOfRowsInSection_returnsCorrectAmountOfRows() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - + let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() let row4 = TestTableViewRow() let row5 = TestTableViewRow() - + + let section1 = OKTableViewSection(rows: [row1, row2]) + let section2 = OKTableViewSection(rows: [row3, row4, row5]) + liaison.append(section: section1) liaison.append(section: section2) - - liaison.append(rows: [row1, row2]) - liaison.append(rows: [row3, row4, row5], to: 1) - + let section1Count = liaison.tableView(tableView, numberOfRowsInSection: 0) let section2Count = liaison.tableView(tableView, numberOfRowsInSection: 1) - + XCTAssertEqual(section1Count, 2) XCTAssertEqual(section2Count, 3) } - + func test_tableViewCanEditRow_correctlyReturnsWhetherRowIsEditable() { - let section = TestTableViewSection() let row1 = TestTableViewRow(editingStyle: .delete) let row2 = TestTableViewRow(editingStyle: .insert) let row3 = TestTableViewRow() - + + let section = OKTableViewSection(rows: [row1, row2, row3]) liaison.append(section: section) - liaison.append(rows: [row1, row2, row3]) - + let row1Editable = liaison.tableView(tableView, canEditRowAt: IndexPath(row: 0, section: 0)) let row2Editable = liaison.tableView(tableView, canEditRowAt: IndexPath(row: 1, section: 0)) let row3Editable = liaison.tableView(tableView, canEditRowAt: IndexPath(row: 2, section: 0)) let nonExistentRowEditable = liaison.tableView(tableView, canEditRowAt: IndexPath(row: 3, section: 0)) - + XCTAssertEqual(row1Editable, true) XCTAssertEqual(row2Editable, true) XCTAssertEqual(row3Editable, false) XCTAssertEqual(nonExistentRowEditable, false) } - + func test_tableViewCanMoveRow_correctlyReturnsWhetherRowIsMovable() { - let section = TestTableViewSection() let row1 = TestTableViewRow(movable: true) let row2 = TestTableViewRow() - + + let section = OKTableViewSection(rows: [row1, row2]) liaison.append(section: section) - liaison.append(rows: [row1, row2]) - + let row1Movable = liaison.tableView(tableView, canMoveRowAt: IndexPath(row: 0, section: 0)) let row2Movable = liaison.tableView(tableView, canMoveRowAt: IndexPath(row: 1, section: 0)) let nonExistentRowMovable = liaison.tableView(tableView, canMoveRowAt: IndexPath(row: 2, section: 0)) - + XCTAssertEqual(row1Movable, true) XCTAssertEqual(row2Movable, false) XCTAssertEqual(nonExistentRowMovable, false) } func test_tableViewCommitEditingStyle_performsEditingActionRowForIndexPath() { - let section = TestTableViewSection() + let section = OKTableViewSection() let row1 = TestTableViewRow(editingStyle: .delete) let row2 = TestTableViewRow(editingStyle: .insert) var deleted = false var inserted = false - row1.set(command: .delete) { (_, _, _) in + row1.set(command: .delete) { _, _, _ in deleted = true } - - row2.set(command: .insert) { (_, _, _) in + + row2.set(command: .insert) { _, _, _ in inserted = true } - + liaison.append(section: section) liaison.append(rows: [row1, row2]) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, commit: .delete, forRowAt: IndexPath(row: 0, section: 0)) liaison.tableView(tableView, commit: .insert, forRowAt: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(deleted, true) XCTAssertEqual(inserted, true) XCTAssertEqual(section.rows.count, 1) } - + func test_moveRowAt_properlyMovesRowFromOneSourceIndexPathToDestinationIndexPath() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - + var moved = false let row1 = TestTableViewRow() row1.set(command: .move) { (_, _, _) in moved = true } - + let row2 = TestTableViewRow() let row3 = TestTableViewRow() - + + let section1 = OKTableViewSection(rows: [row1, row2, row3]) + let section2 = OKTableViewSection() + liaison.append(sections: [section1, section2]) - liaison.append(rows: [row1, row2, row3]) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, moveRowAt: IndexPath(row: 0, section: 0), to: IndexPath(row: 0, section: 1)) } - + XCTAssertEqual(moved, true) XCTAssertEqual(section1.rows.count, 2) XCTAssert(section2.rows.first === row1) } - + func test_willSelectRow_performsWillSelectCommand() { - let section = TestTableViewSection() + let row = TestTableViewRow() var willSelect = false - - row.set(command: .willSelect) { (_, _, _) in + + row.set(command: .willSelect) { _, _, _ in willSelect = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() let expectedIndexPath = IndexPath(row: 0, section: 0) var indexPath: IndexPath? tableView.performInSwizzledEnvironment { indexPath = liaison.tableView(tableView, willSelectRowAt: expectedIndexPath) } - + XCTAssertEqual(willSelect, true) XCTAssertEqual(indexPath, expectedIndexPath) } - + func test_didSelectRow_performsDidSelectCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var didSelected = false - - row.set(command: .didSelect) { (_, _, _) in + + row.set(command: .didSelect) { _, _, _ in didSelected = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, didSelectRowAt: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(didSelected, true) } - + func test_willDeselectRow_performsWillDeselectCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var willDeselect = false - - row.set(command: .willDeselect) { (_, _, _) in + + row.set(command: .willDeselect) { _, _, _ in willDeselect = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() let expectedIndexPath = IndexPath(row: 0, section: 0) var indexPath: IndexPath? tableView.performInSwizzledEnvironment { indexPath = liaison.tableView(tableView, willDeselectRowAt: expectedIndexPath) } - + XCTAssertEqual(willDeselect, true) XCTAssertEqual(indexPath, expectedIndexPath) } - + func test_didDeselectRow_performsDidDeselectCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var didDeselect = false - + row.set(command: .didDeselect) { (_, _, _) in didDeselect = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, didDeselectRowAt: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(didDeselect, true) } - + func test_targetIndexPathForMoveFromRowToProposed_correctlyMovesRow() { - let section1 = TestTableViewSection() - let section2 = TestTableViewSection() - let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() let row4 = TestTableViewRow() let row5 = TestTableViewRow() - - liaison.append(section: section1) - liaison.append(section: section2) - - liaison.append(rows: [row1, row2, row3]) - liaison.append(rows: [row4, row5], to: 1) - + + let section1 = OKTableViewSection(rows: [row1, row2, row3]) + let section2 = OKTableViewSection(rows: [row4, row5]) + + liaison.append(sections: [section1, section2]) + let destination = liaison.tableView(tableView, targetIndexPathForMoveFromRowAt: IndexPath(row: 0, section: 0), toProposedIndexPath: IndexPath(row: 0, section: 1)) - + XCTAssertEqual(section1.rows.count, 2) XCTAssertEqual(section2.rows.count, 3) XCTAssert(section1.rows.first === row2) XCTAssert(section2.rows.first === row1) XCTAssertEqual(destination, IndexPath(row: 0, section: 1)) } - + func test_willDisplayCell_performsWillDisplayCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var willDisplay = false - + row.set(command: .willDisplay) { (_, _, _) in willDisplay = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + let cell = UITableViewCell() liaison.tableView(tableView, willDisplay: cell, forRowAt: IndexPath(row: 0, section: 0)) - + XCTAssertEqual(willDisplay, true) - } - + } + func test_willDisplayCell_paginationDelegateGetsCalled() { - let section = TestTableViewSection() let row = TestTableViewRow() let delegate = TestTableViewLiaisonPaginationDelegate() - + liaison.paginationDelegate = delegate - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + liaison.tableView(tableView, willDisplay: UITableViewCell(), forRowAt: IndexPath(row: 0, section: 0)) - + keyValueObservingExpectation(for: delegate, keyPath: "paginationStartedCallCount") { (delegate, json) -> Bool in guard let delegate = delegate as? TestTableViewLiaisonPaginationDelegate else { return false } - + return delegate.paginationStartedCallCount == 1 && delegate.isPaginationEnabledCallCount == 1 } - + waitForExpectations(timeout: 0.2, handler: nil) } - + func test_appendSection_paginationDelegateEndsByAppendingSection() { let row1 = TestTableViewRow() let row2 = TestTableViewRow() - let section1 = TestTableViewSection(rows: [row1, row2]) + let section1 = OKTableViewSection(rows: [row1, row2]) let delegate = TestTableViewLiaisonPaginationDelegate() let row3 = TestTableViewRow() - let section2 = TestTableViewSection(rows: [row3]) + let section2 = OKTableViewSection(rows: [row3]) liaison.paginationDelegate = delegate liaison.append(section: section1) @@ -874,16 +874,16 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { guard let delegate = delegate as? TestTableViewLiaisonPaginationDelegate else { return false } - + return delegate.paginationEndedCallCount == 1 } - + waitForExpectations(timeout: 0.5, handler: nil) } - + func test_appendRow_paginationDelegateEndsByAppendingRow() { let row1 = TestTableViewRow() - let section = TestTableViewSection(rows: [row1]) + let section = OKTableViewSection(rows: [row1]) let delegate = TestTableViewLiaisonPaginationDelegate() let row2 = TestTableViewRow() @@ -895,255 +895,241 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { DispatchQueue.main.async { self.liaison.append(row: row2) } - + keyValueObservingExpectation(for: delegate, keyPath: "paginationEndedCallCount") { (delegate, json) -> Bool in guard let delegate = delegate as? TestTableViewLiaisonPaginationDelegate else { return false } - + return delegate.paginationEndedCallCount == 1 } - + waitForExpectations(timeout: 0.5, handler: nil) } - + func test_didEndDisplayingCell_performsDidEndDisplayingCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var didEndDisplaying = false - + row.set(command: .didEndDisplaying) { (_, _, _) in didEndDisplaying = true } - - liaison.append(section: section) - liaison.append(row: row) - + + liaison.append(section: OKTableViewSection(rows: [row])) + let cell = UITableViewCell() liaison.tableView(tableView, didEndDisplaying: cell, forRowAt: IndexPath(row: 0, section: 0)) - + XCTAssertEqual(didEndDisplaying, true) } - + func test_willBeginEditingRow_performsWillBeginEditingCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var willBeginEditing = false - + row.set(command: .willBeginEditing) { (_, _, _) in willBeginEditing = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, willBeginEditingRowAt: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(willBeginEditing, true) } - + func test_didEndEditingRow_performsDidEndEditingCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var didEndEditing = false - + row.set(command: .didEndEditing) { (_, _, _) in didEndEditing = true } - - liaison.append(section: section) - liaison.append(row: row) - + + liaison.append(section: OKTableViewSection(rows: [row])) + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, didEndEditingRowAt: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(didEndEditing, true) } - + func test_didHighlightRow_performsDidHighlightRowCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var didHighlight = false - + row.set(command: .didHighlight) { (_, _, _) in didHighlight = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, didHighlightRowAt: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(didHighlight, true) } - + func test_didUnhighlightRow_performsDidUnhighlightRowCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var didUnhighlight = false - + row.set(command: .didUnhighlight) { (_, _, _) in didUnhighlight = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, didUnhighlightRowAt: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(didUnhighlight, true) } - + func test_viewForHeaderInSection_returnCorrectHeaderForSection() { - let section1 = TestTableViewSection.create() - let section2 = TestTableViewSection.create() - - section1.setHeader(command: .configuration) { (header, string, section) in - header.accessibilityIdentifier = "\(section)" - } - - section2.setHeader(command: .configuration) { (header, string, section) in - header.accessibilityIdentifier = "\(section)" + + let header = TestTableViewSectionComponent() + + header.set(command: .configuration) { view, _, section in + view.accessibilityIdentifier = "\(section)" } - - liaison.append(section: section1) - liaison.append(section: section2) - + + let section1 = OKTableViewSection(componentDisplayOption: .header(component: header)) + let section2 = OKTableViewSection(componentDisplayOption: .header(component: header)) + + liaison.append(sections: [section1, section2]) + let section1Header = liaison.tableView(tableView, viewForHeaderInSection: 0) let section2Header = liaison.tableView(tableView, viewForHeaderInSection: 1) - + XCTAssertEqual(section1Header?.accessibilityIdentifier, "0") XCTAssertEqual(section2Header?.accessibilityIdentifier, "1") } - + func test_viewForFooterInSection_returnCorrectFooterForSection() { - let section1 = TestTableViewSection.create() - let section2 = TestTableViewSection.create() - - section1.setFooter(command: .configuration) { (footer, string, section) in - footer.accessibilityIdentifier = "\(section)" - } - - section2.setFooter(command: .configuration) { (footer, string, section) in - footer.accessibilityIdentifier = "\(section)" + + let footer = TestTableViewSectionComponent() + + footer.set(command: .configuration) { view, _, section in + view.accessibilityIdentifier = "\(section)" } - - liaison.append(section: section1) - liaison.append(section: section2) - + + let section1 = OKTableViewSection(componentDisplayOption: .footer(component: footer)) + let section2 = OKTableViewSection(componentDisplayOption: .footer(component: footer)) + + liaison.append(sections: [section1, section2]) + let section1Header = liaison.tableView(tableView, viewForFooterInSection: 0) let section2Header = liaison.tableView(tableView, viewForFooterInSection: 1) - + XCTAssertEqual(section1Header?.accessibilityIdentifier, "0") XCTAssertEqual(section2Header?.accessibilityIdentifier, "1") } - + func test_heightForRow_properlySetsHeightsForRows() { - let section = TestTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() - row1.set(height: .height) { (_) -> CGFloat in + row1.set(height: .height) { _ -> CGFloat in return 100 } - - row2.set(height: .height, value: 200) + + row2.set(height: .height, 200) + + let section = OKTableViewSection(rows: [row1, row2, row3]) liaison.append(section: section) - liaison.append(rows: [row1, row2, row3]) - + let row1Height = liaison.tableView(tableView, heightForRowAt: IndexPath(row: 0, section: 0)) let row2Height = liaison.tableView(tableView, heightForRowAt: IndexPath(row: 1, section: 0)) let row3Height = liaison.tableView(tableView, heightForRowAt: IndexPath(row: 2, section: 0)) - + XCTAssertEqual(row1Height, 100) XCTAssertEqual(row2Height, 200) XCTAssertEqual(row3Height, UITableViewAutomaticDimension) } - + func test_estimatedHeightForRow_properlySetsEstimatedHeightsForRows() { - let section = TestTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() let row3 = TestTableViewRow() - - row1.set(height: .estimatedHeight) { (_) -> CGFloat in + + row1.set(height: .estimatedHeight) { _ -> CGFloat in return 100 } - - row2.set(height: .estimatedHeight, value: 200) + + row2.set(height: .estimatedHeight, 200) + + let section = OKTableViewSection(rows: [row1, row2, row3]) liaison.append(section: section) - liaison.append(rows: [row1, row2, row3]) - + let row1Height = liaison.tableView(tableView, estimatedHeightForRowAt: IndexPath(row: 0, section: 0)) let row2Height = liaison.tableView(tableView, estimatedHeightForRowAt: IndexPath(row: 1, section: 0)) let row3Height = liaison.tableView(tableView, estimatedHeightForRowAt: IndexPath(row: 2, section: 0)) - + XCTAssertEqual(row1Height, 100) XCTAssertEqual(row2Height, 200) XCTAssertEqual(row3Height, UITableViewAutomaticDimension) } - + func test_shouldIndentWhileEditingRow_correctlyReturnsIfRowShouldIndentWhileBeingEdited() { - let section = TestTableViewSection() let row1 = TestTableViewRow(indentWhileEditing: true) let row2 = TestTableViewRow() - + + let section = OKTableViewSection(rows: [row1, row2]) liaison.append(section: section) - liaison.append(rows: [row1, row2]) - + let row1ShouldIndent = liaison.tableView(tableView, shouldIndentWhileEditingRowAt: IndexPath(row: 0, section: 0)) let row2ShouldIndent = liaison.tableView(tableView, shouldIndentWhileEditingRowAt: IndexPath(row: 1, section: 0)) let nonExistentRowShouldIndent = liaison.tableView(tableView, shouldIndentWhileEditingRowAt: IndexPath(row: 2, section: 0)) - + XCTAssertEqual(row1ShouldIndent, true) XCTAssertEqual(row2ShouldIndent, false) XCTAssertEqual(nonExistentRowShouldIndent, false) } - + func test_editingStyleForRow_correctlyReturnsEditingStyleForRow() { - let section = TestTableViewSection() let row1 = TestTableViewRow(editingStyle: .delete) let row2 = TestTableViewRow(editingStyle: .insert) let row3 = TestTableViewRow() + let section = OKTableViewSection(rows: [row1, row2, row3]) liaison.append(section: section) - liaison.append(rows: [row1, row2, row3]) - + let row1EditingStyle = liaison.tableView(tableView, editingStyleForRowAt: IndexPath(row: 0, section: 0)) let row2EditingStyle = liaison.tableView(tableView, editingStyleForRowAt: IndexPath(row: 1, section: 0)) let row3EditingStyle = liaison.tableView(tableView, editingStyleForRowAt: IndexPath(row: 2, section: 0)) let nonExistentRowEditingStyle = liaison.tableView(tableView, editingStyleForRowAt: IndexPath(row: 3, section: 0)) - + XCTAssertEqual(row1EditingStyle, .delete) XCTAssertEqual(row2EditingStyle, .insert) XCTAssertEqual(row3EditingStyle, .none) XCTAssertEqual(nonExistentRowEditingStyle, .none) } - + func test_editActionsForRow_correctlyReturnsEditActions() { - let section = TestTableViewSection() let editAction = UITableViewRowAction(style: .normal, title: "Action", handler: { (action, indexPath) in print("This action is being invoked") }) - + let row1 = TestTableViewRow(editActions: [editAction]) let row2 = TestTableViewRow() - + + let section = OKTableViewSection(rows: [row1, row2]) liaison.append(section: section) - liaison.append(rows: [row1, row2]) - + let row1EditActions = liaison.tableView(tableView, editActionsForRowAt: IndexPath(row: 0, section: 0)) let row2EditActions = liaison.tableView(tableView, editActionsForRowAt: IndexPath(row: 1, section: 0)) let nonExistentRowEditActions = liaison.tableView(tableView, editActionsForRowAt: IndexPath(row: 2, section: 0)) @@ -1151,180 +1137,259 @@ final class OKTableViewLiaison_UnitTests: XCTestCase { XCTAssert(row2EditActions == nil) XCTAssert(nonExistentRowEditActions == nil) } - + func test_accessoryButtonTapped_performsAccessoryButtonTappedCommand() { - let section = TestTableViewSection() let row = TestTableViewRow() var accessoryButtonTapped = false - + row.set(command: .accessoryButtonTapped) { (_, _, _) in accessoryButtonTapped = true } - + + let section = OKTableViewSection(rows: [row]) liaison.append(section: section) - liaison.append(row: row) - + tableView.stubCell = UITableViewCell() tableView.performInSwizzledEnvironment { liaison.tableView(tableView, accessoryButtonTappedForRowWith: IndexPath(row: 0, section: 0)) } - + XCTAssertEqual(accessoryButtonTapped, true) } - + func test_titleForDeleteConfirmationButton_returnsCorrectDeleteConfirmationTitleForRow() { - let section = TestTableViewSection() let row1 = TestTableViewRow(deleteConfirmationTitle: "Delete") let row2 = TestTableViewRow() - + + let section = OKTableViewSection(rows: [row1, row2]) liaison.append(section: section) - liaison.append(rows: [row1, row2]) - + let row1DeleteConfirmationTitle = liaison.tableView(tableView, titleForDeleteConfirmationButtonForRowAt: IndexPath(row: 0, section: 0)) let row2DeleteConfirmationTitle = liaison.tableView(tableView, titleForDeleteConfirmationButtonForRowAt: IndexPath(row: 1, section: 0)) let nonExistentRowDeleteConfirmationTitle = liaison.tableView(tableView, titleForDeleteConfirmationButtonForRowAt: IndexPath(row: 2, section: 0)) - + XCTAssertEqual(row1DeleteConfirmationTitle, "Delete") XCTAssert(row2DeleteConfirmationTitle == nil) XCTAssert(nonExistentRowDeleteConfirmationTitle == nil) } - + func test_heightForHeader_properlySetsHeightsForSectionHeaders() { - let section1 = TestTableViewSection.create() - let section2 = TestTableViewSection.create() - let section3 = TestTableViewSection.create() - - section1.setHeight(for: .header) { _ -> CGFloat in - return 100 + let header1 = TestTableViewSectionComponent() + let header2 = TestTableViewSectionComponent() + let header3 = TestTableViewSectionComponent() + + header1.set(height: .height, 100) + + header2.set(height: .height) { _ -> CGFloat in + return 200 } - - section2.setHeight(for: .header, value: 200) - - liaison.append(section: section1) - liaison.append(section: section2) - liaison.append(section: section3) - + + let section1 = OKTableViewSection(componentDisplayOption: .header(component: header1)) + let section2 = OKTableViewSection(componentDisplayOption: .header(component: header2)) + let section3 = OKTableViewSection(componentDisplayOption: .header(component: header3)) + + liaison.append(sections: [section1, section2, section3]) + let section1Height = liaison.tableView(tableView, heightForHeaderInSection: 0) let section2Height = liaison.tableView(tableView, heightForHeaderInSection: 1) let section3Height = liaison.tableView(tableView, heightForHeaderInSection: 2) - + XCTAssertEqual(section1Height, 100) XCTAssertEqual(section2Height, 200) XCTAssertEqual(section3Height, UITableViewAutomaticDimension) } - func test_heightForFooter_properlySetsHeightsForSectionFooters() { - let section1 = TestTableViewSection.create() - let section2 = TestTableViewSection.create() - let section3 = TestTableViewSection.create() + func test_estimatedHeightForHeader_properlySetsEstimatedHeightsForSectionHeaders() { + let header1 = TestTableViewSectionComponent() + let header2 = TestTableViewSectionComponent() + let header3 = TestTableViewSectionComponent() + let header4 = TestTableViewSectionComponent() - section1.setHeight(for: .footer) { _ -> CGFloat in - return 100 + header1.set(height: .estimatedHeight, 100) + + header2.set(height: .estimatedHeight) { _ -> CGFloat in + return 200 } - section2.setHeight(for: .footer, value: 200) + header3.set(height: .height, 300) - liaison.append(section: section1) - liaison.append(section: section2) - liaison.append(section: section3) + let section1 = OKTableViewSection(componentDisplayOption: .header(component: header1)) + let section2 = OKTableViewSection(componentDisplayOption: .header(component: header2)) + let section3 = OKTableViewSection(componentDisplayOption: .header(component: header3)) + let section4 = OKTableViewSection(componentDisplayOption: .header(component: header4)) + + liaison.append(sections: [section1, section2, section3, section4]) +// let section1EstimatedHeight = liaison.tableView(tableView, estimatedHeightForHeaderInSection: 0) +// let section2EstimatedHeight = liaison.tableView(tableView, estimatedHeightForHeaderInSection: 1) +// let section3EstimatedHeight = liaison.tableView(tableView, estimatedHeightForHeaderInSection: 2) +// let section4EstimatedHeight = liaison.tableView(tableView, estimatedHeightForHeaderInSection: 3) +// +// XCTAssertEqual(section1EstimatedHeight, 100) +// XCTAssertEqual(section2EstimatedHeight, 200) +// XCTAssertEqual(section3EstimatedHeight, 300) +// XCTAssertEqual(section4EstimatedHeight, 0) + } + + func test_heightForFooter_properlySetsHeightsForSectionFooters() { + let footer1 = TestTableViewSectionComponent() + let footer2 = TestTableViewSectionComponent() + let footer3 = TestTableViewSectionComponent() + + footer1.set(height: .height, 100) + + footer2.set(height: .height) { _ -> CGFloat in + return 200 + } + + let section1 = OKTableViewSection(componentDisplayOption: .footer(component: footer1)) + let section2 = OKTableViewSection(componentDisplayOption: .footer(component: footer2)) + let section3 = OKTableViewSection(componentDisplayOption: .footer(component: footer3)) + + liaison.append(sections: [section1, section2, section3]) + let section1Height = liaison.tableView(tableView, heightForFooterInSection: 0) let section2Height = liaison.tableView(tableView, heightForFooterInSection: 1) let section3Height = liaison.tableView(tableView, heightForFooterInSection: 2) - + XCTAssertEqual(section1Height, 100) XCTAssertEqual(section2Height, 200) XCTAssertEqual(section3Height, UITableViewAutomaticDimension) } + func test_estimatedHeightForFooter_properlySetsEstimatedHeightsForSectionFooters() { + let footer1 = TestTableViewSectionComponent() + let footer2 = TestTableViewSectionComponent() + let footer3 = TestTableViewSectionComponent() + let footer4 = TestTableViewSectionComponent() + + footer1.set(height: .estimatedHeight, 100) + + footer2.set(height: .estimatedHeight) { _ -> CGFloat in + return 200 + } + + footer3.set(height: .height, 300) + + let section1 = OKTableViewSection(componentDisplayOption: .footer(component: footer1)) + let section2 = OKTableViewSection(componentDisplayOption: .footer(component: footer2)) + let section3 = OKTableViewSection(componentDisplayOption: .footer(component: footer3)) + let section4 = OKTableViewSection(componentDisplayOption: .footer(component: footer4)) + + liaison.append(sections: [section1, section2, section3, section4]) + +// let section1EstimatedHeight = liaison.tableView(tableView, estimatedHeightForFooterInSection: 0) +// let section2EstimatedHeight = liaison.tableView(tableView, estimatedHeightForFooterInSection: 1) +// let section3EstimatedHeight = liaison.tableView(tableView, estimatedHeightForFooterInSection: 2) +// let section4EstimatedHeight = liaison.tableView(tableView, estimatedHeightForFooterInSection: 3) +// +// XCTAssertEqual(section1EstimatedHeight, 100) +// XCTAssertEqual(section2EstimatedHeight, 200) +// XCTAssertEqual(section3EstimatedHeight, 300) +// XCTAssertEqual(section4EstimatedHeight, 0) + } + + func test_willDisplayHeaderView_performsWillDisplayHeaderViewSectionCommand() { - let section = TestTableViewSection() + + let header = TestTableViewSectionComponent() + var willDisplay = false - - section.setHeader(command: .willDisplay) { (_, _, _) in + header.set(command: .willDisplay) { _, _, _ in willDisplay = true } - + + let section = OKTableViewSection(componentDisplayOption: .header(component: header)) + liaison.append(section: section) let view = UITableViewHeaderFooterView() liaison.tableView(tableView, willDisplayHeaderView: view, forSection: 0) - + XCTAssertEqual(willDisplay, true) } - + func test_willDisplayFooterView_performsWillDisplayFooterViewSectionCommand() { - let section = TestTableViewSection() + + let footer = TestTableViewSectionComponent() + var willDisplay = false - - section.setFooter(command: .willDisplay) { (_, _, _) in + footer.set(command: .willDisplay) { _, _, _ in willDisplay = true } - + + let section = OKTableViewSection(componentDisplayOption: .footer(component: footer)) + liaison.append(section: section) let view = UITableViewHeaderFooterView() liaison.tableView(tableView, willDisplayFooterView: view, forSection: 0) - + XCTAssertEqual(willDisplay, true) } - + func test_didEndDisplayingHeaderView_performsDidEndDisplayingHeaderViewSectionCommand() { - let section = TestTableViewSection() + + let header = TestTableViewSectionComponent() + var didEndDisplaying = false - - section.setHeader(command: .didEndDisplaying) { (_, _, _) in + header.set(command: .didEndDisplaying) { _, _, _ in didEndDisplaying = true } - + + let section = OKTableViewSection(componentDisplayOption: .header(component: header)) + liaison.append(section: section) let view = UITableViewHeaderFooterView() liaison.tableView(tableView, didEndDisplayingHeaderView: view, forSection: 0) - + XCTAssertEqual(didEndDisplaying, true) } - + func test_didEndDisplayingFooterView_performsDidEndDisplayingFooterViewSectionCommand() { - let section = TestTableViewSection() + + let footer = TestTableViewSectionComponent() + var didEndDisplaying = false - - section.setFooter(command: .didEndDisplaying) { (_, _, _) in + footer.set(command: .didEndDisplaying) { _, _, _ in didEndDisplaying = true } - + + let section = OKTableViewSection(componentDisplayOption: .footer(component: footer)) + liaison.append(section: section) let view = UITableViewHeaderFooterView() liaison.tableView(tableView, didEndDisplayingFooterView: view, forSection: 0) - + XCTAssertEqual(didEndDisplaying, true) } - + func test_prefetchRowsAtIndexPaths_performsPrefetchRowCommand() { let row = TestTableViewRow() var prefetch = false row.set(prefetchCommand: .prefetch) { _, _ in prefetch = true } - - let section = TestTableViewSection(rows: [row]) - + + let section = OKTableViewSection(rows: [row]) + liaison.append(section: section) liaison.tableView(tableView, prefetchRowsAt: [IndexPath(row: 0, section: 0)]) - + XCTAssertEqual(prefetch, true) } - + func test_cancelPrefetchingForRowsAtIndexPaths_performsPrefetchRowCommand() { let row = TestTableViewRow() var cancel = false row.set(prefetchCommand: .cancel) { _, _ in cancel = true } - - let section = TestTableViewSection(rows: [row]) - + + let section = OKTableViewSection(rows: [row]) + liaison.append(section: section) liaison.tableView(tableView, cancelPrefetchingForRowsAt: [IndexPath(row: 0, section: 0)]) - + XCTAssertEqual(cancel, true) } - + } diff --git a/Example/Tests/OKTableViewRow+UnitTests.swift b/Example/Tests/OKTableViewRow+UnitTests.swift index 27868e5..8425190 100644 --- a/Example/Tests/OKTableViewRow+UnitTests.swift +++ b/Example/Tests/OKTableViewRow+UnitTests.swift @@ -14,7 +14,7 @@ final class OKTableViewRow_UnitTests: XCTestCase { func test_registerCellTypeWithTableView_registersCellForRow() { let tableView = UITableView() - let row = TestTableViewRow.create() + let row = TestTableViewRow() row.registerCellType(with: tableView) @@ -24,7 +24,7 @@ final class OKTableViewRow_UnitTests: XCTestCase { } func test_setCommand_setsCommandClosure() { - let row = TestTableViewRow.create() + let row = TestTableViewRow() var set = false row.set(command: .configuration) { (_, _, _) in @@ -51,7 +51,7 @@ final class OKTableViewRow_UnitTests: XCTestCase { } func test_setHeight_setsHeightWithClosure() { - let row = TestTableViewRow.create() + let row = TestTableViewRow() row.set(height: .height) { (_) -> CGFloat in return 100 @@ -63,7 +63,7 @@ final class OKTableViewRow_UnitTests: XCTestCase { func test_setHeight_setsHeightWithValue() { let row = TestTableViewRow() - row.set(height: .height, value: 100) + row.set(height: .height, 100) XCTAssertEqual(row.height, 100) } @@ -77,8 +77,8 @@ final class OKTableViewRow_UnitTests: XCTestCase { func test_removeHeight_removesAPreviouslySetHeight() { let row = TestTableViewRow() - row.set(height: .height, value: 100) - row.set(height: .estimatedHeight, value: 100) + row.set(height: .height, 100) + row.set(height: .estimatedHeight, 100) row.remove(height: .height) row.remove(height: .estimatedHeight) @@ -159,7 +159,7 @@ final class OKTableViewRow_UnitTests: XCTestCase { func test_cellForTableViewAt_returnsConfiguredCellForRow() { - let row = TestTableViewRow.create() + let row = TestTableViewRow() let string = "Test" row.set(command: .configuration) { (cell, _, indexPath) in cell.accessibilityIdentifier = string @@ -173,24 +173,11 @@ final class OKTableViewRow_UnitTests: XCTestCase { XCTAssertEqual(cell.accessibilityIdentifier, string) } - func test_perform_performsCommands() { - let row = TestTableViewRow.create() - var configured = false - - row.set(command: .configuration) { (_, _, _) in - configured = true - } - - row.perform(command: .configuration, for: UITableViewCell(), at: IndexPath()) - - XCTAssertEqual(configured, true) - } - func test_perform_ignoresCommandPerformanceForIncorrectCellType() { let row = OKTableViewRow() var configured = false - row.set(command: .configuration) { (_, _, _) in + row.set(command: .configuration) { _, _, _ in configured = true } diff --git a/Example/Tests/OKTableViewSection+UnitTests.swift b/Example/Tests/OKTableViewSection+UnitTests.swift index 7efdeb6..c348dd0 100644 --- a/Example/Tests/OKTableViewSection+UnitTests.swift +++ b/Example/Tests/OKTableViewSection+UnitTests.swift @@ -11,129 +11,126 @@ import XCTest final class OKTableViewSection_UnitTests: XCTestCase { - func test_setHeader_setsHeaderCommandClosure() { - let section = TestTableViewSection() + func test_calculateHeight_setsHeightOfSupplementaryViewsWithClosure() { + + let header = TestTableViewSectionComponent() + let footer = TestTableViewSectionComponent() - var headerSet = false - section.setHeader(command: .configuration) { (_, _, _) in - headerSet = true + header.set(height: .height) { _ -> CGFloat in + return 100 } - section.perform(command: .configuration, - supplementaryView: .header, - for: UITableViewHeaderFooterView(), - in: 0) + footer.set(height: .height) { _ -> CGFloat in + return 50 + } - XCTAssertEqual(headerSet, true) + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: header, footerComponent: footer)) + + XCTAssertEqual(section.calculate(height: .height, for: .header), 100) + XCTAssertEqual(section.calculate(height: .height, for: .footer), 50) } - func test_removeHeader_removesHeaderCommandClosure() { - let section = TestTableViewSection() + func test_calculateEstimatedHeight_setsEstimatedHeightOfSupplementaryViewsWithClosure() { - var headerSet = false - section.setHeader(command: .configuration) { (_, _, _) in - headerSet = true - } - - section.removeHeader(command: .configuration) - section.perform(command: .configuration, - supplementaryView: .header, - for: UITableViewHeaderFooterView(), - in: 0) + let header = TestTableViewSectionComponent() + let footer = TestTableViewSectionComponent() - XCTAssertEqual(headerSet, false) - } - - func test_setFooter_setsFooterCommandClosure() { - let section = TestTableViewSection() + header.set(height: .estimatedHeight) { _ -> CGFloat in + return 100 + } - var footerSet = false - section.setFooter(command: .configuration) { (_, _, _) in - footerSet = true + footer.set(height: .estimatedHeight) { _ -> CGFloat in + return 50 } - section.perform(command: .configuration, - supplementaryView: .footer, - for: UITableViewHeaderFooterView(), - in: 0) + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: header, footerComponent: footer)) - XCTAssertEqual(footerSet, true) + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .header), 100) + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .footer), 50) } - func test_removeFooter_removesFooterCommandClosure() { - let section = TestTableViewSection() + func test_calculateHeight_setsHeightOfSupplementaryViewsWithValue() { - var footerSet = false - section.setFooter(command: .configuration) { (_, _, _) in - footerSet = true - } + let header = TestTableViewSectionComponent() + let footer = TestTableViewSectionComponent() + + header.set(height: .height, 100) + footer.set(height: .height, 50) - section.removeFooter(command: .configuration) - section.perform(command: .configuration, - supplementaryView: .header, - for: UITableViewHeaderFooterView(), - in: 0) + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: header, footerComponent: footer)) - XCTAssertEqual(footerSet, false) + XCTAssertEqual(section.calculate(height: .height, for: .header), 100) + XCTAssertEqual(section.calculate(height: .height, for: .footer), 50) } - func test_calculateHeight_setsHeightOfSupplementaryViewsWithClosure() { - let section = TestTableViewSection.create() + func test_calculateEstimatedHeight_setsEstimatedHeightOfSupplementaryViewsWithValue() { - section.setHeight(for: .header) { _ -> CGFloat in - return 100 - } + let header = TestTableViewSectionComponent() + let footer = TestTableViewSectionComponent() - section.setHeight(for: .footer) { _ -> CGFloat in - return 50 - } - - XCTAssertEqual(section.calculateHeight(for: .header), 100) - XCTAssertEqual(section.calculateHeight(for: .footer), 50) + header.set(height: .estimatedHeight, 100) + footer.set(height: .estimatedHeight, 50) + + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: header, footerComponent: footer)) + + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .header), 100) + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .footer), 50) } - func test_calculateHeight_setsHeightOfSupplementaryViewsWithValue() { - let section = TestTableViewSection.create() + func test_calculateHeight_returnsAutomaticDimensionForSelfSizingSupplementaryViews() { + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: TestTableViewSectionComponent(), + footerComponent: TestTableViewSectionComponent())) - section.setHeight(for: .header, value: 125) - section.setHeight(for: .footer, value: 75) - - XCTAssertEqual(section.calculateHeight(for: .header), 125) - XCTAssertEqual(section.calculateHeight(for: .footer), 75) + XCTAssertEqual(section.calculate(height: .height, for: .header), UITableViewAutomaticDimension) + XCTAssertEqual(section.calculate(height: .height, for: .footer), UITableViewAutomaticDimension) } - func test_calculateHeight_returnsAutomaticDimensionForSelfSizingSupplementaryViews() { - let section = TestTableViewSection.create() + func test_calculateHeight_returnsZeroForNonSetEstimatedSupplementaryViewsHeights() { + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: TestTableViewSectionComponent(), + footerComponent: TestTableViewSectionComponent())) - XCTAssertEqual(section.calculateHeight(for: .header), UITableViewAutomaticDimension) - XCTAssertEqual(section.calculateHeight(for: .footer), UITableViewAutomaticDimension) + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .header), 0) + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .footer), 0) } func test_calculateHeight_returnZeroForHeightOfNonDisplayedSupplementaryViews() { - let section = TestTableViewSection() + let section = OKTableViewSection() - let headerHeight = section.calculateHeight(for: .header) - let footerHeight = section.calculateHeight(for: .footer) + let headerHeight = section.calculate(height: .height, for: .header) + let footerHeight = section.calculate(height: .height, for: .footer) + let headerEstimatedHeight = section.calculate(height: .estimatedHeight, for: .header) + let footerEstimatedHeight = section.calculate(height: .estimatedHeight, for: .footer) XCTAssertEqual(headerHeight, .leastNormalMagnitude) XCTAssertEqual(footerHeight, .leastNormalMagnitude) + XCTAssertEqual(headerEstimatedHeight, .leastNormalMagnitude) + XCTAssertEqual(footerEstimatedHeight, .leastNormalMagnitude) } func test_removeHeight_removesHeightOfSupplementaryViews() { - let section = TestTableViewSection.create() + let header = TestTableViewSectionComponent() + let footer = TestTableViewSectionComponent() - section.setHeight(for: .header, value: 200) - section.setHeight(for: .footer, value: 200) + header.set(height: .height, 40) + footer.set(height: .height, 40) + header.set(height: .estimatedHeight, 40) + footer.set(height: .estimatedHeight, 40) - section.removeHeight(for: .header) - section.removeHeight(for: .footer) + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: header, footerComponent: footer)) - XCTAssertEqual(section.calculateHeight(for: .header), UITableViewAutomaticDimension) - XCTAssertEqual(section.calculateHeight(for: .footer), UITableViewAutomaticDimension) + header.remove(height: .height) + footer.remove(height: .height) + header.remove(height: .estimatedHeight) + footer.remove(height: .estimatedHeight) + + XCTAssertEqual(section.calculate(height: .height, for: .header), UITableViewAutomaticDimension) + XCTAssertEqual(section.calculate(height: .height, for: .footer), UITableViewAutomaticDimension) + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .header), 0) + XCTAssertEqual(section.calculate(height: .estimatedHeight, for: .footer), 0) } func test_appendRows_appendsNewRowsToSection() { - let section = TestTableViewSection() + let section = OKTableViewSection() let row1 = TestTableViewRow() let row2 = TestTableViewRow() @@ -145,7 +142,7 @@ final class OKTableViewSection_UnitTests: XCTestCase { } func test_appendRow_appendsRowToSection() { - let section = TestTableViewSection() + let section = OKTableViewSection() let row = TestTableViewRow() section.append(row: row) @@ -156,42 +153,49 @@ final class OKTableViewSection_UnitTests: XCTestCase { func test_headerForTableView_returnsConfiguredHeaderForSection() { let tableView = UITableView() - let section = TestTableViewSection.create() + let header = TestTableViewSectionComponent() let reuseIdentifier = String(describing: UITableViewHeaderFooterView.self) tableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: reuseIdentifier) let string = "Test" - section.setHeader(command: .configuration) { (header, _, section) in - header.accessibilityIdentifier = string + header.set(command: .configuration) { view, _, _ in + view.accessibilityIdentifier = string } - let header = section.view(supplementaryView: .header, for: tableView, in: 0) + let section = OKTableViewSection(componentDisplayOption: .header(component: header)) + + let headerView = section.view(componentView: .header, for: tableView, in: 0) - XCTAssertEqual(header?.accessibilityIdentifier, string) - XCTAssert(header is UITableViewHeaderFooterView) + XCTAssertEqual(headerView?.accessibilityIdentifier, string) + XCTAssert(headerView is UITableViewHeaderFooterView) } func test_footerForTableView_returnsConfiguredFooterForSection() { let tableView = UITableView() - let section = TestTableViewSection.create() - + let footer = TestTableViewSectionComponent() + let reuseIdentifier = String(describing: UITableViewHeaderFooterView.self) tableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: reuseIdentifier) let string = "Test" - section.setFooter(command: .configuration) { (footer, _, section) in - footer.accessibilityIdentifier = string + footer.set(command: .configuration) { view, _, _ in + view.accessibilityIdentifier = string } - let footer = section.view(supplementaryView: .footer, for: tableView, in: 0) + let section = OKTableViewSection(componentDisplayOption: .footer(component: footer)) + + let footerView = section.view(componentView: .footer, for: tableView, in: 0) - XCTAssertEqual(footer?.accessibilityIdentifier, string) - XCTAssert(footer is UITableViewHeaderFooterView) + XCTAssertEqual(footerView?.accessibilityIdentifier, string) + XCTAssert(footerView is UITableViewHeaderFooterView) } func test_perform_performsSectionCommands() { - let section = TestTableViewSection() + + let header = TestTableViewSectionComponent() + let footer = TestTableViewSectionComponent() + var headerConfiguration = "" var headerDidEndDisplaying = "" var headerWillDisplay = "" @@ -199,31 +203,32 @@ final class OKTableViewSection_UnitTests: XCTestCase { var footerDidEndDisplaying = "" var footerWillDisplay = "" - section.setHeader(command: .configuration) { (view, string, section) in + header.set(command: .configuration) { view, string, section in headerConfiguration = "Configured!" } - section.setHeader(command: .didEndDisplaying) { (view, string, section) in + header.set(command: .didEndDisplaying) { view, string, section in headerDidEndDisplaying = "DidEndDisplaying!" } - section.setHeader(command: .willDisplay) { (view, string, section) in + header.set(command: .willDisplay) { view, string, section in headerWillDisplay = "WillDisplay!" } - section.setFooter(command: .configuration) { (view, string, section) in + footer.set(command: .configuration) { view, string, section in footerConfiguration = "Configured!" } - section.setFooter(command: .didEndDisplaying) { (view, string, section) in + footer.set(command: .didEndDisplaying) { view, string, section in footerDidEndDisplaying = "DidEndDisplaying!" } - section.setFooter(command: .willDisplay) { (view, string, section) in + footer.set(command: .willDisplay) { view, string, section in footerWillDisplay = "WillDisplay!" } let view = UITableViewHeaderFooterView() + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: header, footerComponent: footer)) section.perform(command: .configuration, supplementaryView: .header, for: view, in: 0) section.perform(command: .configuration, supplementaryView: .footer, for: view, in: 0) @@ -241,20 +246,23 @@ final class OKTableViewSection_UnitTests: XCTestCase { } func test_perform_ignoresCommandPerformanceForIncorrectSupplementaryViewType() { - let section = TestTableViewSection() + let header = TestTableViewSectionComponent() + let footer = TestTableViewSectionComponent() + var headerConfiguration = "" var footerConfiguration = "" - section.setHeader(command: .configuration) { (view, string, section) in + header.set(command: .configuration) { view, string, section in headerConfiguration = "Configured!" } - section.setFooter(command: .configuration) { (view, string, section) in + footer.set(command: .configuration) { view, string, section in footerConfiguration = "Configured!" } let view = UIView() + let section = OKTableViewSection(componentDisplayOption: .both(headerComponent: header, footerComponent: footer)) section.perform(command: .configuration, supplementaryView: .header, for: view, in: 0) section.perform(command: .configuration, supplementaryView: .footer, for: view, in: 0) diff --git a/Example/Tests/OKTableViewSectionComponent+UnitTests.swift b/Example/Tests/OKTableViewSectionComponent+UnitTests.swift new file mode 100644 index 0000000..7d43817 --- /dev/null +++ b/Example/Tests/OKTableViewSectionComponent+UnitTests.swift @@ -0,0 +1,131 @@ +// +// OKTableViewSectionComponent+UnitTests.swift +// OKTableViewLiaison_Tests +// +// Created by Dylan Shine on 5/30/18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import XCTest +@testable import OKTableViewLiaison + +final class OKTableViewSectionComponent_UnitTests: XCTestCase { + + func test_registerViewTypeWithTableView_registersViewForSectionComponent() { + let tableView = UITableView() + + let component = TestTableViewSectionComponent() + component.registerViewType(with: tableView) + + let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: component.reuseIdentifier) + + XCTAssert(view != nil) + } + + func test_setCommand_setsCommandClosure() { + let component = TestTableViewSectionComponent() + + var set = false + component.set(command: .configuration) { _, _, _ in + set = true + } + + component.perform(command: .configuration, for: UITableViewHeaderFooterView(), in: 0) + + XCTAssertEqual(set, true) + } + + func test_removeCommand_removesCommand() { + let component = TestTableViewSectionComponent() + + var set = false + component.set(command: .configuration) { _, _, _ in + set = true + } + + component.remove(command: .configuration) + component.perform(command: .configuration, for: UITableViewHeaderFooterView(), in: 0) + + XCTAssertEqual(set, false) + } + + func test_setHeight_setsHeightWithClosure() { + let component = TestTableViewSectionComponent() + + component.set(height: .height) { _ -> CGFloat in + return 100 + } + + component.set(height: .estimatedHeight) { _ -> CGFloat in + return 150 + } + + XCTAssertEqual(component.height, 100) + XCTAssertEqual(component.estimatedHeight, 150) + } + + func test_setHeight_setsHeightWithValue() { + let component = TestTableViewSectionComponent() + + component.set(height: .height, 100) + component.set(height: .estimatedHeight, 105) + + XCTAssertEqual(component.height, 100) + XCTAssertEqual(component.estimatedHeight, 105) + } + + func test_setHeight_returnsAutomaticDimensionForSelfSizingView() { + let component = TestTableViewSectionComponent() + XCTAssertEqual(component.height, UITableViewAutomaticDimension) + XCTAssertEqual(component.estimatedHeight, 0) + } + + func test_removeHeight_removesAPreviouslySetHeight() { + let component = TestTableViewSectionComponent() + + component.set(height: .height, 100) + component.set(height: .estimatedHeight, 100) + component.remove(height: .height) + component.remove(height: .estimatedHeight) + + XCTAssertEqual(component.height, UITableViewAutomaticDimension) + XCTAssertEqual(component.estimatedHeight, 0) + } + + func test_estimatedHeight_estimatedHeightReturnsHeightIfHeightIsSetAndEstimatedHeightIsNot() { + let component = TestTableViewSectionComponent() + component.set(height: .height, 100) + + XCTAssertEqual(component.estimatedHeight, 100) + } + + func test_viewForTableViewInSection_returnsConfiguredViewForComponent() { + + let component = TestTableViewSectionComponent() + let string = "Test" + component.set(command: .configuration) { view, _, _ in + view.accessibilityIdentifier = string + } + + let tableView = UITableView() + component.registerViewType(with: tableView) + + let view = component.view(for: tableView, in: 0) + + XCTAssertEqual(view?.accessibilityIdentifier, string) + } + + func test_perform_ignoresCommandPerformanceForIncorrectViewType() { + let component = TestTableViewSectionComponent() + var configured = false + + component.set(command: .configuration) { _, _, _ in + configured = true + } + + component.perform(command: .configuration, for: UIView(), in: 0) + + XCTAssertEqual(configured, false) + } + +} diff --git a/Example/Tests/TestTableViewRow.swift b/Example/Tests/TestTableViewRow.swift index d35075d..fd9669f 100644 --- a/Example/Tests/TestTableViewRow.swift +++ b/Example/Tests/TestTableViewRow.swift @@ -9,16 +9,4 @@ import UIKit @testable import OKTableViewLiaison -final class TestTableViewRow: OKTableViewRow { - - static func create() -> TestTableViewRow { - - return TestTableViewRow((), - editingStyle: .none, - movable: false, - deleteConfirmationTitle: "Delete", - registrationType: TestTableViewRow.defaultClassRegistrationType) - - } - -} +final class TestTableViewRow: OKTableViewRow {} diff --git a/Example/Tests/TestTableViewSection.swift b/Example/Tests/TestTableViewSection.swift deleted file mode 100644 index 57a0245..0000000 --- a/Example/Tests/TestTableViewSection.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// TestTableViewSection.swift -// OKTableViewLiaisonTests -// -// Created by Dylan Shine on 3/23/18. -// Copyright © 2018 Dylan Shine. All rights reserved. -// - -import UIKit -@testable import OKTableViewLiaison - -final class TestTableViewSection: OKTableViewSection { - - static func create() -> TestTableViewSection { - - return TestTableViewSection((), - supplementaryViewDisplay: .both(headerRegistrationType: TestTableViewSection.defaultHeaderClassRegistrationType, - footerRegistrationType: TestTableViewSection.defaultFooterClassRegistrationType)) - - } - -} diff --git a/Example/Tests/TestTableViewSectionComponent.swift b/Example/Tests/TestTableViewSectionComponent.swift new file mode 100644 index 0000000..dfed0b3 --- /dev/null +++ b/Example/Tests/TestTableViewSectionComponent.swift @@ -0,0 +1,12 @@ +// +// TestTableViewSectionComponent.swift +// OKTableViewLiaison_Tests +// +// Created by Dylan Shine on 5/30/18. +// Copyright © 2018 CocoaPods. All rights reserved. +// + +import UIKit +@testable import OKTableViewLiaison + +final class TestTableViewSectionComponent: OKTableViewSectionComponent {} diff --git a/OKTableViewLiaison.podspec b/OKTableViewLiaison.podspec index ae3aee6..0f66e5a 100644 --- a/OKTableViewLiaison.podspec +++ b/OKTableViewLiaison.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'OKTableViewLiaison' - s.version = '1.4.0' + s.version = '2.0.0' s.license = 'MIT' s.summary = 'Framework to help you better manage UITableViews.' s.description = 'OKTableViewLiaison abstracts and simplifies UITableView construction and management.' diff --git a/OKTableViewLiaison/Classes/Enums/OKTableViewSectionCommand.swift b/OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentCommand.swift similarity index 69% rename from OKTableViewLiaison/Classes/Enums/OKTableViewSectionCommand.swift rename to OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentCommand.swift index 15ae6bc..1b22aae 100644 --- a/OKTableViewLiaison/Classes/Enums/OKTableViewSectionCommand.swift +++ b/OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentCommand.swift @@ -1,5 +1,5 @@ // -// OKTableViewSectionCommand.swift +// OKTableViewSectionComponentCommand.swift // OKTableViewLiaison // // Created by Dylan Shine on 3/22/18. @@ -8,7 +8,7 @@ import Foundation -public enum OKTableViewSectionCommand { +public enum OKTableViewSectionComponentCommand { case configuration case didEndDisplaying case willDisplay diff --git a/OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentDisplayOption.swift b/OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentDisplayOption.swift new file mode 100644 index 0000000..8f9e1d3 --- /dev/null +++ b/OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentDisplayOption.swift @@ -0,0 +1,44 @@ +// +// OKTableViewSectionSupplementaryViewDisplayOption.swift +// OKTableViewLiaison +// +// Created by Dylan Shine on 3/21/18. +// Copyright © 2018 Dylan Shine. All rights reserved. +// + +import UIKit + +public enum OKTableViewSectionComponentDisplayOption { + case none + case header(component: OKAnyTableViewSectionComponent) + case footer(component: OKAnyTableViewSectionComponent) + case both(headerComponent: OKAnyTableViewSectionComponent, + footerComponent: OKAnyTableViewSectionComponent) + + func registerComponentViews(with tableView: UITableView) { + [header, footer].forEach { $0?.registerViewType(with: tableView) } + } + + var header: OKAnyTableViewSectionComponent? { + switch self { + case .header(let header): + return header + case .both(let header, _): + return header + default: + return nil + } + } + + var footer: OKAnyTableViewSectionComponent? { + switch self { + case .footer(let footer): + return footer + case .both(_, let footer): + return footer + default: + return nil + } + } + +} diff --git a/OKTableViewLiaison/Classes/Enums/OKTableViewSectionSupplementaryView.swift b/OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentView.swift similarity index 82% rename from OKTableViewLiaison/Classes/Enums/OKTableViewSectionSupplementaryView.swift rename to OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentView.swift index 91fb736..7776947 100644 --- a/OKTableViewLiaison/Classes/Enums/OKTableViewSectionSupplementaryView.swift +++ b/OKTableViewLiaison/Classes/Enums/OKTableViewSectionComponentView.swift @@ -8,7 +8,7 @@ import Foundation -public enum OKTableViewSectionSupplementaryView { +public enum OKTableViewSectionComponentView { case header case footer } diff --git a/OKTableViewLiaison/Classes/Enums/OKTableViewSectionSupplementaryViewDisplayOption.swift b/OKTableViewLiaison/Classes/Enums/OKTableViewSectionSupplementaryViewDisplayOption.swift deleted file mode 100644 index 1d8b051..0000000 --- a/OKTableViewLiaison/Classes/Enums/OKTableViewSectionSupplementaryViewDisplayOption.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// OKTableViewSectionSupplementaryViewDisplayOption.swift -// OKTableViewLiaison -// -// Created by Dylan Shine on 3/21/18. -// Copyright © 2018 Dylan Shine. All rights reserved. -// - -import UIKit - -public enum OKTableViewSectionSupplementaryViewDisplayOption { - case none - case header(registrationType: OKTableViewRegistrationType) - case footer(registrationType: OKTableViewRegistrationType) - case both(headerRegistrationType: OKTableViewRegistrationType, footerRegistrationType: OKTableViewRegistrationType) - - public var headerRegistrationType: OKTableViewRegistrationType? { - switch self { - case .header(let registrationType), .both(let registrationType, _): - return registrationType - default: - return nil - } - } - - public var footerRegistrationType: OKTableViewRegistrationType? { - switch self { - case .footer(let registrationType), .both(_, let registrationType): - return registrationType - default: - return nil - } - } -} diff --git a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Pagination.swift b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Pagination.swift index 6c0ec44..c2f3777 100644 --- a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Pagination.swift +++ b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Pagination.swift @@ -64,7 +64,7 @@ extension OKTableViewLiaison { paginationDelegate?.paginationEnded(indexPath: firstNewIndexPath) } - func endPagination(sections: [OKAnyTableViewSection]) { + func endPagination(sections: [OKTableViewSection]) { hidePaginationSpinner(animated: sections.isEmpty) guard !sections.isEmpty else { return } let firstNewIndexPath = IndexPath(row: 0, section: self.sections.count) diff --git a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Row.swift b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Row.swift index 93e61c8..bcac358 100644 --- a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Row.swift +++ b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Row.swift @@ -57,7 +57,6 @@ public extension OKTableViewLiaison { if let cell = tableView?.cellForRow(at: indexPath) { row.perform(command: .insert, for: cell, at: indexPath) } - } @discardableResult diff --git a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Section.swift b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Section.swift index be305b2..c58519b 100644 --- a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Section.swift +++ b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+Section.swift @@ -9,7 +9,7 @@ import UIKit public extension OKTableViewLiaison { - public func append(sections: [OKAnyTableViewSection], animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { + public func append(sections: [OKTableViewSection], animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { if isShowingPaginationSpinner { endPagination(sections: sections) @@ -29,18 +29,33 @@ public extension OKTableViewLiaison { } - public func append(section: OKAnyTableViewSection, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { + public func append(section: OKTableViewSection, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { append(sections: [section], animation: animation, animated: animated) } - public func insert(section: OKAnyTableViewSection, at index: Int, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { + public func insert(sections: [OKTableViewSection], startingAt index: Int, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { + guard !sections.isEmpty else { return } + + let indexRange = (index...(index + sections.count)) + + zip(sections, indexRange) + .forEach { section, index in + self.sections.insert(section, at: index) + } + + let indexSet = IndexSet(integersIn: indexRange) + performTableViewUpdates(animated: animated) { + tableView?.insertSections(indexSet, with: animation) + } + } + + public func insert(section: OKTableViewSection, at index: Int, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { sections.insert(section, at: index) performTableViewUpdates(animated: animated) { tableView?.insertSections(IndexSet(integer: index), with: animation) } - } public func emptySection(at index: Int, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { @@ -64,7 +79,7 @@ public extension OKTableViewLiaison { } } - public func replaceSection(at index: Int, with section: OKAnyTableViewSection, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { + public func replaceSection(at index: Int, with section: OKTableViewSection, animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { sections.remove(at: index) sections.insert(section, at: index) @@ -91,7 +106,7 @@ public extension OKTableViewLiaison { } } - public func clearSections(replacedBy sections: [OKAnyTableViewSection] = [], + public func clearSections(replacedBy sections: [OKTableViewSection] = [], animation: UITableViewRowAnimation = .automatic, animated: Bool = true) { diff --git a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+UITableViewDelegate.swift b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+UITableViewDelegate.swift index 28aef5d..6de23c2 100644 --- a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+UITableViewDelegate.swift +++ b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison+UITableViewDelegate.swift @@ -20,7 +20,6 @@ extension OKTableViewLiaison: UITableViewDelegate { } public func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { - return perform(command: .willSelect, for: tableView, at: indexPath) } @@ -29,7 +28,6 @@ extension OKTableViewLiaison: UITableViewDelegate { } public func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? { - return perform(command: .willDeselect, for: tableView, at: indexPath) } @@ -69,11 +67,11 @@ extension OKTableViewLiaison: UITableViewDelegate { } public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - return sections.element(at: section)?.view(supplementaryView: .header, for: tableView, in: section) + return sections.element(at: section)?.view(componentView: .header, for: tableView, in: section) } public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { - return sections.element(at: section)?.view(supplementaryView: .footer, for: tableView, in: section) + return sections.element(at: section)?.view(componentView: .footer, for: tableView, in: section) } public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { @@ -105,11 +103,19 @@ extension OKTableViewLiaison: UITableViewDelegate { } public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - return sections.element(at: section)?.calculateHeight(for: .header) ?? UITableViewAutomaticDimension + return sections.element(at: section)?.calculate(height: .height, for: .header) ?? UITableViewAutomaticDimension } public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { - return sections.element(at: section)?.calculateHeight(for: .footer) ?? UITableViewAutomaticDimension + return sections.element(at: section)?.calculate(height: .height, for: .footer) ?? UITableViewAutomaticDimension + } + + public func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat { + return sections.element(at: section)?.calculate(height: .estimatedHeight, for: .header) ?? 0 + } + + public func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat { + return sections.element(at: section)?.calculate(height: .estimatedHeight, for: .footer) ?? 0 } public func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { diff --git a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison.swift b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison.swift index 349679a..a00e890 100644 --- a/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison.swift +++ b/OKTableViewLiaison/Classes/Liaison/OKTableViewLiaison.swift @@ -10,7 +10,7 @@ import UIKit final public class OKTableViewLiaison: NSObject { weak var tableView: UITableView? - public internal(set) var sections = [OKAnyTableViewSection]() { + public internal(set) var sections = [OKTableViewSection]() { didSet { didSetSections() } } @@ -18,7 +18,7 @@ final public class OKTableViewLiaison: NSObject { var waitingForPaginatedResults = false public weak var paginationDelegate: OKTableViewLiaisonPaginationDelegate? - public init(sections: [OKAnyTableViewSection] = [], + public init(sections: [OKTableViewSection] = [], paginationRow: OKAnyTableViewRow = OKPaginationTableViewRow()) { self.sections = sections self.paginationSection = OKPaginationTableViewSection(row: paginationRow) @@ -67,7 +67,7 @@ final public class OKTableViewLiaison: NSObject { tv.isEditing = !tv.isEditing } - public func section(for indexPath: IndexPath) -> OKAnyTableViewSection? { + public func section(for indexPath: IndexPath) -> OKTableViewSection? { return sections.element(at: indexPath.section) } diff --git a/OKTableViewLiaison/Classes/Rows/OKAnyTableViewRow.swift b/OKTableViewLiaison/Classes/Protocols/OKAnyTableViewRow.swift similarity index 100% rename from OKTableViewLiaison/Classes/Rows/OKAnyTableViewRow.swift rename to OKTableViewLiaison/Classes/Protocols/OKAnyTableViewRow.swift diff --git a/OKTableViewLiaison/Classes/Protocols/OKAnyTableViewSectionComponent.swift b/OKTableViewLiaison/Classes/Protocols/OKAnyTableViewSectionComponent.swift new file mode 100644 index 0000000..83cf7fe --- /dev/null +++ b/OKTableViewLiaison/Classes/Protocols/OKAnyTableViewSectionComponent.swift @@ -0,0 +1,15 @@ +// +// OKAnyTableViewSectionSupplementaryView.swift +// OKTableViewLiaison +// +// Created by Dylan Shine on 5/29/18. +// + +import UIKit + +public protocol OKAnyTableViewSectionComponent { + func calculate(height: OKTableViewHeightType) -> CGFloat + func registerViewType(with tableView: UITableView) + func perform(command: OKTableViewSectionComponentCommand, for view: UIView, in section: Int) + func view(for tableView: UITableView, in section: Int) -> UITableViewHeaderFooterView? +} diff --git a/OKTableViewLiaison/Classes/Rows/OKPaginationTableViewRow.swift b/OKTableViewLiaison/Classes/Rows/OKPaginationTableViewRow.swift index 5f02d71..52a759c 100644 --- a/OKTableViewLiaison/Classes/Rows/OKPaginationTableViewRow.swift +++ b/OKTableViewLiaison/Classes/Rows/OKPaginationTableViewRow.swift @@ -12,12 +12,12 @@ final public class OKPaginationTableViewRow: OKTableViewRow: OKAnyTableViewRow { // MARK: - Cell public func cell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell { - let cell = dequeueCell(with: tableView) + + guard let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier) as? Cell else { + fatalError("Failed to dequeue cell of type \(Cell.self).") + } + commands[.configuration]?(cell, model, indexPath) return cell } @@ -77,11 +81,11 @@ open class OKTableViewRow: OKAnyTableViewRow { commands[command] = nil } - public func set(height: OKTableViewHeightType, with closure: @escaping (Model) -> CGFloat) { + public func set(height: OKTableViewHeightType, _ closure: @escaping (Model) -> CGFloat) { heights[height] = closure } - public func set(height: OKTableViewHeightType, value: CGFloat) { + public func set(height: OKTableViewHeightType, _ value: CGFloat) { let closure: ((Model) -> CGFloat) = { _ -> CGFloat in return value } heights[height] = closure } @@ -116,11 +120,6 @@ open class OKTableViewRow: OKAnyTableViewRow { } // MARK: - Private - private func dequeueCell(with tableView: UITableView) -> Cell { - guard let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier) as? Cell else { fatalError("Failed to dequeue cell of type \(Cell.self).") } - - return cell - } private func calculate(height: OKTableViewHeightType) -> CGFloat { return heights[height]?(model) ?? UITableViewAutomaticDimension diff --git a/OKTableViewLiaison/Classes/Sections/OKAnyTableViewSection.swift b/OKTableViewLiaison/Classes/Sections/OKAnyTableViewSection.swift deleted file mode 100644 index 92b7090..0000000 --- a/OKTableViewLiaison/Classes/Sections/OKAnyTableViewSection.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// OKAnyTableViewSection.swift -// OKTableViewLiaison -// -// Created by Dylan Shine on 3/28/18. -// Copyright © 2018 Dylan Shine. All rights reserved. -// - -import UIKit - -open class OKAnyTableViewSection { - weak var tableView: UITableView? - public private(set) var rows: [OKAnyTableViewRow] - - init(rows: [OKAnyTableViewRow] = []) { - self.rows = rows - } - - public func perform(command: OKTableViewSectionCommand, supplementaryView: OKTableViewSectionSupplementaryView, for view: UIView, in section: Int) { - fatalError("OKAnyTableViewSection is an abstract class. Please use a valid subclass and override \(#function)") - } - - public func calculateHeight(for supplementaryView: OKTableViewSectionSupplementaryView) -> CGFloat { - fatalError("OKAnyTableViewSection is an abstract class. Please use a valid subclass and override \(#function)") - } - - public func view(supplementaryView: OKTableViewSectionSupplementaryView, for tableView: UITableView, in section: Int) -> UIView? { - fatalError("OKAnyTableViewSection is an abstract class. Please use a valid subclass and override \(#function)") - } - - // MARK: - Helpers - func rowIndexPaths(for section: Int) -> [IndexPath] { - return rows.enumerated().map { item, _ -> IndexPath in - return IndexPath(item: item, section: section) - } - } - - func append(row: OKAnyTableViewRow) { - registerCell(for: row) - rows.append(row) - } - - func append(rows: [OKAnyTableViewRow]) { - rows.forEach(registerCell(for:)) - self.rows.append(contentsOf: rows) - } - - @discardableResult - func deleteRow(at indexPath: IndexPath) -> OKAnyTableViewRow? { - guard rows.indices.contains(indexPath.item) else { return nil } - - return rows.remove(at: indexPath.item) - } - - func insert(row: OKAnyTableViewRow, at indexPath: IndexPath) { - guard rows.count >= indexPath.item else { return } - - registerCell(for: row) - rows.insert(row, at: indexPath.item) - } - - func swapRows(at source: IndexPath, to destination: IndexPath) { - guard rows.indices.contains(source.item) && rows.indices.contains(destination.item) else { return } - - rows.swapAt(source.item, destination.item) - } - - func removeAllRows() { - rows.removeAll() - } - - private func registerCell(for row: OKAnyTableViewRow) { - guard let tableView = tableView else { return } - - row.registerCellType(with: tableView) - } -} diff --git a/OKTableViewLiaison/Classes/Sections/OKPaginationTableViewSection.swift b/OKTableViewLiaison/Classes/Sections/OKPaginationTableViewSection.swift index 780b32e..454ec71 100644 --- a/OKTableViewLiaison/Classes/Sections/OKPaginationTableViewSection.swift +++ b/OKTableViewLiaison/Classes/Sections/OKPaginationTableViewSection.swift @@ -7,7 +7,7 @@ import UIKit -final class OKPaginationTableViewSection: OKPlainTableViewSection { +final class OKPaginationTableViewSection: OKTableViewSection { public init(row: OKAnyTableViewRow) { super.init(rows: [row]) diff --git a/OKTableViewLiaison/Classes/Sections/OKPlainTableViewSection.swift b/OKTableViewLiaison/Classes/Sections/OKPlainTableViewSection.swift deleted file mode 100644 index f498c2f..0000000 --- a/OKTableViewLiaison/Classes/Sections/OKPlainTableViewSection.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// OKPlainTableViewSection.swift -// OKTableViewLiaison -// -// Created by Dylan Shine on 3/30/18. -// - -import UIKit - -open class OKPlainTableViewSection: OKTableViewSection { - - public init(rows: [OKAnyTableViewRow] = []) { - super.init((), rows: rows, supplementaryViewDisplay: .none) - } - -} diff --git a/OKTableViewLiaison/Classes/Sections/OKTableViewSection.swift b/OKTableViewLiaison/Classes/Sections/OKTableViewSection.swift index 1dac7c2..8071826 100644 --- a/OKTableViewLiaison/Classes/Sections/OKTableViewSection.swift +++ b/OKTableViewLiaison/Classes/Sections/OKTableViewSection.swift @@ -8,68 +8,22 @@ import UIKit -open class OKTableViewSection: OKAnyTableViewSection { +open class OKTableViewSection { - public let model: Model - - override weak var tableView: UITableView? { + weak var tableView: UITableView? { didSet { registerRowCells() - registerHeaderFooterViews() + registerComponentViews() } } - private var headerCommands = [OKTableViewSectionCommand: (Header, Model, Int) -> Void]() - private var footerCommands = [OKTableViewSectionCommand: (Footer, Model, Int) -> Void]() - private let supplementaryViewDisplay: OKTableViewSectionSupplementaryViewDisplayOption - private var heights = [OKTableViewSectionSupplementaryView: (Model) -> CGFloat]() - - public init(_ model: Model, - rows: [OKAnyTableViewRow] = [], - supplementaryViewDisplay: OKTableViewSectionSupplementaryViewDisplayOption = .none) { - self.model = model - self.supplementaryViewDisplay = supplementaryViewDisplay - super.init(rows: rows) - } - - // MARK: - Configuration - public func setHeader(command: OKTableViewSectionCommand, with closure: @escaping (Header, Model, _ section: Int) -> Void) { - headerCommands[command] = closure - } - - public func removeHeader(command: OKTableViewSectionCommand) { - headerCommands[command] = nil - } - - public func setFooter(command: OKTableViewSectionCommand, with closure: @escaping (Footer, Model, _ section: Int) -> Void) { - footerCommands[command] = closure - } - - public func removeFooter(command: OKTableViewSectionCommand) { - footerCommands[command] = nil - } + public private(set) var rows: [OKAnyTableViewRow] + private let componentDisplayOption: OKTableViewSectionComponentDisplayOption - public func setHeight(for supplementaryView: OKTableViewSectionSupplementaryView, with closure: @escaping (Model) -> CGFloat) { - heights[supplementaryView] = closure - } - - public func setHeight(for supplementaryView: OKTableViewSectionSupplementaryView, value: CGFloat) { - let closure: (Model) -> CGFloat = { _ -> CGFloat in return value } - heights[supplementaryView] = closure - } - - public func removeHeight(for supplementaryView: OKTableViewSectionSupplementaryView) { - heights[supplementaryView] = nil - } - - override public func calculateHeight(for supplementaryView: OKTableViewSectionSupplementaryView) -> CGFloat { - - switch (supplementaryViewDisplay, supplementaryView) { - case (.both, _), (.header, .header), (.footer, .footer): - return heights[supplementaryView]?(model) ?? UITableViewAutomaticDimension - default: - return .leastNormalMagnitude - } + public init(rows: [OKAnyTableViewRow] = [], + componentDisplayOption: OKTableViewSectionComponentDisplayOption = .none) { + self.rows = rows + self.componentDisplayOption = componentDisplayOption } // MARK: - Type Registration @@ -81,109 +35,90 @@ open class OKTableViewSection UIView? { - switch supplementaryView { + public func view(componentView: OKTableViewSectionComponentView, for tableView: UITableView, in section: Int) -> UIView? { + switch componentView { case .header: - return header(for: tableView, in: section) + return componentDisplayOption.header?.view(for: tableView, in: section) case .footer: - return footer(for: tableView, in: section) + return componentDisplayOption.footer?.view(for: tableView, in: section) } } - private func header(for tableView: UITableView, in section: Int) -> UIView? { + func calculate(height: OKTableViewHeightType, for componentView: OKTableViewSectionComponentView) -> CGFloat { - guard let headerIdentifer = supplementaryViewDisplay.headerRegistrationType?.identifier else { - return nil - } - - guard let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerIdentifer) as? Header else { - return nil + switch (componentDisplayOption, componentView) { + case (.both(let header, _), .header): + return header.calculate(height: height) + case (.both(_, let footer), .footer): + return footer.calculate(height: height) + case (.header(let header), .header): + return header.calculate(height: height) + case (.footer(let footer), .footer): + return footer.calculate(height: height) + default: + return .leastNormalMagnitude } - - headerCommands[.configuration]?(header, model, section) - - return header } - private func footer(for tableView: UITableView, in section: Int) -> UIView? { - - guard let footerIdentifer = supplementaryViewDisplay.footerRegistrationType?.identifier else { - return nil - } - - guard let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerIdentifer) as? Footer else { - return nil + // MARK: - Helpers + func rowIndexPaths(for section: Int) -> [IndexPath] { + return rows.enumerated().map { item, _ -> IndexPath in + return IndexPath(item: item, section: section) } - - footerCommands[.configuration]?(footer, model, section) - - return footer } -} - -public extension OKTableViewSection where Model == Void { - convenience public init(rows: [OKAnyTableViewRow] = [], - supplementaryViewDisplay: OKTableViewSectionSupplementaryViewDisplayOption = .none) { - self.init((), - rows: rows, - supplementaryViewDisplay: supplementaryViewDisplay) + func append(row: OKAnyTableViewRow) { + registerCell(for: row) + rows.append(row) } -} - -// MARK: - OKTableViewRegistrationType -public extension OKTableViewSection { - public static var defaultHeaderClassRegistrationType: OKTableViewRegistrationType { - return .defaultClassRegistration(for: Header.self) + func append(rows: [OKAnyTableViewRow]) { + rows.forEach(registerCell(for:)) + self.rows.append(contentsOf: rows) } - public static var defaultHeaderNibRegistrationType: OKTableViewRegistrationType { - return .defaultNibRegistration(for: Header.self) + @discardableResult + func deleteRow(at indexPath: IndexPath) -> OKAnyTableViewRow? { + guard rows.indices.contains(indexPath.item) else { return nil } + + return rows.remove(at: indexPath.item) } - public static var defaultFooterClassRegistrationType: OKTableViewRegistrationType { - return .defaultClassRegistration(for: Footer.self) + func insert(row: OKAnyTableViewRow, at indexPath: IndexPath) { + guard rows.count >= indexPath.item else { return } + + registerCell(for: row) + rows.insert(row, at: indexPath.item) } - public static var defaultFooterNibRegistrationType: OKTableViewRegistrationType { - return .defaultNibRegistration(for: Footer.self) + func swapRows(at source: IndexPath, to destination: IndexPath) { + guard rows.indices.contains(source.item) && rows.indices.contains(destination.item) else { return } + + rows.swapAt(source.item, destination.item) + } + + func removeAllRows() { + rows.removeAll() } + private func registerCell(for row: OKAnyTableViewRow) { + guard let tableView = tableView else { return } + + row.registerCellType(with: tableView) + } } diff --git a/OKTableViewLiaison/Classes/Sections/OKTableViewSectionComponent.swift b/OKTableViewLiaison/Classes/Sections/OKTableViewSectionComponent.swift new file mode 100644 index 0000000..6d2ec65 --- /dev/null +++ b/OKTableViewLiaison/Classes/Sections/OKTableViewSectionComponent.swift @@ -0,0 +1,112 @@ +// +// OKTableViewSectionSupplementaryView.swift +// OKTableViewLiaison +// +// Created by Dylan Shine on 5/29/18. +// + +import Foundation + +open class OKTableViewSectionComponent: OKAnyTableViewSectionComponent { + + public init(_ model: Model, registrationType: OKTableViewRegistrationType = OKTableViewSectionComponent.defaultClassRegistrationType) { + self.model = model + self.registrationType = registrationType + } + + private let model: Model + public let registrationType: OKTableViewRegistrationType + + private var commands = [OKTableViewSectionComponentCommand: (View, Model, Int) -> Void]() + private var heights = [OKTableViewHeightType: (Model) -> CGFloat]() + + public func perform(command: OKTableViewSectionComponentCommand, for view: UIView, in section: Int) { + + guard let view = view as? View else { return } + + commands[command]?(view, model, section) + } + + public func set(command: OKTableViewSectionComponentCommand, with closure: @escaping (View, Model, Int) -> Void) { + commands[command] = closure + } + + public func remove(command: OKTableViewSectionComponentCommand) { + commands[command] = nil + } + + public func set(height: OKTableViewHeightType, _ closure: @escaping (Model) -> CGFloat) { + heights[height] = closure + } + + public func set(height: OKTableViewHeightType, _ value: CGFloat) { + let closure: ((Model) -> CGFloat) = { _ -> CGFloat in return value } + heights[height] = closure + } + + public func remove(height: OKTableViewHeightType) { + heights[height] = nil + } + + // MARK: - Computed Properties + public var height: CGFloat { + return calculate(height: .height) + } + + public var estimatedHeight: CGFloat { + return calculate(height: .estimatedHeight) + } + + public var reuseIdentifier: String { + return registrationType.identifier + } + + public func view(for tableView: UITableView, in section: Int) -> UITableViewHeaderFooterView? { + + guard let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: reuseIdentifier) as? View else { return nil } + + commands[.configuration]?(view, model, section) + + return view + } + + public func calculate(height: OKTableViewHeightType) -> CGFloat { + switch height { + case .height: + return heights[.height]?(model) ?? UITableViewAutomaticDimension + case .estimatedHeight: + return heights[.estimatedHeight]?(model) ?? heights[.height]?(model) ?? 0 + } + } + + public func registerViewType(with tableView: UITableView) { + switch registrationType { + case let .class(identifier): + tableView.register(View.self, forHeaderFooterViewReuseIdentifier: identifier) + case let .nib(nib, identifier): + tableView.register(nib, forHeaderFooterViewReuseIdentifier: identifier) + } + } + +} + +public extension OKTableViewSectionComponent where Model == Void { + + public convenience init(registrationType: OKTableViewRegistrationType = OKTableViewSectionComponent.defaultClassRegistrationType) { + + self.init((), + registrationType: registrationType) + } +} + +// MARK: - OKTableViewRegistrationType +public extension OKTableViewSectionComponent { + + public static var defaultClassRegistrationType: OKTableViewRegistrationType { + return .defaultClassRegistration(for: View.self) + } + + public static var defaultNibRegistrationType: OKTableViewRegistrationType { + return .defaultNibRegistration(for: View.self) + } +} diff --git a/README.md b/README.md index 0af8c61..bf08afb 100644 --- a/README.md +++ b/README.md @@ -64,63 +64,62 @@ In the event you would like to remove the tableView from the liaison, simply inv OKTableViewLiaison populates sections and rows using two main types: ### Section -`class OKTableViewSection` +`class OKTableViewSection` To create a section for our tableView, create an instance of `OKTableViewSection` and add it to the liaison. ```swift -let section = OKTableViewSection(model: "Section") +let section = OKTableViewSection() -let plainSection = OKPlainTableViewSection() - -let liaison = OKTableViewLiaison(sections: [section, plainSection]) +let liaison = OKTableViewLiaison(sections: [section]) ``` or ```swift -let section = OKTableViewSection(model: "Section") - -let plainSection = OKPlainTableViewSection() +let section = OKTableViewSection() -liaison.append(sections: [section, plainSection]) +liaison.append(sections: [section]) ``` -### Supplementary Views -To notify the liaison that your `OKTableViewSection` will display a header and/or footer view, you must provide an instance of `OKTableViewSectionSupplementaryViewDisplayOption` during initialization. +### Supplementary Section Views +To notify the liaison that your `OKTableViewSection` will display a header and/or footer view, you must provide an instance of `OKTableViewSectionComponentDisplayOption` during initialization. + +`OKTableViewSectionComponentDisplayOption` is an enumeration that notfies the liaison which supplementary views should be displayed for a given section. A header/footer view is represented by: + +`class OKTableViewSectionComponent` ```swift -let section = TableViewSection(model: HeaderModel(text: "Sample Model")", -supplementaryViewDisplay: .header(registrationType: OKTableViewSection.defaultHeaderClassRegistrationType)) +let header = OKTableViewSectionComponent(.dylan) +let section = OKTableViewSection(componentDisplayOption: .header(component: header)) ``` -If your section will only display a single supplementary view, the other supplementary view type provided in the generic declaration will be ignored. - -You can set a static height of a supplementary view by calling `setHeight` with either a CGFloat value or closure: +You can set a static height of a section component by using either a CGFloat value or closure: ```swift -section.setHeight(for: .header, value: 50) - -section.setHeight(for: .header) { model -> CGFloat in - return model.text == "Sample Model" ? 100 : 50 +header.set(height: .height, 55) + +header.set(height: .height) { user -> CGFloat in + return user.username == "dylan" ? 100 : 75 } + +header.set(height: .estimatedHeight, 125) ``` -In the event a height is not provided for a supplementary view, the liaison will assume the supplementary view is self sizing and return `UITableViewAutomaticDimension`. +In the event a height is not provided for a section component, the liaison will assume the supplementary view is self sizing and return a `.height` of `UITableViewAutomaticDimension`. Make sure you provide an `.estimatedHeight` to avoid layout complications. -The `OKTableViewSection` supplementary views can be customized using `func setHeader(command: OKTableViewSectionCommand, with closure: @escaping (Header, Model, _ section: Int) -> Void)` or `func setFooter(command: OKTableViewSectionCommand, with closure: @escaping (Footer, Model, _ section: Int) -> Void)` at all the following lifecycle events: +The `OKTableViewSectionComponent ` views can be customized using `func set(command: OKTableViewSectionComponentCommand, with closure: @escaping (View, Model, Int) -> Void)` at all the following lifecycle events: - configuration - didEndDisplaying - willDisplay ```swift -section.setHeader(command: .configuration) { header, model, section in - header.textLabel?.text = model.text - header.contentView.backgroundColor = .black +header.set(command: .configuration) { view, user, section in + view.textLabel?.text = user.username } - -section.setHeader(command: .willDisplay) { header, model, section in - print("Header: \(header) will display for Section: \(section) with Model: \(model)") + +header.set(command: .willDisplay) { view, user, section in + print("Header: \(view) will display for Section: \(section) with User: \(user)") } ``` @@ -131,14 +130,14 @@ To add a row for a section, create an instance of `OKTableViewRow` and pass it t ```swift let row = OKTableViewRow(model: RowModel(type: .small)) -let section = OKPlainTableViewSection(rows: [row]) +let section = OKTableViewSection(rows: [row]) liaison.append(section: section) ``` or ```swift let row = OKTableViewRow(model: RowModel(type: .small)) -let section = OKPlainTableViewSection() +let section = OKTableViewSection() liaison.append(section: section) liaison.append(row: row) ``` @@ -146,7 +145,9 @@ liaison.append(row: row) `OKTableViewRow` heights are similarly configured to `OKTableViewSection`: ```swift -row.set(height: .height, value: 300) +row.set(height: .height, 300) + +row.set(height: .estimatedHeight, 210) row.set(height: .height) { model -> CGFloat in switch model.type { @@ -213,7 +214,7 @@ row.set(prefetchCommand: .cancel) { model, indexPath in By default, `OKTableViewRow` is instantiated with `OKTableViewRow.defaultClassRegistrationType`. -`OKTableViewSection` supplementary view registration is encapsulated by its`OKTableViewSectionSupplementaryViewDisplayOption`. By default, `OKTableViewSection` `supplementaryViewDisplay` is instantiated with `.none`. +`OKTableViewSection` supplementary view registration is encapsulated by its`OKTableViewSectionComponentDisplayOption`. By default, `OKTableViewSection` `componentDisplayOption` is instantiated with `.none`. ### Pagination `OKTableViewLiaison` comes equipped to handle your pagination needs. To configure the liaison for pagination, simply set its `paginationDelegate` to an instance of `OKTableViewLiaisonPaginationDelegate`. @@ -245,8 +246,7 @@ final class PostTextTableViewRow: OKTableViewRow ```swift static func contentRow(with image: UIImage, width: CGFloat) -> AnyTableViewRow { - let row = OKTableViewRow(image, - registrationType: PostTextTableViewRow.defaultNibRegistrationType) + let row = OKTableViewRow(image) row.set(height: .height) { image -> CGFloat in let ratio = image.size.width / image.size.height