GithubHelp home page GithubHelp logo

ra1028 / carbon Goto Github PK

View Code? Open in Web Editor NEW
1.3K 25.0 94.0 13.05 MB

🚴 A declarative library for building component-based user interfaces in UITableView and UICollectionView.

Home Page: https://ra1028.github.io/Carbon

License: Apache License 2.0

Swift 98.54% Makefile 0.12% Ruby 1.34%
swift ios component node diffing declarative render react delegate datasource

carbon's Introduction

β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘
β–‘β–‘β–‘β–‘β–‘β–„β–„β–ˆβ–ˆβ–ˆβ–ˆβ–„β–„β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–€β–„β–‘β–‘β–‘β–„β–€β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–„β–‘β–€β–„β–‘β–‘β–‘β–„β–€β–‘β–„β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–„β–„β–ˆβ–ˆβ–ˆβ–ˆβ–„β–„β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘
β–‘β–‘β–‘β–„β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–„β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–„β–ˆβ–€β–ˆβ–ˆβ–ˆβ–€β–ˆβ–„β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–„β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–„β–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–„β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–„β–‘β–‘
β–‘β–„β–ˆβ–ˆβ–„β–ˆβ–ˆβ–„β–ˆβ–ˆβ–„β–ˆβ–ˆβ–„β–ˆβ–ˆβ–„β–‘β–‘β–‘β–‘β–ˆβ–€β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–€β–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–„β–ˆβ–ˆβ–ˆβ–„β–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–„β–„β–ˆβ–ˆβ–„β–„β–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–„β–ˆβ–ˆβ–„β–ˆβ–ˆβ–ˆβ–‘
β–‘β–‘β–‘β–€β–ˆβ–€β–‘β–‘β–€β–€β–‘β–‘β–€β–ˆβ–€β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–‘β–ˆβ–€β–€β–€β–€β–€β–ˆβ–‘β–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–€β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–€β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–„β–€β–„β–€β–€β–„β–€β–„β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–„β–€β–„β–„β–€β–„β–‘β–‘β–‘
β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–€β–€β–‘β–€β–€β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–„β–€β–‘β–‘β–‘β–‘β–‘β–€β–„β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–€β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–€β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–€β–‘β–€β–‘β–‘β–€β–‘β–€β–‘β–‘
β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘

carbon's People

Contributors

popeyelau avatar ra1028 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

carbon's Issues

Add prebuilt carthage framework

Checklist

Description

Add a prebuilt carthage framework to every Carbon release to speed up build times when using it in apps.

Motivation and Context

I'm using carthage as dependency manager for my projects and I use Carbon extensively, thank you for the awesome work! Carthage builds all the dependencies from source every time, unless they have a prebuilt framework attached to the github release. By attaching it, the client simply downloads the framework and build times are much faster.

Proposed Solution

## do this only the first time on your mac or CI
## https://github.com/github/hub
brew install hub

## to create a release, from the project's root
carthage build --archive
hub release create -a Carbon.framework.zip -m "tag comment" "tag version"

And you will get a release like this (taken from RxSwift)
Schermata 2019-05-10 alle 11 44 06

Option to reload/replace a specific section ID

If we have for example a grouped list with a lot of itens an option to reload only a specific section improves the performance a lot because we don't have to map and regenerate all the components again (for ex when expand/collapsing sections).

Is it possible to get something like this?

Decompose `IdentifiableComponent` to `Identifiable` and `Component`

Checklist

Description

Decompose IdentifiableComponent to Identifiable and Component.

Motivation and Context

Use protocol composition like SwiftUI.

Proposed Solution

Use Swift.Identifiable if Swift version is greater than 5, and creates Carbon.Identifiable protocol if not.
e.g.

#if swift(<5)

public protocol Identifiable {
    associatedtype ID: Hashable

    var id: ID { get }
}

#endif

typealias IdentifiableComponent = Identifiable & Component

IdentifiableComponent will be deprecated in the future, but not now.

Crash when building and launching for iOS 10, 11 and 12 simulator

