Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class based size source #107

Merged
merged 3 commits into from
Oct 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CollectionKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

/* Begin PBXBuildFile section */
0E3258451F5E23B000D455F8 /* FlowLayoutSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3258441F5E23B000D455F8 /* FlowLayoutSpec.swift */; };
A3066AAD2176997900467E3C /* BasicProvider+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3066AAC2176997800467E3C /* BasicProvider+Convenience.swift */; };
A3066AAF2176997F00467E3C /* ComposedHeaderProvider+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3066AAE2176997F00467E3C /* ComposedHeaderProvider+Convenience.swift */; };
A3299F342064ED690075A137 /* VisibleFrameInsetLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3299F332064ED690075A137 /* VisibleFrameInsetLayout.swift */; };
A363C56520C7EA44009A885F /* ComposedViewSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = A363C56420C7EA44009A885F /* ComposedViewSource.swift */; };
A363C56620C7EA66009A885F /* AnyViewSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = A363C56220C7EA2E009A885F /* AnyViewSource.swift */; };
Expand Down Expand Up @@ -74,6 +76,8 @@
0E3258441F5E23B000D455F8 /* FlowLayoutSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlowLayoutSpec.swift; sourceTree = "<group>"; };
18407FD826F3703406A838D4 /* Pods_CollectionKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CollectionKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
571F2E4FA7747B7E5CAC5A2D /* Pods-CollectionKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CollectionKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CollectionKitTests/Pods-CollectionKitTests.debug.xcconfig"; sourceTree = "<group>"; };
A3066AAC2176997800467E3C /* BasicProvider+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BasicProvider+Convenience.swift"; sourceTree = "<group>"; };
A3066AAE2176997F00467E3C /* ComposedHeaderProvider+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ComposedHeaderProvider+Convenience.swift"; sourceTree = "<group>"; };
A3299F332064ED690075A137 /* VisibleFrameInsetLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleFrameInsetLayout.swift; sourceTree = "<group>"; };
A32B59BD213C063400DED8B4 /* CollectionKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CollectionKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A32B59BE213C063400DED8B4 /* CollectionKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CollectionKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -279,8 +283,10 @@
isa = PBXGroup;
children = (
B148237A1F1E87F60007A7E2 /* BasicProvider.swift */,
A3066AAC2176997800467E3C /* BasicProvider+Convenience.swift */,
B1E861F81F21520200621BA0 /* ComposedProvider.swift */,
A363C56D20CBD55B009A885F /* ComposedHeaderProvider.swift */,
A3066AAE2176997F00467E3C /* ComposedHeaderProvider+Convenience.swift */,
A363C56B20CACA89009A885F /* FlattenedProvider.swift */,
B144CE091F437A6B0073CF4E /* EmptyCollectionProvider.swift */,
);
Expand Down Expand Up @@ -526,6 +532,7 @@
B1688A2D1F25632900C229BD /* SpaceProvider.swift in Sources */,
A363C56520C7EA44009A885F /* ComposedViewSource.swift in Sources */,
B1B7B0611E7DAD2700F2483E /* Util.swift in Sources */,
A3066AAD2176997900467E3C /* BasicProvider+Convenience.swift in Sources */,
B144CE0A1F437A6B0073CF4E /* EmptyCollectionProvider.swift in Sources */,
B144CE061F437A1D0073CF4E /* RowLayout.swift in Sources */,
B19D64C91F23DCA800D02FDB /* CollectionReuseViewManager.swift in Sources */,
Expand All @@ -546,6 +553,7 @@
B1B7B05F1E7DAD2700F2483E /* CollectionView.swift in Sources */,
B157E51A1F6719F0008AEF83 /* SimpleLayout.swift in Sources */,
A3299F342064ED690075A137 /* VisibleFrameInsetLayout.swift in Sources */,
A3066AAF2176997F00467E3C /* ComposedHeaderProvider+Convenience.swift in Sources */,
B1E861F41F21517400621BA0 /* DataSource.swift in Sources */,
A3C76C1F20D10817003082BF /* LayoutableProvider.swift in Sources */,
B157E5181F66FEE5008AEF83 /* OverlayLayout.swift in Sources */,
Expand Down
16 changes: 8 additions & 8 deletions CollectionKitTests/CollectionViewSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ class CollectionViewSpec: QuickSpec {
dataSource = ArrayDataSource(data: [1, 2, 3, 4])
provider = BasicProvider(
dataSource: dataSource,
viewSource: ClosureViewSource(viewUpdater: { (label: UILabel, data: Int, index: Int) in
viewSource: { (label: UILabel, data: Int, index: Int) in
label.backgroundColor = .red
label.textAlignment = .center
label.text = "\(data)"
}),
},
sizeSource: { (index: Int, data: Int, collectionSize: CGSize) -> CGSize in
return CGSize(width: 50, height: 50)
}
Expand Down Expand Up @@ -228,10 +228,10 @@ class CollectionViewSpec: QuickSpec {
expect((collectionView.cell(at: 1) as! UILabel).text) == "2"

provider = BasicProvider(
dataSource: ArrayDataSource(data: [0, 0, 0, 0]),
viewSource: ClosureViewSource(viewUpdater: { (label: UILabel, data: Int, index: Int) in
dataSource: [0, 0, 0, 0],
viewSource: { (label: UILabel, data: Int, index: Int) in
label.text = "\(data)"
}),
},
sizeSource: { (index: Int, data: Int, collectionSize: CGSize) -> CGSize in
return CGSize(width: 50, height: 50)
}
Expand Down Expand Up @@ -264,10 +264,10 @@ class CollectionViewSpec: QuickSpec {
it("handles tap") {
var lastTappedIndex: Int = -1
provider = BasicProvider(
dataSource: ArrayDataSource(data: [0, 1, 2, 3]),
viewSource: ClosureViewSource(viewUpdater: { (label: UILabel, data: Int, index: Int) in
dataSource: [0, 1, 2, 3],
viewSource: { (label: UILabel, data: Int, index: Int) in
label.text = "\(data)"
}),
},
sizeSource: { (index: Int, data: Int, collectionSize: CGSize) -> CGSize in
return CGSize(width: 50, height: 50)
},
Expand Down
10 changes: 5 additions & 5 deletions CollectionKitTests/ComposedProviderSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ class ComposedProviderSpec: QuickSpec {

expect(collectionView.subviews[0].frame.origin) == CGPoint.zero
expect(collectionView.subviews[1].frame.origin) == CGPoint(x: 50, y: 0)
provider1.sizeSource = { _, _, _ in
provider1.sizeSource = ClosureSizeSource(sizeSource: { _, _, _ in
return CGSize(width: 30, height: 30)
}
})
collectionView.layoutIfNeeded()
expect(collectionView.reloadCount) == 1
expect(collectionView.subviews[0].frame.origin) == CGPoint.zero
Expand Down Expand Up @@ -160,11 +160,11 @@ class ComposedProviderSpec: QuickSpec {
let provider2 = SimpleTestProvider(data: ["a", "b"])

let tapProvider = BasicProvider(
dataSource: ArrayDataSource(data: [11, 12]),
viewSource: ClosureViewSource(viewUpdater: {
dataSource: [11, 12],
viewSource: {
(label: UILabel, data: Int, index: Int) in
label.text = "\(data)"
}),
},
sizeSource: { (index: Int, data: Int, collectionSize: CGSize) -> CGSize in
return CGSize(width: 50, height: 50)
},
Expand Down
4 changes: 2 additions & 2 deletions CollectionKitTests/TestUils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ class SimpleTestProvider<Data>: BasicProvider<Data, UILabel> {
label.textAlignment = .center
label.text = "\(data)"
}),
sizeSource: { (index: Int, data: Data, collectionSize: CGSize) -> CGSize in
sizeSource: ClosureSizeSource(sizeSource: { (index: Int, data: Data, collectionSize: CGSize) -> CGSize in
return CGSize(width: 50, height: 50)
}
})
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AnimatorExampleViewController: CollectionViewController {
let visibleFrameInsets = UIEdgeInsets(top: 0, left: -100, bottom: 0, right: -100)

let imageProvider = BasicProvider(
dataSource: ArrayDataSource(data: testImages),
dataSource: testImages,
viewSource: ClosureViewSource(viewGenerator: { (data, index) -> UIImageView in
let view = UIImageView()
view.layer.cornerRadius = 5
Expand All @@ -33,7 +33,7 @@ class AnimatorExampleViewController: CollectionViewController {
}, viewUpdater: { (view: UIImageView, data: UIImage, at: Int) in
view.image = data
}),
sizeSource: imageSizeProvider,
sizeSource: UIImageSizeSource(),
layout: WaterfallLayout(columns: 2, spacing: 10).transposed().inset(by: bodyInset).insetVisibleFrame(by: visibleFrameInsets),
animator: animators[0].1
)
Expand All @@ -44,12 +44,12 @@ class AnimatorExampleViewController: CollectionViewController {
buttonsCollectionView.showsHorizontalScrollIndicator = false

let buttonsProvider = BasicProvider(
dataSource: ArrayDataSource(data: animators),
viewSource: ClosureViewSource(viewUpdater: { (view: SelectionButton, data: (String, Animator), at: Int) in
dataSource: animators,
viewSource: { (view: SelectionButton, data: (String, Animator), at: Int) in
view.label.text = data.0
view.label.textColor = imageProvider.animator === data.1 ? .white : .black
view.backgroundColor = imageProvider.animator === data.1 ? .lightGray : .white
}),
},
sizeSource: { _, data, maxSize in
return CGSize(width: data.0.width(withConstraintedHeight: maxSize.height, font: UIFont.systemFont(ofSize:18)) + 20, height: maxSize.height)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ class ArticleExampleViewController: CollectionViewController {

collectionView.contentInset = UIEdgeInsets(top: 20, left: 16, bottom: 20, right: 16)
provider = BasicProvider(
dataSource: ArrayDataSource(data: articles),
viewSource: ClosureViewSource(viewUpdater: {
(view: ArticleView, data: ArticleData, at: Int) in
dataSource: articles,
viewSource: { (view: ArticleView, data: ArticleData, at: Int) in
view.populate(article: data)
}),
},
sizeSource: { (_, view, size) -> CGSize in
return CGSize(width: size.width, height: 200)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ class GridViewController: CollectionViewController {
collectionView.contentInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
provider = BasicProvider(
dataSource: dataSource,
viewSource: ClosureViewSource(viewUpdater: { (view: SquareView, data: Int, index: Int) in
viewSource: { (view: SquareView, data: Int, index: Int) in
view.backgroundColor = UIColor(hue: CGFloat(index) / CGFloat(kGridSize.width * kGridSize.height),
saturation: 0.68, brightness: 0.98, alpha: 1)
view.text = "\(data)"
}),
},
layout: layout,
animator: WobbleAnimator()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@ class HeaderExampleViewController: CollectionViewController {
}

let provider = ComposedHeaderProvider(
headerViewSource: ClosureViewSource(
viewUpdater: { (view: UILabel, data, index) in
headerViewSource: { (view: UILabel, data, index) in
view.backgroundColor = UIColor.darkGray
view.textColor = .white
view.textAlignment = .center
view.text = "Header \(data.index)"
}),
},
headerSizeSource: { (index, data, maxSize) -> CGSize in
return CGSize(width: maxSize.width, height: 40)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,6 @@
import UIKit
import CollectionKit

func imageSizeProvider(at: Int, data: UIImage, collectionSize: CGSize) -> CGSize {
var imageSize = data.size
if imageSize.width > collectionSize.width {
imageSize.height /= imageSize.width/collectionSize.width
imageSize.width = collectionSize.width
}
if imageSize.height > collectionSize.height {
imageSize.width /= imageSize.height/collectionSize.height
imageSize.height = collectionSize.height
}
return imageSize
}

class HorizontalGalleryViewController: CollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
Expand All @@ -30,7 +17,7 @@ class HorizontalGalleryViewController: CollectionViewController {

let visibleFrameInsets = UIEdgeInsets(top: 0, left: -100, bottom: 0, right: -100)
provider = BasicProvider(
dataSource: ArrayDataSource(data: testImages),
dataSource: testImages,
viewSource: ClosureViewSource(viewGenerator: { (data, index) -> UIImageView in
let view = UIImageView()
view.layer.cornerRadius = 5
Expand All @@ -39,7 +26,7 @@ class HorizontalGalleryViewController: CollectionViewController {
}, viewUpdater: { (view: UIImageView, data: UIImage, at: Int) in
view.image = data
}),
sizeSource: imageSizeProvider,
sizeSource: UIImageSizeSource(),
layout: WaterfallLayout(columns: 2, spacing: 10).transposed().insetVisibleFrame(by: visibleFrameInsets),
animator: WobbleAnimator()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,13 @@ class ReloadAnimationViewController: CollectionViewController {

provider = BasicProvider(
dataSource: dataSource,
viewSource: ClosureViewSource(viewUpdater: { (view: SquareView, data: Int, index: Int) in
viewSource: { (view: SquareView, data: Int, index: Int) in
view.backgroundColor = UIColor(hue: CGFloat(data) / 30,
saturation: 0.68,
brightness: 0.98,
alpha: 1)
view.text = "\(data)"
}),
},
sizeSource: { (index, data, _) in
return CGSize(width: 80, height: 80)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class ReloadDataViewController: CollectionViewController {

provider = BasicProvider(
dataSource: dataSource,
viewSource: ClosureViewSource(viewUpdater: { (view: SquareView, data: Int, index: Int) in
viewSource: { (view: SquareView, data: Int, index: Int) in
view.backgroundColor = UIColor(hue: CGFloat(data) / 30,
saturation: 0.68,
brightness: 0.98,
alpha: 1)
view.text = "\(data)"
}),
},
sizeSource: { (index, data, _) in
return CGSize(width: 80, height: data % 3 == 0 ? 120 : 80)
},
Expand Down
7 changes: 3 additions & 4 deletions Examples/CollectionKitExamples/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ class ViewController: CollectionViewController {
super.viewDidLoad()

let examplesSection = BasicProvider(
dataSource: ArrayDataSource(data: examples),
viewSource: ClosureViewSource(viewUpdater: {
(view: ExampleView, data: (String, UIViewController.Type), at: Int) in
dataSource: examples,
viewSource: { (view: ExampleView, data: (String, UIViewController.Type), at: Int) in
view.populate(title: data.0, contentViewControllerType: data.1)
}),
},
sizeSource: { (_, _, size) -> CGSize in
return CGSize(width: size.width, height: max(360, UIScreen.main.bounds.height * 0.7))
},
Expand Down
2 changes: 1 addition & 1 deletion Sources/Layout/LayoutContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ public protocol LayoutContext {
var numberOfItems: Int { get }
func data(at: Int) -> Any
func identifier(at: Int) -> String
func size(at: Int, collectionSize: CGSize) -> CGSize
func size(at index: Int, collectionSize: CGSize) -> CGSize
}
6 changes: 3 additions & 3 deletions Sources/Other/Deprecated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extension BasicProvider {
dataProvider: DataSource<Data>,
viewProvider: ViewSource<Data, View>,
layout: Layout = FlowLayout(),
sizeProvider: @escaping SizeSource<Data> = defaultSizeSource,
sizeProvider: SizeSource<Data> = SizeSource<Data>(),
presenter: Animator? = nil,
willReloadHandler: (() -> Void)? = nil,
didReloadHandler: (() -> Void)? = nil,
Expand All @@ -98,7 +98,7 @@ extension BasicProvider {
viewGenerator: ((Data, Int) -> View)? = nil,
viewUpdater: @escaping (View, Data, Int) -> Void,
layout: Layout = FlowLayout(),
sizeProvider: @escaping SizeSource<Data> = defaultSizeSource,
sizeProvider: SizeSource<Data> = SizeSource<Data>(),
presenter: Animator? = nil,
willReloadHandler: (() -> Void)? = nil,
didReloadHandler: (() -> Void)? = nil,
Expand All @@ -118,7 +118,7 @@ extension BasicProvider {
viewGenerator: ((Data, Int) -> View)? = nil,
viewUpdater: @escaping (View, Data, Int) -> Void,
layout: Layout = FlowLayout(),
sizeProvider: @escaping SizeSource<Data> = defaultSizeSource,
sizeProvider: SizeSource<Data> = SizeSource<Data>(),
presenter: Animator? = nil,
willReloadHandler: (() -> Void)? = nil,
didReloadHandler: (() -> Void)? = nil,
Expand Down
40 changes: 37 additions & 3 deletions Sources/Other/SizeSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,42 @@

import UIKit

public typealias SizeSource<Data> = (Int, Data, CGSize) -> CGSize
public typealias ClosureSizeSourceFn<Data> = (Int, Data, CGSize) -> CGSize

public func defaultSizeSource<Data>(at: Int, data: Data, collectionSize: CGSize) -> CGSize {
return collectionSize
open class SizeSource<Data> {

public init() {}

// override point for subclass
open func size(at index: Int, data: Data, collectionSize: CGSize) -> CGSize {
return collectionSize
}
}

open class UIImageSizeSource: SizeSource<UIImage> {
open override func size(at index: Int, data: UIImage, collectionSize: CGSize) -> CGSize {
var imageSize = data.size
if imageSize.width > collectionSize.width {
imageSize.height /= imageSize.width / collectionSize.width
imageSize.width = collectionSize.width
}
if imageSize.height > collectionSize.height {
imageSize.width /= imageSize.height / collectionSize.height
imageSize.height = collectionSize.height
}
return imageSize
}
}

open class ClosureSizeSource<Data>: SizeSource<Data> {
open var sizeSource: ClosureSizeSourceFn<Data>

public init(sizeSource: @escaping ClosureSizeSourceFn<Data>) {
self.sizeSource = sizeSource
super.init()
}

open override func size(at index: Int, data: Data, collectionSize: CGSize) -> CGSize {
return sizeSource(index, data, collectionSize)
}
}
Loading