diff --git a/GridView/GridView.swift b/GridView/GridView.swift index 95970ce..e5348bb 100644 --- a/GridView/GridView.swift +++ b/GridView/GridView.swift @@ -14,6 +14,7 @@ import UIKit func gridView(_ gridView: GridView, cellForRowAt indexPath: IndexPath) -> GridViewCell @objc optional func numberOfColumns(in gridView: GridView) -> Int + @objc optional func numberOfColumnsPerPage(in gridView: GridView) -> Int } // MARK: - @@ -42,7 +43,7 @@ open class GridView: UIScrollView { override open class var layerClass : AnyClass { return AnimatedLayer.self } - + /// Set `false` if you don't need to loop of view. Default is `true`. open var isInfinitable = true /// Set the vertical and horizontal minimum scales. Default for x and y are 1. @@ -179,12 +180,11 @@ open class GridView: UIScrollView { let inset = UIEdgeInsets(top: -frame.minY, left: -frame.minX, bottom: -superview.bounds.height + frame.maxY, right: -superview.bounds.width + frame.maxX) super.scrollIndicatorInsets = inset + originScrollIndicatorInsets } - - stopScroll() - + columnRow.removeAll() currentInfo = ViewVisibleInfo() currentMatrix = makeMatrix(.all(currentMatrix)) + print("Matrix Reload = ", currentMatrix) performWithoutDelegation { contentSize = currentMatrix.contentSize @@ -196,7 +196,6 @@ open class GridView: UIScrollView { layoutToRemoveCells() case .layout(let type): - stopScroll() currentMatrix = makeMatrix(type) @@ -233,6 +232,41 @@ open class GridView: UIScrollView { layoutToRemoveCells() } + case .appendVertical: + if let superview = superview { + let inset = UIEdgeInsets(top: -frame.minY, left: -frame.minX, bottom: -superview.bounds.height + frame.maxY, right: -superview.bounds.width + frame.maxX) + super.scrollIndicatorInsets = inset + originScrollIndicatorInsets + } + + columnRow.removeAll() + currentInfo = ViewVisibleInfo() + currentMatrix = makeMatrix(.appendVertical(currentMatrix)) + print("Matrix Append Vertical = ", currentMatrix) + + performWithoutDelegation { + contentSize = currentMatrix.contentSize + } + contentOffset = currentMatrix.convert(lastValidityContentOffset, from: currentMatrix) + super.contentInset = currentMatrix.contentInset + + infiniteIfNeeded() + layoutToRemoveCells() + + case .appendHorizontal: + + columnRow.removeAll() + currentInfo = ViewVisibleInfo() + currentMatrix = makeMatrix(.appendHorizontal(currentMatrix)) + print("Matrix Append Horizontal = ", currentMatrix) + + performWithoutDelegation { + contentSize = currentMatrix.contentSize + } + contentOffset = currentMatrix.convert(lastValidityContentOffset, from: currentMatrix) + super.contentInset = currentMatrix.contentInset + + infiniteIfNeeded() + layoutToRemoveCells() } UIView.setAnimationsEnabled(areAnimationsEnabled) @@ -267,6 +301,10 @@ open class GridView: UIScrollView { } } + fileprivate func columnCountPerPage() -> Int { + return dataSource?.numberOfColumnsPerPage?(in: self) ?? 0 + } + fileprivate func rowCount(in column: Int) -> Int { if let rowCount = columnRow[column] { return rowCount @@ -407,6 +445,16 @@ extension GridView { layoutIfNeeded() } + public func appendTime() { + setNeedsLayout(.appendVertical) + layoutIfNeeded() + } + + public func appendChannel() { + setNeedsLayout(.appendHorizontal) + layoutIfNeeded() + } + public func invalidateContentSize() { setNeedsLayout(.layout(.rotating(currentMatrix))) } @@ -769,18 +817,14 @@ private extension GridView { (0.. 0 && columnHorizontals.count == count { + horizontals = columnHorizontals + } else { + horizontals = nil + } + + copyMatrix.appendVerticals(horizontals: horizontals, verticals: columnRowVerticals, viewFrame: frame, contentHeight: size.height, superviewSize: superview?.bounds.size, scale: currentScale) + + return copyMatrix + + case .appendHorizontal(let matrix): + + var copyMatrix = matrix + var size: CGSize = .zero + if let arrayHorizontal = copyMatrix.horizontals, + let lastItem = arrayHorizontal.last { + size.width = lastItem.maxX + } + + let count = columnCount() + var columnHorizontals: [Horizontal] = [] + var columnRowVerticals: [[Vertical?]] = [] + + (0.. 0 && columnHorizontals.count == count { + horizontals = columnHorizontals + } else { + horizontals = nil + } + + copyMatrix.appendHorizontals(horizontals: horizontals, verticals: columnRowVerticals, viewFrame: frame, contentHeight: size.height, superviewSize: superview?.bounds.size, scale: currentScale) + + return copyMatrix } } } diff --git a/GridView/NeedsLayout.swift b/GridView/NeedsLayout.swift index 19fa2bb..213eec0 100644 --- a/GridView/NeedsLayout.swift +++ b/GridView/NeedsLayout.swift @@ -7,17 +7,19 @@ // enum NeedsLayout: CustomDebugStringConvertible { - case none, reload, layout(LayoutType) + case none, reload, layout(LayoutType), appendVertical, appendHorizontal var debugDescription: String { switch self { case .none: return ".none" case .reload: return ".reload" case .layout(let type): return ".layout(\(type.debugDescription))" + case .appendVertical: return ".appendVertical" + case .appendHorizontal: return ".appendHorizontal" } } enum LayoutType: CustomDebugStringConvertible { - case all(ViewMatrix), horizontally(ViewMatrix), rotating(ViewMatrix), scaling(ViewMatrix), pinching(ViewMatrix) + case all(ViewMatrix), horizontally(ViewMatrix), rotating(ViewMatrix), scaling(ViewMatrix), pinching(ViewMatrix), appendVertical(ViewMatrix), appendHorizontal(ViewMatrix) var isScaling: Bool { switch self { case .scaling, .pinching: @@ -34,6 +36,8 @@ enum NeedsLayout: CustomDebugStringConvertible { case .rotating: return ".rotating" case .scaling: return ".scaling" case .pinching: return ".pinching" + case .appendVertical: return ".appendVertical" + case .appendHorizontal: return ".appendHorizontal" } } } @@ -70,6 +74,10 @@ extension NeedsLayout: Comparable { } case .none: return false + case .appendVertical: + return true + case .appendHorizontal: + return true } } } @@ -77,7 +85,7 @@ extension NeedsLayout: Comparable { extension NeedsLayout.LayoutType { var matrix: ViewMatrix { switch self { - case .all(let m), .horizontally(let m), .rotating(let m), .scaling(let m), .pinching(let m): + case .all(let m), .horizontally(let m), .rotating(let m), .scaling(let m), .pinching(let m), .appendVertical(let m), .appendHorizontal(let m): return m } } @@ -128,6 +136,10 @@ extension NeedsLayout.LayoutType: Comparable { } case .pinching: return false + case .appendVertical: + return true + case .appendHorizontal: + return true } } } diff --git a/GridView/ViewMatrix.swift b/GridView/ViewMatrix.swift index f6bfb57..fd22b01 100644 --- a/GridView/ViewMatrix.swift +++ b/GridView/ViewMatrix.swift @@ -10,18 +10,18 @@ import UIKit struct ViewMatrix: Countable { private let isInfinitable: Bool - private let horizontals: [Horizontal]? - private let verticals: [[Vertical?]] - private let visibleSize: CGSize? - private let viewFrame: CGRect + public var horizontals: [Horizontal]? + private var verticals: [[Vertical?]] + private var visibleSize: CGSize? + private var viewFrame: CGRect private let scale: Scale private let inset: UIEdgeInsets - private let aroundInset: AroundInsets - private let contentHeight: CGFloat + private var aroundInset: AroundInsets + private var contentHeight: CGFloat - let validityContentRect: CGRect - let contentSize: CGSize - let contentInset: UIEdgeInsets + var validityContentRect: CGRect + var contentSize: CGSize + var contentInset: UIEdgeInsets var count: Int { return verticals.count } @@ -279,6 +279,51 @@ struct ViewMatrix: Countable { } } +extension ViewMatrix { + mutating func appendVerticals(horizontals: [Horizontal]?, verticals: [[Vertical?]], viewFrame: CGRect, contentHeight: CGFloat, superviewSize: CGSize?, scale: Scale) { + + var contentSize: CGSize = .zero + contentSize.width = (horizontals?.last?.maxX ?? viewFrame.width * CGFloat(verticals.endIndex)) * scale.x + if contentHeight == 0 { + contentSize.height = viewFrame.height * CGFloat(verticals.first?.endIndex ?? 0) * scale.y + } else { + contentSize.height = contentHeight * scale.y + } + + self.verticals += verticals + self.viewFrame = viewFrame + self.visibleSize = superviewSize + self.contentHeight = contentHeight + + self.aroundInset = .zero + self.validityContentRect = CGRect(origin: .zero, size: contentSize) + self.contentSize = contentSize + } + + mutating func appendHorizontals(horizontals: [Horizontal]?, verticals: [[Vertical?]], viewFrame: CGRect, contentHeight: CGFloat, superviewSize: CGSize?, scale: Scale) { + + var contentSize: CGSize = .zero + contentSize.width = (horizontals?.last?.maxX ?? viewFrame.width * CGFloat(verticals.endIndex)) * scale.x + if contentHeight == 0 { + contentSize.height = viewFrame.height * CGFloat(verticals.first?.endIndex ?? 0) * scale.y + } else { + contentSize.height = contentHeight * scale.y + } + if var selfHorizontals = horizontals, let arrayHorizontals = horizontals { + selfHorizontals += arrayHorizontals + self.horizontals = selfHorizontals + } + self.verticals += verticals + self.viewFrame = viewFrame + self.visibleSize = superviewSize + self.contentHeight = contentHeight + + self.aroundInset = .zero + self.validityContentRect = CGRect(origin: .zero, size: contentSize) + self.contentSize = contentSize + } +} + #if DEBUG extension ViewMatrix { func debugVerticalsForColumn(_ column: Int) -> [Vertical?] {