babylonhealth / bento Goto Github PK
View Code? Open in Web Editor NEWSwift library for building component-based interfaces on top of UITableView and UICollectionView š±
License: MIT License
Swift library for building component-based interfaces on top of UITableView and UICollectionView š±
License: MIT License
Currently, the version available on cocoapods is 0.2 https://cocoapods.org/pods/Bento .
Therefore doing pod 'Bento'
on Xcode 10 results in a broken build.
Could you please update version available through official cocoapods channel to the newest?
The idea for the public API for the moment is
Form
form.render(in: tableView)
Renderable
a way for users of the library to provide custom componentslet form = Form.empty
|-+ Section()
|--+ Row()
|--+ Row()
|-+ Section()
|--+ Row()
|--+ Row()
from.render(in: tableView)
A Component
conforming to PreSizingLayoutPassRequiring
exhibits strange rendering behaviour, appearing to render at zero height and then re-size to the correct height on every render pass. This can be seen in the SignUp Example:
The Gender field is using DetailedDescripton
which conforms to PreSizingLayoutPassRequiring
. If I remove this conformance, the rendering glitch goes away.
I suspect that this is somehow related to the recent changes relating to size caching, as this only started to occur recently (on the develop
branch, btw).
Seems related to #80
cc: @andersio
Currently there seem to be no way to change table view appearance, i.e. its background colour, managed by Bento as it is being set to .clear
in viewDidLoad
in BoxViewController
. At the same time there is a TableViewStyleSheet
that seem to be only used when table is part of some other Bento component.
I'd suggest to make it part of Screen
API and apply it internally instead of setting hardcoded default as it is done right now (in private func configureTableView(_ tableView: UITableView) -> UITableView
). i.e.:
Screen(title: "", box: ..., style: TableViewStyleSheet(...))
Same can apply to the pinned boxes as they are implemented as separate table views, but usually contain just one component so things like background colour can be set through this component.
The Component.Button.Stylesheet
currently inherits from BaseViewStyleSheet
, but the base view for the Button
component is an InteractiveView
so the stylesheet class should inherit from InteractiveViewStyleSheet
.
A consequence of this bug is that you cannot set the highlightColor
for a Button. That means that when you set custom .highlighted
color for the button, it is overridden with the default highlightColor
of the InteractiveView
:
As I see there is no activity since June. Are you going to maintain this library further?
It seems that UITableView
does not like when you move section and insert an item in it at the same time:
If we have sections transitions:
[1, 2] - [3, 4] -> [1, 2] - [5] - [6, 3, 4]
As you can see we insert new sections [5]
and move [3, 4]
and at the same time insert an item 6
The solution is to treat moves of the sections as removal and insertion
Is anyone realistically going to use Bento
on its own? I donāt really think so, because it has no ready to use components, so only a masochist would go down that route. However, BentoKit
, which gives you some components, obliges you to integrate ReactiveSwift/ReactiveCocoa (RAS/RAC) into your project, even if you donāt want to use it.
None of the Component
s in BentoKit
require RAS/RAC except TitledDescription
š¤¦āāļø, which only uses it for the image
property.
In fact, the only things in BentoKit
that require RAS/RAC are: BoxViewModel
, BoxViewController
and ImageOrLabelView
(and therefore TitledDescription
). For ImageOrLabelView
itās only a Reactive
extension which could easily be moved elsewhere.
StyleSheets
is also required to use the Component
s so TBH I donāt see why it needs to be in a separate framework (itās not particularly useful on its own)
If we want Bento
to be developer friendly ideally we should:
Component
s from BentoKit
into Bento
(except TitledDescription
)BentoKit
such as all the RAS/RAC things like BoxViewModel
, BoxViewController
and all that they are part of (Screen
etc) into a new library into a separate repo.That way in Bento
we would be left with a nice declarative, component based, tableview / collection view library (Bento
+ components + StyleSheets
) that anyone could use without being wedded to RAS/RAC or the Screen
/ BoxViewController
/ BoxViewModel
architecture.
BentoKit
would become its own thing that depends on Bento
.
Enable size caching by default in Bento, for both UITableView and UICollectionView (if using UICollectionViewFlowLayout).
This helps scrolling performance for use cases with a low frequency of changes & a moderate amount of screen complexity.
The problem is, however, the incurred cost during re-rendering of new Box
s. Bento must invalidate all cached sizes before starting to render any new Box
, unless the component does not change at a given ID path. Pragmatically speaking, this cannot happen for a majority of components (e.g. BentoKit) falling back to the pointer equality (conservative but correct), due to them carrying non-equatable properties e.g. callback.
So if we enable size caching without addressing this issue, for screens that have high burst of state changes e.g. reacting to continuous text input, the cost of precomputation would be incurred every time a new Box
is rendered, which is incredibly unideal.
TitledDescription
, 1000 iterations, -O -wholemodule
Source
Item | Result (1000 iterations) |
---|---|
Full equality of layout affecting properties* | Small Strings: āØsub 1 ms. 5000+ character strings: sub 2 msāØ |
Custom Height Computation | āØsub 100 msāØ |
AutoLayout height computationāØ | > 1000 ms |
* Style sheets & RAS properties are compared by value.
Evaluating equality of a subset of component properties is considerably cheaper (2-3 order of magnitude) than computing the actual layout height.
In order words, it is beneficial and pragmatic to evaluate equality so as to avoid as much layout computation as possible, lowering the performance impact of sizing ahead of time.
Introduce a notion of ācomponent layout equivalenceā to replace component equation.āØāØāØāØ
When we say C.isLayoutEquivalent(a, b) == true
, all properties contributing to the layout from both instances are equal. In other words, rendering a
and b
should result in the same exact layout.
Renderable
would however provide a false
returning default implementation. This effectively replicates the current behaviour (still correct but more expensive), while being (mostly) source compatible.
BentoKit components should provide implementations for this requirement.
Remove Equatable
inheritance from Renderable
.
We should not reappropriate ==
for component layout equivalence, since it would violate the substitutability requirement mandated by the Equatable contract.
With the above two measures in place, Bento may start pre-compute component height using AutoLayout by defaultāØ.
Bento should invalidate only cached size for ID paths failing the component layout equivalence test.
(Optionally) Replacing HeightCustomizing
with something more general.
The last release of Bento was a long time ago.
We need to start thinking about realising a new version
The 0.4.0 version will contain breaking changes
Component.Description.StyleSheet
inherits from BaseViewStyleSheet
but it's view inherits from InteractiveView
not BaseView
so the stylesheet should inherit from InteractiveViewStyleSheet
to allow customising the interaction behaviour.
Trying to install Bento 0.4 using carthage:
% carthage update bento --platform ios
*** Cloning Bento
*** Fetching ReactiveCocoa
*** Fetching TinyConstraints
*** Cloning FlexibleDiff
*** Fetching ReactiveSwift
*** Cloning Result
*** Cloning xcconfigs
*** Cloning Box
*** xcodebuild output can be found in /var/folders/w3/d5j4zf_13xnf7ppx7qlps8wh0000gn/T/carthage-xcodebuild.GupBlD.log
The dependency graph contained a cycle:
TinyConstraints:
ReactiveCocoa: ReactiveSwift
% swift --version
Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.5.0
% carthage version
0.33.0
%
Cartfile looks like this:
github "ReactiveCocoa/ReactiveCocoa" ~> 10.0.0
github "roberthein/TinyConstraints" ~> 4.0.0
github "babylonpartners/Bento" ~> 0.4
It seems like there is an issue with delete animation if the state of the table view changes quickly (e.g during the delete transition transition)
make delete
call on the component after transaction finishes
sections[indexPath.section].items.remove(at: indexPath.row)
CATransaction.begin()
CATransaction.setCompletionBlock {
component.delete()
}
actionPerformed?(true)
tableView?.deleteRows(at: [indexPath], with: .left)
CATransaction.commit()
Before | After |
---|---|
Currently Screen
and, by extension, BoxViewController
only support text for the navigation bar title. They should support images as well.
Screen
already has NavigationTitleItem
for this, but it is not yet being used.
There should be a convenience initialiser for Screen
which takes NavigationTitleItem
instead of a String
for the title, and BoxViewController
needs to handle setting the image, in case the title is set as an image.
Add Diffing algorithm to support animated changes we gonna use FlexibleDiff for this
I'm testing out this library and based on documentation I can't seem to display table's header (an empty one).
Release: 0.3
Package Manager: Carthage
Here's my view controller:
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let box = Box<Int, Int>.empty
|-+ Section<Int, Int>(id: 0,
header: EmptySpaceComponent(height: 24, color: .green),
footer: EmptySpaceComponent(height: 50, color: .red))
|---+ 5 <> RowComponent(i: 5)
tableView.render(box)
}
}
The EmptySpaceComponent
:
struct EmptySpaceComponent: Renderable {
var height: CGFloat
var color: UIColor
typealias View = UIView
func render(in view: UIView) {
view.heightAnchor.constraint(equalToConstant: height).isActive = true
view.backgroundColor = color
view.layoutIfNeeded()
}
}
And the RowComponent
:
struct RowComponent: Renderable {
var i: Int
typealias View = UILabel
func render(in view: UILabel) {
view.text = "\(i)"
view.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
}
In Bento 0.4.0 we want to remove <>
operator as we think usage of Node.init is verbose enough and it doesn't need an operator to simplify it.
Moreover, <>
is a known operator in the functional programming world. We don't want to Bento stays in the conflict with it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ššš
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ā¤ļø Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.