dyld: Library not loaded: /System/Library/Frameworks/SwiftUI.framework/SwiftUI
  Referenced from: /Users/thomasricouard/Library/Developer/CoreSimulator/Devices/A09605A4-9BF2-4D63-9B5A-000D85C18FCA/data/Containers/Bundle/Application/92E5E64B-1EBD-46C3-A9A0-486C122D0E41/Glose Education Staging.app/Frameworks/Carbon.framework/Carbon
  Reason: no suitable image found.  Did find:
	/System/Library/Frameworks/SwiftUI.framework/SwiftUI: mach-o, but not built for iOS simulator

SwiftUI is not conditionally linked? I'm getting crash on launch as SwiftUI can't be linked on any earlier iOS version than 13.

[Idea] Make `referenceSize(in bounds:)` returns nil by default

Checklist

Description

Make referenceSize(in bounds:) returns nil by default in Component.
The table view and collection view are use their own size setting by default.
e.g.

  • UITableView uses UITableView.rowHeight, default is UITableViewAutomaticDimenstion.
  • UICollectionView(flow layout) uses UICollectionViewFlowLayout.itemSize, default is CGSize(width: 50, height: 50).
struct Label: Component, Equitable {
    var text: String

    func renderContent() -> UILabel {
        return UILabel()
    }

    func render(in content: UILabel) {
        content.text = text
    }

-    // Default is nil, it fallback to `UITableView.rowHeight`.
-    func referenceSize(in bounds: CGRect) -> CGSize? {
-        return CGSize(width: bounds.width, height: 44)
-    }
}

Motivation and Context

Wants to simplify the creation of Component like as List in SwiftUI.

Proposed Solution

Make Component.referenceSize returns nil by default.

Discussion

Agree πŸ‘ or Disagree πŸ‘Ž

cellNode(at: indexPath) Fatal error: Index out of range

Checklist

Expected Behavior

Should not crash

Current Behavior

Rapid updates between these two type of reload methods cause datasource to be inconsistent
https://github.com/ra1028/Carbon/blob/master/Sources/Updaters/UICollectionViewUpdater.swift#L59-L64
https://github.com/ra1028/Carbon/blob/master/Sources/Updaters/UICollectionViewUpdater.swift#L70-L75

and will sometimes, very rarely, cause cellNode(at: indexPath) below to throw an fatal arror
https://github.com/ra1028/Carbon/blob/master/Sources/Updaters/UICollectionViewUpdater.swift#L168

Steps to Reproduce

Attached simple example project. You may have to run it a few times.
CarbonCrash.zip

Screenshot 2020-10-29 at 21 45 39

Environments

  • Carbon version: Master
  • Swift version: 5.3
  • iOS version: 14.1
  • Xcode version: 12
  • Devices/Simulators: All
  • CocoaPods/Carthage version: SPM

How to create Content as UIViewController

Checklist

Expected Behavior

I have some UIViewControlers will be embedded in UITableViewCell. This require calling addChildController and didMove(toParent:) when deque cell.

At the moment, seem that Carbon does not support to do that.

Keep UITableView ContentOffset to prepend list items

Checklist

Expected Behavior

I want to make a timeline like Twitter using Carbon and UITableView.

  • When I continue to load the latest items and append the Component Items in List, UITableView contentOffset works properly. (= keep the current position)
  • When I pull to refresh and prepend Component items in List, UITableView contentOffset moves to top position in List.

Current Behavior

Add to append items.

list = [Component3, Component4, Component5]
appendItems = [Component6, Component7]

I scroll to the latest item Component5.

newList = [Component3, Component4, Component5, Component6, Component7]

and UITableView's contentOffset indicates Component5. Keep current position.

Add to prepend items.

list = [Component3, Component4, Component5]
appendItems = [Component1, Component2]

I pull to refresh.

newList = [Component1, Component2, Component3, Component4, Component5]

and UITableView's contentOffset indicates Component1. Not Component3

Detailed Description (Include Screenshots)

  • I want to resolve latter case. (add to prepend items)
    • UITableView's contentOffset should indicate Component3.
  • Do you have any solutions? Thank you.

Environment

  • Carbon version:
    1.0.0 Release Candidate 6

  • Swift version:
    Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29)

  • iOS version:
    13.4.1

  • Xcode version:
    11.4.1

  • Devices/Simulators:
    iPhone11Pro 13.4.1

  • using SPM

[Proposal] Consider `estimateItemSize` in addition to `itemSize.`

Checklist

