diff --git a/LeadKit.xcodeproj/project.pbxproj b/LeadKit.xcodeproj/project.pbxproj index 8d6d6e61..869c9e22 100644 --- a/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit.xcodeproj/project.pbxproj @@ -384,6 +384,8 @@ 67E6C2371EBB32F5007842A6 /* SingleLoadCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6C2341EBB32F5007842A6 /* SingleLoadCursor.swift */; }; 67E6C2381EBB32F5007842A6 /* SingleLoadCursor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E6C2341EBB32F5007842A6 /* SingleLoadCursor.swift */; }; 82F8BB181F5DDED100C1061B /* Single+DeferredJust.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F8BB171F5DDED100C1061B /* Single+DeferredJust.swift */; }; + A658E54D1F8CD7790093527A /* TableRow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A658E54C1F8CD7790093527A /* TableRow+Extensions.swift */; }; + A658E54E1F8CD7790093527A /* TableRow+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A658E54C1F8CD7790093527A /* TableRow+Extensions.swift */; }; A6C9A4FA1F8BBCF2009311CC /* EmptyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6AF3B371F8B956F00CDB971 /* EmptyCell.swift */; }; A6C9A4FB1F8BBCF2009311CC /* EmptyCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6AF3B361F8B956E00CDB971 /* EmptyCellViewModel.swift */; }; A6C9A5041F8BC78F009311CC /* CellSeparatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E0DDEE1F8A6C57002CA74E /* CellSeparatorType.swift */; }; @@ -396,11 +398,11 @@ A6C9A5111F8BC79D009311CC /* Comparable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D10EAA1F8A9278003E69DD /* Comparable+Extensions.swift */; }; A6D10EAB1F8A9278003E69DD /* Comparable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D10EAA1F8A9278003E69DD /* Comparable+Extensions.swift */; }; A6E0DDDE1F8A696F002CA74E /* EmptyCellRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A71F8A654600C6308D /* EmptyCellRow.swift */; }; - A6E0DDDF1F8A696F002CA74E /* BaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A61F8A653600C6308D /* BaseCell.swift */; }; - A6E0DDE01F8A696F002CA74E /* BaseCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A51F8A653500C6308D /* BaseCellViewModel.swift */; }; + A6E0DDDF1F8A696F002CA74E /* SeparatorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A61F8A653600C6308D /* SeparatorCell.swift */; }; + A6E0DDE01F8A696F002CA74E /* SeparatorCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A51F8A653500C6308D /* SeparatorCellViewModel.swift */; }; A6E0DDE11F8A696F002CA74E /* AnyBaseTableRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A81F8A655600C6308D /* AnyBaseTableRow.swift */; }; - A6E0DDE31F8A696F002CA74E /* BaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A61F8A653600C6308D /* BaseCell.swift */; }; - A6E0DDE41F8A696F002CA74E /* BaseCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A51F8A653500C6308D /* BaseCellViewModel.swift */; }; + A6E0DDE31F8A696F002CA74E /* SeparatorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A61F8A653600C6308D /* SeparatorCell.swift */; }; + A6E0DDE41F8A696F002CA74E /* SeparatorCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A51F8A653500C6308D /* SeparatorCellViewModel.swift */; }; A6E0DDE51F8A696F002CA74E /* AnyBaseTableRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A66428A81F8A655600C6308D /* AnyBaseTableRow.swift */; }; A6E0DDEF1F8A6C57002CA74E /* CellSeparatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E0DDEE1F8A6C57002CA74E /* CellSeparatorType.swift */; }; A6E0DDF11F8A6C80002CA74E /* SeparatorConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6E0DDF01F8A6C80002CA74E /* SeparatorConfiguration.swift */; }; @@ -596,8 +598,9 @@ 887F99C5326BD220C2811BD6 /* Pods_LeadKit_LeadKit_iOS_Extensions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKit_LeadKit_iOS_Extensions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 95E457F1241D136396FC2420 /* Pods_LeadKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9966FB938D114F79F71AE037 /* Pods-LeadKit-LeadKit iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKit-LeadKit iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKit-LeadKit iOS/Pods-LeadKit-LeadKit iOS.release.xcconfig"; sourceTree = ""; }; - A66428A51F8A653500C6308D /* BaseCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCellViewModel.swift; sourceTree = ""; }; - A66428A61F8A653600C6308D /* BaseCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCell.swift; sourceTree = ""; }; + A658E54C1F8CD7790093527A /* TableRow+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TableRow+Extensions.swift"; sourceTree = ""; }; + A66428A51F8A653500C6308D /* SeparatorCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorCellViewModel.swift; sourceTree = ""; }; + A66428A61F8A653600C6308D /* SeparatorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorCell.swift; sourceTree = ""; }; A66428A71F8A654600C6308D /* EmptyCellRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyCellRow.swift; sourceTree = ""; }; A66428A81F8A655600C6308D /* AnyBaseTableRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyBaseTableRow.swift; sourceTree = ""; }; A6AF3B361F8B956E00CDB971 /* EmptyCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyCellViewModel.swift; sourceTree = ""; }; @@ -748,7 +751,7 @@ isa = PBXGroup; children = ( A6AF3B381F8B957400CDB971 /* AnyBaseTableRow */, - A66428A41F8A651700C6308D /* BaseCell */, + A66428A41F8A651700C6308D /* SeparatorCell */, A6C9A4F71F8BBC0F009311CC /* EmptyCell */, A6C9A4F81F8BBC27009311CC /* SpinnerView */, A6C9A4F91F8BBCCE009311CC /* XibView */, @@ -939,6 +942,7 @@ isa = PBXGroup; children = ( 671462011EB3396E00EAB194 /* TableDirector+Extensions.swift */, + A658E54C1F8CD7790093527A /* TableRow+Extensions.swift */, ); path = TableDirector; sourceTree = ""; @@ -1255,15 +1259,15 @@ path = Single; sourceTree = ""; }; - A66428A41F8A651700C6308D /* BaseCell */ = { + A66428A41F8A651700C6308D /* SeparatorCell */ = { isa = PBXGroup; children = ( - A66428A61F8A653600C6308D /* BaseCell.swift */, - A66428A51F8A653500C6308D /* BaseCellViewModel.swift */, + A66428A61F8A653600C6308D /* SeparatorCell.swift */, + A66428A51F8A653500C6308D /* SeparatorCellViewModel.swift */, A6E0DDEE1F8A6C57002CA74E /* CellSeparatorType.swift */, A6E0DDF01F8A6C80002CA74E /* SeparatorConfiguration.swift */, ); - path = BaseCell; + path = SeparatorCell; sourceTree = ""; }; A6AF3B381F8B957400CDB971 /* AnyBaseTableRow */ = { @@ -2114,6 +2118,7 @@ 671462D01EB3396E00EAB194 /* UIScrollView+Support.swift in Sources */, 671463901EB3396E00EAB194 /* TemplateDrawingOperation.swift in Sources */, 6714630C1EB3396E00EAB194 /* UIViewController+DefaultStoryboardIdentifier.swift in Sources */, + A658E54D1F8CD7790093527A /* TableRow+Extensions.swift in Sources */, 671462981EB3396E00EAB194 /* CGSize+Resize.swift in Sources */, 671462F81EB3396E00EAB194 /* UIView+DefaultReuseIdentifier.swift in Sources */, 67051ADB1EBC7C36008EADC0 /* SpinnerView.swift in Sources */, @@ -2130,7 +2135,7 @@ 671462E01EB3396E00EAB194 /* UICollectionView+CellRegistration.swift in Sources */, 671462601EB3396E00EAB194 /* PaginationTableViewWrapper.swift in Sources */, 671463281EB3396E00EAB194 /* BaseViewModel.swift in Sources */, - A6E0DDDF1F8A696F002CA74E /* BaseCell.swift in Sources */, + A6E0DDDF1F8A696F002CA74E /* SeparatorCell.swift in Sources */, 671462AC1EB3396E00EAB194 /* Observable+DeferredJust.swift in Sources */, 671463001EB3396E00EAB194 /* UIView+LoadFromNib.swift in Sources */, 6714627C1EB3396E00EAB194 /* AlamofireManager+Extensions.swift in Sources */, @@ -2168,7 +2173,7 @@ A6F32C081F6EBDAA00AC08EE /* String+LocalizedComponent.swift in Sources */, 671462881EB3396E00EAB194 /* CGFloat+Pixels.swift in Sources */, 671462941EB3396E00EAB194 /* CGSize+CGContextSize.swift in Sources */, - A6E0DDE01F8A696F002CA74E /* BaseCellViewModel.swift in Sources */, + A6E0DDE01F8A696F002CA74E /* SeparatorCellViewModel.swift in Sources */, 671463641EB3396E00EAB194 /* ViewHeightProtocol.swift in Sources */, 671462481EB3396E00EAB194 /* FixedPageCursor.swift in Sources */, 671462C81EB3396E00EAB194 /* String+Localization.swift in Sources */, @@ -2208,12 +2213,13 @@ A6C9A50E1F8BC799009311CC /* EmptyCellRow.swift in Sources */, A6C9A50C1F8BC799009311CC /* EmptyCell.swift in Sources */, 671463B81EB34B1E00EAB194 /* StubCursor.swift in Sources */, - A6E0DDE41F8A696F002CA74E /* BaseCellViewModel.swift in Sources */, + A658E54E1F8CD7790093527A /* TableRow+Extensions.swift in Sources */, + A6E0DDE41F8A696F002CA74E /* SeparatorCellViewModel.swift in Sources */, 671463BB1EB34B1E00EAB194 /* CursorTests.swift in Sources */, A6F32C101F6EBE9600AC08EE /* StringExtensionTests.swift in Sources */, 671463C11EB34B1E00EAB194 /* MappableUserDefaultsTests.swift in Sources */, 671463BE1EB34B1E00EAB194 /* LoadFromNibTests.swift in Sources */, - A6E0DDE31F8A696F002CA74E /* BaseCell.swift in Sources */, + A6E0DDE31F8A696F002CA74E /* SeparatorCell.swift in Sources */, A6C9A50F1F8BC79D009311CC /* Comparable+Extensions.swift in Sources */, 671463C41EB34B1E00EAB194 /* Post.swift in Sources */, A6E0DDE51F8A696F002CA74E /* AnyBaseTableRow.swift in Sources */, diff --git a/Sources/Classes/Views/AnyBaseTableRow/AnyBaseTableRow.swift b/Sources/Classes/Views/AnyBaseTableRow/AnyBaseTableRow.swift index 7e08e10d..4ac6d62d 100644 --- a/Sources/Classes/Views/AnyBaseTableRow/AnyBaseTableRow.swift +++ b/Sources/Classes/Views/AnyBaseTableRow/AnyBaseTableRow.swift @@ -32,7 +32,8 @@ private class AnyBaseTableRowHolder { } /// Class used to hold resolved TableRow -private final class AnyBaseTableRowBox: AnyBaseTableRowHolder where T: BaseCell, T.T: BaseCellViewModel { +private final class AnyBaseTableRowBox: AnyBaseTableRowHolder + where T: SeparatorCell, T.T: SeparatorCellViewModel { init(tableRow: TableRow) { super.init(tableRow: tableRow) @@ -47,7 +48,7 @@ public final class AnyBaseTableRow { fileprivate let anyTableRow: AnyBaseTableRowHolder /// Row `item`, that typed as BaseCellViewModel - public let viewModel: BaseCellViewModel + public let viewModel: SeparatorCellViewModel /// TableRow that typed to generic Row public var row: Row { @@ -56,7 +57,7 @@ public final class AnyBaseTableRow { /// Initialize AnyBaseTableRow with tableRow /// - parameter tableRow: TableRow which `item` conforms to BaseCellViewModel - public init(tableRow: TableRow) where T: BaseCell, T.T: BaseCellViewModel { + public init(tableRow: TableRow) where T: SeparatorCell, T.T: SeparatorCellViewModel { anyTableRow = AnyBaseTableRowBox(tableRow: tableRow) viewModel = tableRow.item } diff --git a/Sources/Classes/Views/EmptyCell/EmptyCell.swift b/Sources/Classes/Views/EmptyCell/EmptyCell.swift index c8ed04b6..be80560e 100644 --- a/Sources/Classes/Views/EmptyCell/EmptyCell.swift +++ b/Sources/Classes/Views/EmptyCell/EmptyCell.swift @@ -25,7 +25,7 @@ import TableKit /// Empty cell class. Do not use it directly. /// - see: `EmptyCellRow` -public final class EmptyCell: BaseCell, ConfigurableCell { +public final class EmptyCell: SeparatorCell, ConfigurableCell { public func configure(with viewModel: EmptyCellViewModel) { backgroundColor = .clear diff --git a/Sources/Classes/Views/EmptyCell/EmptyCellViewModel.swift b/Sources/Classes/Views/EmptyCell/EmptyCellViewModel.swift index d185804c..1c7d7281 100644 --- a/Sources/Classes/Views/EmptyCell/EmptyCellViewModel.swift +++ b/Sources/Classes/Views/EmptyCell/EmptyCellViewModel.swift @@ -23,7 +23,7 @@ import UIKit /// ViewModel for EmptyCell -public final class EmptyCellViewModel: BaseCellViewModel { +public final class EmptyCellViewModel: SeparatorCellViewModel { let color: UIColor let height: CGFloat diff --git a/Sources/Classes/Views/BaseCell/CellSeparatorType.swift b/Sources/Classes/Views/SeparatorCell/CellSeparatorType.swift similarity index 97% rename from Sources/Classes/Views/BaseCell/CellSeparatorType.swift rename to Sources/Classes/Views/SeparatorCell/CellSeparatorType.swift index 97c9b803..e85cadc5 100644 --- a/Sources/Classes/Views/BaseCell/CellSeparatorType.swift +++ b/Sources/Classes/Views/SeparatorCell/CellSeparatorType.swift @@ -42,7 +42,7 @@ public enum CellSeparatorType { switch self { case .top, .none: return true - default: + case .bottom, .full: return false } } @@ -52,7 +52,7 @@ public enum CellSeparatorType { switch self { case .bottom, .none: return true - default: + case .top, .full: return false } } diff --git a/Sources/Classes/Views/BaseCell/BaseCell.swift b/Sources/Classes/Views/SeparatorCell/SeparatorCell.swift similarity index 87% rename from Sources/Classes/Views/BaseCell/BaseCell.swift rename to Sources/Classes/Views/SeparatorCell/SeparatorCell.swift index 6f9b482c..ce8c04c7 100644 --- a/Sources/Classes/Views/BaseCell/BaseCell.swift +++ b/Sources/Classes/Views/SeparatorCell/SeparatorCell.swift @@ -24,16 +24,31 @@ import UIKit import TableKit /// Base cell that provides separator support -open class BaseCell: UITableViewCell { +/// Take note that separators are simple views, that located on contentView, +/// so if you hide that with another view that fully hide +/// you can use that method `moveSeparators(to:)` +open class SeparatorCell: UITableViewCell { // MARK: - Public /// Configure separator with viewModel /// - parameter viewModel: ViewModel of cell, that inherits from BaseCellViewModel - public func configureSeparator(with viewModel: BaseCellViewModel) { + public func configureSeparator(with viewModel: SeparatorCellViewModel) { configureInterface(with: viewModel) } + /// Use this function to place separator at hierarchy + /// - parameter front: Move separator to front or bottom in heirarchy + public func moveSeparators(to front: Bool) { + if front { + contentView.bringSubview(toFront: topView) + contentView.bringSubview(toFront: bottomView) + } else { + contentView.sendSubview(toBack: topView) + contentView.sendSubview(toBack: bottomView) + } + } + // MARK: - Private private var topView: UIView! @@ -85,7 +100,7 @@ open class BaseCell: UITableViewCell { super.updateConstraints() } - private func configureInterface(with viewModel: BaseCellViewModel?) { + private func configureInterface(with viewModel: SeparatorCellViewModel?) { guard let viewModel = viewModel else { return } @@ -103,15 +118,6 @@ open class BaseCell: UITableViewCell { } private func configureLineViews() { - let requiredValues: [Any?] = [ - topView, bottomView, - topViewLeftConstraint, topViewRightConstraint, topViewTopConstraint, - bottomViewLeftConstraint, bottomViewRightConstraint, bottomViewBottomConstraint] - - if !requiredValues.contains(where: { $0 == nil }) { - return - } - topView = createSeparatorView() bottomView = createSeparatorView() @@ -124,7 +130,6 @@ open class BaseCell: UITableViewCell { view.backgroundColor = .black view.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(view) -// contentView.bringSubview(toFront: view) return view } @@ -158,13 +163,3 @@ open class BaseCell: UITableViewCell { } } - -public extension TableRow where CellType.T: BaseCellViewModel { - - @discardableResult - func with(separatorType: CellSeparatorType) -> Self { - item.with(separatorType: separatorType) - return self - } - -} diff --git a/Sources/Classes/Views/BaseCell/BaseCellViewModel.swift b/Sources/Classes/Views/SeparatorCell/SeparatorCellViewModel.swift similarity index 97% rename from Sources/Classes/Views/BaseCell/BaseCellViewModel.swift rename to Sources/Classes/Views/SeparatorCell/SeparatorCellViewModel.swift index 28d083a0..40062507 100644 --- a/Sources/Classes/Views/BaseCell/BaseCellViewModel.swift +++ b/Sources/Classes/Views/SeparatorCell/SeparatorCellViewModel.swift @@ -23,7 +23,7 @@ import UIKit /// By default this class does not provide any separators -open class BaseCellViewModel { +open class SeparatorCellViewModel { internal var separatorType = CellSeparatorType.none @@ -51,7 +51,7 @@ open class BaseCellViewModel { case .full(let top, let bottom): topSeparatorConfiguration = top bottomSeparatorConfiguration = bottom - default: + case .none: topSeparatorConfiguration = nil bottomSeparatorConfiguration = nil } diff --git a/Sources/Classes/Views/BaseCell/SeparatorConfiguration.swift b/Sources/Classes/Views/SeparatorCell/SeparatorConfiguration.swift similarity index 100% rename from Sources/Classes/Views/BaseCell/SeparatorConfiguration.swift rename to Sources/Classes/Views/SeparatorCell/SeparatorConfiguration.swift diff --git a/Sources/Extensions/Comparable/Comparable+Extensions.swift b/Sources/Extensions/Comparable/Comparable+Extensions.swift index 9589de93..4c49811e 100644 --- a/Sources/Extensions/Comparable/Comparable+Extensions.swift +++ b/Sources/Extensions/Comparable/Comparable+Extensions.swift @@ -24,6 +24,9 @@ import Foundation public extension Comparable { + /// Use this function to restrict comparable with lower and upper values + /// - parameter bounds: Lower and uppper bounds tuple + /// - returns: Current value if it fits range, otherwise lower if value is too small or upper if value is too big func `in`(bounds: (lower: Self, upper: Self)) -> Self { return min(max(bounds.lower, self), bounds.upper) } diff --git a/Sources/Extensions/TableDirector/TableRow+Extensions.swift b/Sources/Extensions/TableDirector/TableRow+Extensions.swift new file mode 100644 index 00000000..aafee926 --- /dev/null +++ b/Sources/Extensions/TableDirector/TableRow+Extensions.swift @@ -0,0 +1,33 @@ +// +// Copyright (c) 2017 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import TableKit + +public extension TableRow where CellType.T: SeparatorCellViewModel { + + @discardableResult + func with(separatorType: CellSeparatorType) -> Self { + item.with(separatorType: separatorType) + return self + } + +}