Skip to content

[WIP] No More Collection View #532

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
133 changes: 133 additions & 0 deletions ListableUI/Sources/CollectionView/CollectionView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
//
// CollectionView.swift
// ListableUI
//
// Created by Kyle Van Essen on 11/29/23.
//

import Foundation


final class LSTCollectionView : UIScrollView {

private let queue : ListChangesQueue

private(set) var content : Content

private var reuseCache : ReusableViewCache

private let view : ContentView

// MARK: Initialization

override init(frame: CGRect) {

self.queue = .init()
self.content = .empty
self.reuseCache = .init()
self.view = .init(frame: .init(origin: .zero, size: frame.size))

super.init(frame: frame)

self.addSubview(self.view)
}

// MARK: UIScrollView

override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
super.setContentOffset(contentOffset, animated: animated)
}

// MARK: UIView

override func layoutSubviews() {
super.layoutSubviews()

self.view.frame = bounds
}

required init?(coder: NSCoder) { fatalError() }

func set(
content : Content,
changes: SectionedDiff<Section,
AnyIdentifier,
AnyItem,
AnyIdentifier>,
completion : @escaping () -> ()
) {
queue.add {

}
}

}

extension LSTCollectionView {
final class ContentView : UIScrollView {

}
}

open class LSTCollectionReusableView : UIView {

}

open class LSTCollectionSupplementaryView : LSTCollectionReusableView {

}

open class LSTCollectionItemView : LSTCollectionReusableView {

}


extension LSTCollectionView {

struct Content {

static var empty : Self {
fatalError()
}

var supplementaries : Supplementaries

var sections : [Section]
}

struct Section {
var supplementaries : Supplementaries

var items : [Item]
}

struct Item {
var value : AnyItem

var state : State

final class State {

}
}

struct Supplementaries {

private var byType : [ObjectIdentifier:Supplementary]

}

struct Supplementary {
var value : AnyHeaderFooter

var state : State

final class State {

}
}
}

protocol SupplementaryTypeKey {

}
16 changes: 7 additions & 9 deletions ListableUI/Sources/Internal/ReusableViewCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,32 @@ import Foundation

final class ReusableViewCache
{
private var views : [String:[AnyObject]] = [:]

init() {}
private var views : [AnyHashable:[AnyObject]] = [:]

func count<Content>(for reuseIdentifier : ReuseIdentifier<Content>) -> Int
{
let views = self.views[reuseIdentifier.stringValue, default: []]
let views = self.views[reuseIdentifier, default: []]

return views.count
}

func push<Content,View:AnyObject>(_ view : View, with reuseIdentifier: ReuseIdentifier<Content>)
{
var views = self.views[reuseIdentifier.stringValue, default: []]
var views = self.views[reuseIdentifier, default: []]

listableInternalPrecondition(views.contains { $0 === view } == false, "Cannot push a view which is already in the cache.")

views.append(view)

self.views[reuseIdentifier.stringValue] = views
self.views[reuseIdentifier] = views
}

func pop<Content,View:AnyObject>(with reuseIdentifier: ReuseIdentifier<Content>, _ create : () -> View) -> View
{
var views = self.views[reuseIdentifier.stringValue, default: []]
var views = self.views[reuseIdentifier, default: []]

if let view = views.popLast() {
self.views[reuseIdentifier.stringValue] = views
self.views[reuseIdentifier] = views
return view as! View
} else {
return create()
Expand All @@ -46,7 +44,7 @@ final class ReusableViewCache

func use<Content,View:AnyObject, Result>(with reuseIdentifier: ReuseIdentifier<Content>, create : () -> View, _ use : (View) -> Result) -> Result
{
let views = self.views[reuseIdentifier.stringValue, default: []]
let views = self.views[reuseIdentifier, default: []]

if let view = views.last {
// Fast path: Already in the cache, just reference it here.
Expand Down
28 changes: 28 additions & 0 deletions ListableUI/Sources/ListView/ListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,34 @@ public final class ListView : UIView
self.updateCollectionViewWithCurrentLayoutProperties()
}

//
// MARK: Replace UICollectionView Feature Flag
//

public static var isNewBackingViewEnabled : Bool {
get {
UserDefaults.standard.bool(forKey: "Listable.isNewBackingViewEnabled")
}

set {
UserDefaults.standard.setValue(newValue, forKey: "Listable.isNewBackingViewEnabled")
}
}

public let isNewBackingViewEnabled : Bool = ListView.isNewBackingViewEnabled

public func ifNew<Output>(
_ ifNew : () throws -> Output,
ifOld : () throws -> Output
) rethrows -> Output {

if Self.isNewBackingViewEnabled {
try ifNew()
} else {
try ifOld()
}
}

//
// MARK: Layout
//
Expand Down
Loading