Description

I used UICollectionViewFlowLayout to implement a collectionView where collectionView.height and collectionView.contentSize.height are equal and the width of the cell is dynamic. Then, I set estimatedItemSize on prepare () method(didn't set itemSize).
It makes UICollectionViewFlowLayoutBreakForInvalidSizes of layout error.(I called layoutIfNeeded after reloadData)

I resolved to set itemSize on prepare().

Found Carbon handle for only itemSize.

Apple Document don't say need both estimatedItemSize and itemSize.

Proposed Solution

Carbon handle both itemSize and estimatedItemSize or write doc about estimatedItemSize. (It may not be necessary because itemSize is already written πŸ€” )

Need the ability to add event handling to the Component

Checklist

Description

I would like to be able to add event handling directly to the component.

Example:
struct HelloMessage: Component {
Β Β Β  ...
}

HelloMessage().on(.click) { ... }.cellNode
HelloMessage().on(.viewWillAppear) { ... }.cellNode

or

HelloMessage().cellNode.on(.click) { ... }
HelloMessage().cellNode.on(.viewWillAppear) { ... }

Motivation and Context

Allows you to make ViewController cleaner.

Mismatched header types

Checklist

Expected Behavior

In RC2 it was possible two show a different heading based on a flag

Current Behavior

In RC4 this behavior is not possible anymore. Resulting in this error:
Result values in '? :' expression have mismatching types 'TodayEmpty' and 'TodayHeader'

Detailed Description (Include Screenshots)

Section(
                id: "contactToday",
                header: state.today.isEmpty
                    ? TodayEmpty() : TodayHeader(),
                cells: { }
)

Both are Component:
struct TodayEmpty : Component
struct TodayHeader : Component

Environment

  • Carbon version:
    RC4
  • Swift version:

Is this possible in RC4 and onwards?

Generic parameter 'H' could not be inferred

Checklist

Expected Behavior

Render Section() with FunctionBuilder Syntax

Current Behavior

When updating to RC4, rewriting to use FunctionBuilder Syntax, build failed with error:
Generic parameter 'H' could not be inferred for Section(

Steps to Reproduce

Section(
            id: ID.summary,
            header: nil,
            cells: {
                Group(of: state.someContent.enumerated()) { offset, someContent in
                    SampleCell(someContent)
                }
        })

Environments

  • Carbon version:
    1.0.0-rc.4

  • Swift version:
    Apple Swift version 5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)

  • Xcode version:
    Version 11.0 (11A419c)

[Idea] Declarative syntax like SwiftUI with function builder

Checklist

Description

Add support declarative syntax like SwiftUI with function builder for Swift5.1.
It replaces closire style syntax added in Carbon 1.0.0.-rc.1.

renderer.render {
    Label("foo")
    Label("bar")
    Label("baz")

    if flag {
        Label("qux")
    }
}
renderer.render {
    Section(id: "section1") {
        Label("foo")
        Label("bar")
        Label("baz")
    }

    Section(
        id: "section2",
        header: Label("header"),
        footer: Label("footer"),
        cells: {
            Label("qux")
            
            if flag {
                Label("quux")
            }
        }
    )
}

Motivation and Context

Wants to simplify the creation rendering like as List in SwiftUI.

Proposed Solution

Add support @functionbuilder for Renderer.render and Section initializer.

Discussion

Agree πŸ‘ or Disagree πŸ‘Ž

Compilation error "Carbon is not available when building for iOS Simulator"

Checklist

Expected Behavior

The example application compiles without the error message

Current Behavior

~/Carbon/Examples/Example-iOS/Example-iOS.xcodeproj Carbon is not available when building for iOS Simulator.

Steps to Reproduce

Install Xcode 11.4
Follow the steps to run the example app from the README.

Reproducible Demo Project

The as is Example app from the Carbon repository.

Environments

I was thinking that this is related to CocoaPods only but seems like the Example app from the Carbon that is not using CocoaPods to resolve dependencies has the same issue in Xcode 11.4.

Crash in the example app on shuffle or relaod.

Checklist

Expected Behavior

The application doesn't crash on changeset usage.

Current Behavior

Steps to Reproduce

  1. git clone https://github.com/ra1028/Carbon
  2. make setup
  3. Run example app on the simulator e.g. iPhone 11 (13.3)
  4. Pick Shuffle Emoji
  5. Tap on *Shuffle or reload

Detailed Description (Include Screenshots)

The application crashes when tries to access variable changesets in StagedChangeset.

Class stack:

#0	0x00007fff51ba9008 in swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::incrementSlow(swift::RefCountBitsT<(swift::RefCountInlinedness)1>, unsigned int) ()
#1	0x00007fff51b81028 in _swift_retain_(swift::HeapObject*) ()
#2	0x00007fff51bd03dc in swift_bridgeObjectRetain ()
#3	0x0000000106eae18b in initializeWithCopy for Changeset ()
#4	0x00007fff51903ecd in ContiguousArray.subscript.getter ()
#5	0x0000000106ec9eb9 in StagedChangeset.subscript.getter at ~/Downloads/Carbon/Carthage/Checkouts/DifferenceKit/Sources/StagedChangeset.swift:70
#6	0x0000000106eca4ea in StagedChangeset.subscript.read ()
#7	0x0000000106ecb1c9 in protocol witness for Collection.subscript.read in conformance StagedChangeset<A> ()
#8	0x00007fff518fc01c in protocol witness for IteratorProtocol.next() in conformance IndexingIterator<A> ()
#9	0x00007fff51a04a71 in Sequence.reduce<A>(_:_:) ()
#10	0x0000000106e1aa8a in UICollectionViewUpdater.performUpdates(target:adapter:data:) at ~/Downloads/Carbon/Sources/Updaters/UICollectionViewUpdater.swift:66

When trying to access changesets from LLDB the errors is shown:

expression produced error: error: /var/folders/02/t9d7qfqn41l47hv7p007jkgr0000gn/T/expr114-a87593..swift:1:123: error: use of undeclared type 'Carbon'
Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer<Swift.ContiguousArray<DifferenceKit.Changeset<Swift.Array<Carbon.Section>>>>(bitPattern: 0x114343780)!.pointee)

Environments

  • Carbon version:
    1.0.0-rc.6

  • Swift version:
    5.1.3

  • iOS version:
    13.3

  • Xcode version:
    11.3.1

  • Devices/Simulators:
    Any simulator

Add helper scroll methods

I know this is a bit out of context of the framework, but some methods to scroll the target to a specific section id or cell id are really useful.

Why the removal of `UITableViewCellContent` related classes?

Checklist

Hi, I appreciate your work but I was wondering: why did you remove UITableViewCellContent in the latest release (rc1)?
It was the only way to access the cell that actually is rendered by the tableview.
Now I can't, for example, add an accessory view to the cell keeping the cell's background color the same, and I can't make use of the default cell selection behavior.

Detect component appear/disappear?

Hi,

in apple documentation for didEndDisplaying we read:

Use this method to detect when a cell is removed from a collection view, as opposed to monitoring the view itself to see when it disappears.

this means that this method can't be used to implement the contentDidEndDisplay``contentWillDisplay...

for me in iOS 13.1 b4 this methods won't fire when we really need them. I need to perform some lazy loading work in the component and without this is really hard to detect when to cancel it.

Make updater can insert any processes before `CATransaction.commit`

Checklist

Description

Make updater can insert any processes before CATransaction.commit by overriding update method in updater.
This allows user to insert a arbitrary process sequentially on the run loop.

Motivation and Context

Wants to adjust the content offset after updating for implement the comment UI.
Currently, runloop is divided by CATransaction, and the drawing glitches for a moment.

Proposed Solution

Split the code in a transaction into another method to make can be overridden.

Gif

comment

XCode 13+ issues

Checklist

Expected Behavior

Expecting to be able to do pod install & to archive a build.

Current Behavior

pod install results in errors for Carbon.
Trying to archive the project results in compile errors.

Steps to Reproduce

  1. Open a project that uses Carbon on a system with above described details
  2. Try to do an archive

Environments

  • Carbon version: 1.0.0-rc6

  • Swift version: 5.5

  • Xcode version: 13.1

Generic parameter 'Element' could not be inferred

Checklist

Expected Behavior

While updating from RC2 to RC4, the next issue happens.

Current Behavior

Array of class [ClassName], using the group function to list as cells.

cells: {
                        Group(of: state.todos.enumerated()) { offset, todo in
                            TodoText(todo: todo, isCompleted: false)
}}

Detailed Description (Include Screenshots)

However, using another class results in this error:
Generic parameter 'Element' could not be inferred. Explicitly specify the generic arguments to fix this issue
When explicitly specifying arguments I get the following error:
Unable to infer closure type in the current context.

What am I doing wrong?

Environment

  • Carbon version:
    RC4

Weird behaviour as I scroll up

Hello,

I'm making a fairly complexe UITableView, and I have some weird behaviours.
As I scroll down, mostly no problem. As I scroll up I get really weird behaviours, like blank space (missing components?) and wrongly sized component.

Here is two images, one normal and one as I scroll up.
IMG_0496
IMG_0495

Here is some code, this is a big project, it would be very hard for me to extract and isolate this code to make a self contain package in order to reproduce it.
But maybe something is wrong in my approach.

Here is my datasource
Screenshot 2019-10-23 at 18 41 18

And also the code of one of my component as an example

struct ReadingActivityQuoteComponent: IdentifiableComponent {
    let quote: Quote?
    let isTop: Bool
    
    var id: String {
        quote?.id ?? "quoteLoading"
    }
    
    class View: UIView {
        var quote: Quote? {
            didSet {
                render()
            }
        }
        
        var isTop: Bool = false {
            didSet {
                if isTop {
                    cardView.maskedCorners = [.topLeft, .topRight]
                } else {
                    cardView.maskedCorners = []
                }
            }
        }
        
        let quoteLabel = QuoteDarkerLeft(frame: .zero)
        let cardView = CardView(frame: .zero)
        
        init() {
            super.init(frame: CGRect.zero)
            
            cardView.maskedCorners = []
            
            quoteLabel.showAnimatedGradientSkeleton()
            quoteLabel.numberOfLines = 0
        
            addSubview(cardView)
            cardView.addSubview(quoteLabel)

            
            constrain(self, cardView, quoteLabel) { parent, card, quote in
                card.top == parent.top
                card.left == parent.readableContentGuide.left + 12
                card.right == parent.readableContentGuide.right - 12
                card.bottom == parent.bottom
                
                quote.top == card.top + 12
                quote.left == card.left + 12
                quote.right == card.right - 12
                quote.bottom == card.bottom - 12
            }
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        func render() {
            quoteLabel.hideSkeleton()
            quoteLabel.text = quote?.text
        }
    }
    
    func renderContent() -> ReadingActivityQuoteComponent.View {
        View()
    }
    
    func render(in content: ReadingActivityQuoteComponent.View) {
        content.quote = quote
        content.isTop = isTop
    }
}

Coming from a lot of SwiftUI lately, Carbon is really awesome to use in the UIKit world. But I'm having quite some issues right now.
Again, I have no idea if my architecture is wrong or if I'm hitting some underlying Carbon or UITableView related bugs.
I'm self sizing every component with auto layout using Cartography.

What's the difference between these two methods?

Checklist

What's the difference between these two methods?

/// Returns a new instance of `Content`.
///
/// - Returns: A new `Content` instance.
func renderContent() -> Content

/// Render properties into the content.
///
/// - Parameter:
///   - content: An instance of `Content` laid out on the element of list UI.
func render(in content: Content)

Pass focus between components with keyboard's return key

Description

I'll describe you my scenario. I have a form made in Carbon with two text fields. I want to be able to change the focused component by pressing keyboard's return key. When I reach the last one I want to display Done or Send (it depends on the specific scenario).

Proposed Solution

Taken the idea from here: https://medium.com/swift2go/swift-move-to-the-next-uitextfield-by-hitting-return-c3ce44ee9591

and implemented in Example project of my fork: https://github.com/leoparenti/Carbon

You can clone it and check it.

This solution uses tags and viewWithTag and it works, but I understand it's not the Carbon way of doing things, but I haven't find a better way to do it. Do you have better ideas or solutions to achieve the same final result, but with something more compliant to Carbon? Thank you in advance.

Stick a component to the bottom of a UITableView

Checklist

Expected Behavior

Being able to set AnyComponent or ViewNode as tableView.tableFooterView so it always sticks to the bottom no matter how many cells are displayed.

Current Behavior

Seems like currently there is no way to set a footer of the whole table view, only within a section:

renderer.render {
      Section(
        id: "XXX",
        cells: [
          ...,
         ...
        ],
       footer: <FOOTER>
      )
}

Detailed Description (Include Screenshots)

Thanks a lot for the framework. I was curious whether there is way to attach a view to the bottom of the screen using ViewNode or AnyComponent irregardless of the number of displayed cells (so the spacing between this component and BottomLayoutGuide is always fixed).

Environment

  • Carbon version:
    1.0.0-rc.5
  • Swift version:
    5.0
  • Xcode version:
    11.1

[Idea] Make `alwaysRenderVisibleComponents` true by default

Checklist

Description

Make alwaysRenderVisibleComponents true by default in UITableViewUpdater and UICollectionViewUpdater.
And make Component not required to implement shouldComponentUpdate.
Even if it returns false by default, it can be rendered always in the updater.

Expected changes

  • alwaysRenderVisibleComponents set true by default.
  • shouldComponentUpdate returns false by default.
  • Abolish skipReloadComponents.

e.g.

struct Label: Component {
    var text: String

    func renderContent() -> UILabel {
        return UILabel()
    }

    func render(in content: UILabel) {
        content.text = text
    }

- // always return `false`, and updater reloads visible items after updates.
-    func shouldContentUpdate(with next: Label) -> Bool {
-        return text != next.text
-    }
}

Motivation and Context

It eliminates the need for developers to implement shouldContentUpdate.
Because it is the most iterative implementation in app using Carbon, omitting it will increase development efficiency and safety.

Discussion

AgreeπŸ‘ or disagreeπŸ‘Ž

`keepContentOffset` not working ?

Checklist

Expected Behavior

TableView is not bouncing after reloadData.

Current Behavior

The form example is auto bouncing after reloadData when tableView contentOffset.y is bottom.
I tried set keepContentOffset true, but it's not working.
Do you know anything about this ?

Detailed Description (Include Screenshots)

Environment

  • Carbon version:
    0.3.0(latest)
  • Swift version:
    4.2
  • iOS version:
    11.0
  • Xcode version:
    10.1
  • Devices/Simulators:
    Devices - iPhoneX
  • CocoaPods/Carthage version:

Unexpected behaviour with section headers

Checklist

Hey @ra1028 πŸ‘‹
First of all, congrats on such a great project! I've been playing with Carbon lately and I think I managed to find a nasty issue with UITableView section headers or maybe I'm doing something wrong πŸ€”

Expected Behavior

Show all section headers and allow self-sizing

Current Behavior

  • First section header is not displayed
  • Self-sizing doesn't seem to work

Detailed Description (Include Screenshots)

  • Expected (with standard UITableView code)

Screenshot 2019-11-14 at 10 43 59

  • What I get with Carbon

Screenshot 2019-11-14 at 10 43 57

Sample Project:

Test.zip

Environment

  • Carbon version: What's currently in master

  • Swift version: 5.1

  • iOS version: 13.2

  • Xcode version: 11.2

  • Devices/Simulators: iPhone 11 Pro

  • CocoaPods/Carthage version: Not applicable (Swift Package Manager)

Initializing `Renderer` without passing the target instance.

Checklist

Description

Allow Renderer to be initialized without passing the target instance.

Motivation and Context

Become no need to add lazy to renderer property declarations.
Also, the timing when delegate and dataSource are set in tableView becomes explicit.
Depending on when delegate and dataSource are set, cases have been found where unnecessary space is available above or below the tableView.

Proposed Solution

@IBOutlet weak var tableView: UITableView!

let renderer = Renderer(
    adapter: UITableViewAdapter(),
    updater: UITableViewUpdater()
)

func viewDidLoad() {
    super.viewDidLoad()
    renderer.target = tableView
}

why?when I copy a New Project

ζˆͺ屏2019-12-25δΈ‹εˆ6 05 16

Checklist

Expected Behavior

Current Behavior

Steps to Reproduce

Detailed Description (Include Screenshots)

Reproducible Demo Project

Environments

  • Carbon version:

  • Swift version:

  • iOS version:

  • Xcode version:

  • Devices/Simulators:

  • CocoaPods/Carthage version:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.