React-inspired framework for building component-based user interfaces in Swift.

Related tags

React-Like react swift
Overview

TemplateKit

Swift Carthage compatible CocoaPods Compatible Platform License

React-inspired framework for building component-based user interfaces in Swift.

Features
🐀 Completely native - write your app in Swift
πŸ“ƒ Declarative - define your UI using markup
πŸ“¦ Components - encapsulate functionality into reusable chunks
πŸ“ Layout - Flexbox for layout, just like on the web
πŸ–‹ State - automatically flush state changes to UI
βš– Diffing - the minimum set of updates are flushed to UI
πŸš€ Performance - diffing and layout are done on background threads
⏲ Animation - built-in support for animating any property

Example

You define your UI using a simple markup language, which is inspired by HTML and CSS. This UI definition is rendered into a tree of native elements.

Component.xml

<template>
  <style>
    #container > .button {
      color: #000;
    }
    
    #container > .button-selected {
      color: #f00;
    }
  </style>

  <box id="container">
    <text text="$properties.title" />
    <text text="Click me!" onTap="handleClick" classNames="$textClasses" />
  </box>
</template>

Component.swift

Functionality and state is encapsulated into components, which do things like handle user events and flush state changes to the UI. Components have strongly typed State and Properties values, that are used to figure out what ends up getting pushed out to UIKit.

struct ComponentState: State {
  var selected: Bool?
}

struct ComponentProperties: Properties {
  var core = CoreProperties()
  var title: String? = "This is a default title"
}

class MyComponent: CompositeComponent<ComponentState, ComponentProperties, UIView> {
  // Stored properties on the component are made available to template.
  var textClasses: String?
 
  // As are functions, referenced by their selector name.
  @objc func handleClick() {
    updateComponentState { state in
      state.selected = !state.selected
    }
  }
 
  override func render() -> Element {
    textClasses = state.selected ? "button" : "button-selected"
  
    return render("http://localhost:8000/Component.xml")
  }
}

ViewController.swift

Rendering components is as easy as calling a render function, which asynchronously computes and flushes a component to the supplied container view.

override func viewDidLoad() {
  super.viewDidLoad()
 
  UIKitRenderer.render(component(MyComponent.self), container: self.view, context: self) { component in
    self.component = component
  }
}

See the included Example project for more examples of how to use TemplateKit.

Why?

Swift

Because you like writing your apps completely in Swift. TemplateKit is fully native and compiled.

Declarative Style

Writing user interfaces in a declarative style makes it easier to reason about how model data and user actions affect what gets rendered. Out-of-the-box support for XML. Extensible if you want to add your own template format (e.g., protocol buffers).

Components

Components make it easy to encapsulate application functionality into re-usable building blocks. These blocks can then be composed to create more complex interfaces.

Layout

Flexbox-based layout primitives allow developers to use the the same expressive layout system available in modern browsers.

Asynchronous Rendering & Performance

All layout computation, text sizing, tree diffing, image decoding is performed in the background. This keeps the main thread available for responding to user actions. Only the absolute minimum set of changes needed to update the view hierarchy are actually flushed to the rendered views.

CSS

Use stylesheets to style components, just like you do on the web.

Animations

Animate layout, style and arbitrary properties using an intuitive API.

Live Reloading

Automatically reload changes to user interfaces without having to re-build binaries or restart your application. Usable in both development and production environments.

Extensible

Add custom components, custom native views, custom template loading schemes and more.

Easy to try

Plug it in anywhere you want to render a view in your application. Plays nicely with the rest of your app.

Installation

Carthage

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

Add the following line to your Cartfile:

github "mcudich/TemplateKit"

Run carthage update, then make sure to add TemplateKit.framework, CSSLayout.framework, and CSSParser.framework to "Linked Frameworks and Libraries" and "copy-frameworks" Build Phases.

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate TemplateKit into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'TemplateKit', '~> 0.1.0'
end

Then, run the following command:

$ pod install

Requirements

  • iOS 9.3+
  • Xcode 8.0+
  • Swift 3.0+

Communication

  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

How does it work?

At its core, TemplateKit is comprised of Element and Node instances. Elements are used to describe trees of nodes, which can be anything that implements the Node interface. Nodes are used to vend out and manage view hierarchies.

Out of the box, there are several Node implementations that make it easy to set up UI hierarchies: Component, ViewNode, and a set of native controls like buttons, text labels, text fields and so on.

Building a component is as simple as subclassing Component, overriding its render() function, and deciding the set of properties it might accept and use as part of rendering. render() simply needs to return a Template, which can be constructed programmatically, or via an XML document (or other custom payload). When it comes time to render your component into a view, you simply call UIKitRenderer.render, and pass in the view that should contain your component's rendered output. This will in turn call render() on your component instance, compute the layout and styles for the view tree, build this tree and then apply the layout and styles to it as appropriate.

When it comes time to update your component's state, you can call updateState from within your component implementation. This function receives a function that is passed the current state value (each Component can declare a State type, in the same way it declares a Properties type). This function in turn enqueues an update to the component, which will cause it to re-render, taking into account whatever changes were made to the state. This update is intelligent, and compares the current incarnation of the rendered view tree against the proposed element tree. Only the deltas between these two are flushed out to the view layer.

Opaque Views

If there are parts of your UI that are easier to deal with as plain UIViews, TemplateKit provides a simple abstraction Node called ViewNode that allows you to include these "opaque" views as part of any TemplateKit-managed tree. TemplateKit stays out of the way, and simply sets the frame of these views for you, so they sit nicely within in whatever UI tree you've composed.

Collections

TemplateKit provides UITableView and UICollectionView subclasses which are able to load, and asynchronously size and render Components into cells with just a little bit of configuration. Tables and collections can be used via Table and Collection components, or simply wrapped as ViewNode instances. The Table and Collection components have built-in support for diffing, so that data-source updates result in the minimum set of operations required to have the respective UIKit views reflect data changes. See Diff.swift for more information.

How's this different from React Native?

TemplateKit is implemented in Swift (and a bit of C). If you like writing entirely in Swift, then this framework might be for you.

React Native relies on a very well-tested library (React), and has been shipping in popular apps for some time now. This means it probably has way fewer rough edges, has sorted out many performance issues TemplateKit has yet to face, and so on.

What's Missing

A lot.

There's no AppKit support yet (though it would be straightforward to add). Lots of tests have yet to be written. Performance testing has yet to be done. The entirety of the applicable CSS spec is not supported. Animation features are rudimentary at best. Many gesture types need to be added. And much more.

If you'd like something added, please file a feature request or send a pull request!

Inspiration

See Also

If TemplateKit isn't exactly what you're looking for, check out these other great projects!

Comments
  • Table component should be smarter about reloading data

    Table component should be smarter about reloading data

    Right now, it blindly reloads data any time it sees that item keys have changed. Instead, the table component should diff the item keys to understand the minimum set of operations it needs to perform to reload rows.

    opened by mcudich 1
  • List component

    List component

    Add a basic List component that supports simple use cases where a TableView might be used. Such a component would receive a delegate and data source as properties and would manage updating itself as needed.

    enhancement 
    opened by mcudich 1
  • Ability to

    Ability to "hide" components

    There currently is no way to hide a component (a la display: none in CSS). Hiding a component should remove it completely from layout calculations, but have it remain in the UI tree.

    enhancement 
    opened by mcudich 1
  • Animation support

    Animation support

    Support mutating property and state values over time, or via a gesture. Proper animation support would allow specifying things like transitions, keyframes, and so on. These need to be settable both via declarative and imperative syntax.

    enhancement 
    opened by mcudich 1
  • Add ability to specify animation transitions in CSS

    Add ability to specify animation transitions in CSS

    Using the standard CSS transition property. The component rendering this template would need to get access to whatever Animatables are constructed from the CSS property declarations so that it could animate them appropriately.

    enhancement animation 
    opened by mcudich 0
  • Add ability to compose Animatables

    Add ability to compose Animatables

    Right now you can only animate a single animatable, but not chain them or compose them in any way. Add some sort of AnimatableGroup object or something that would allow for this.

    enhancement animation 
    opened by mcudich 0
  • Allow styling components based on their current state

    Allow styling components based on their current state

    Right now, there's no way to specify a given set of styles that should be applied to a component when that component's state changes. This has to do with the fact that styles are passed as properties, and an internal state change is insulated within a component. This means that state may change, and the parent component, where the styles are defined, may not know about it.

    enhancement 
    opened by mcudich 0
Releases(0.1.0)
Owner
Matias Cudich
Matias Cudich
UIKit a-lΓ  SwiftUI.framework [min deployment target iOS10]

Render CoreRender is a SwiftUI inspired API for UIKit (that is compatible with iOS 10+ and ObjC). Introduction Declarative: CoreRender uses a declarat

Alex Usbergo 2.2k Dec 29, 2022
Small swift events kit

CoreEvents Small Swift events kit that provides some base types of events: FutureEvent PresentEvent PastEvent FutureEvent Simple event. Provides class

Surf 6 May 25, 2022
TemplateKit - React inspired framework for building component-based user interfaces in Swift

TemplateKit React-inspired framework for building component-based user interface

null 0 Feb 6, 2022
Carbon🚴 A declarative library for building component-based user interfaces in UITableView and UICollectionView.

A declarative library for building component-based user interfaces in UITableView and UICollectionView. Declarative Component-Based Non-Destructive Pr

Ryo Aoyama 1.2k Jan 5, 2023
🚴 A declarative library for building component-based user interfaces in UITableView and UICollectionView.

A declarative library for building component-based user interfaces in UITableView and UICollectionView. Declarative Component-Based Non-Destructive Pr

Ryo Aoyama 1.2k Jan 5, 2023
🦁 πŸƒ πŸ“± An animal matching puzzle card game– built with turn-based game engine boardgame.io and React-Native + React-Native-Web

Matchimals.fun an animal matching puzzle card game ?? ?? ?? Download for iOS from the App Store ?? Download for Android from the Google Play Store ??

iGravity Studios 137 Nov 24, 2022
Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if you are using Excel.

kishikawakatsumi/SpreadsheetView has moved! It is being actively maintained at bannzai/SpreadsheetView. This fork was created when the project was mov

Kishikawa Katsumi 34 Sep 26, 2022
Full configurable spreadsheet view user interfaces for iOS applications. With this framework, you can easily create complex layouts like schedule, gantt chart or timetable as if you are using Excel.

kishikawakatsumi/SpreadsheetView has moved! It is being actively maintained at bannzai/SpreadsheetView. This fork was created when the project was mov

Kishikawa Katsumi 34 Sep 26, 2022
Introducing SwiftUI. A declarative way to create User Interfaces with Swift.

SwiftUI - Landmarks Introducing SwiftUI. A declarative way to create User Interfaces with Swift. SwiftUI was introduced at WWDC 2019 by Apple. It is t

Alex Paul 8 Sep 21, 2021
Generate Swift code from Qt5 user interfaces.

Qlift-uic Description qlift-uic takes a Qt5 user interface description file and compiles it to Swift code for use with QLift. Splitted from main QLift

Dmitriy Borovikov 1 Apr 2, 2022
UIPheonix is a super easy, flexible, dynamic and highly scalable UI framework + concept for building reusable component/control-driven apps for macOS, iOS and tvOS

UIPheonix is a super easy, flexible, dynamic and highly scalable UI framework + concept for building reusable component/control-driven apps for macOS, iOS and tvOS

Mohsan Khan 29 Sep 9, 2022
A weather app developed in React Native. It is the React Native version of SwiftWeather.

ReactNativeWeather A weather app developed in React Native. It is the React Native version of SwiftWeather How to run the app Install react-native If

Jake Lin 22 Jun 7, 2022
Vahesaroyan-react-native-bubble-select - React native bubble picker

@vahesaroyan/react-native-bubble-select React native bubble picker Installation

Vahe Saroyan 0 Jan 30, 2022
Non-intrusive iOS UI library to implement overlay based interfaces

OverlayContainer is a UI library written in Swift. It makes easier to develop overlay based interfaces, such as the one presented in the Apple Maps, S

Applidium 1k Jan 4, 2023
Eat fit is a component for attractive data representation inspired by Google Fit

EatFit Check this article on our blog. Purpose Eat fit is a component for attractive data representation inspired by Google Fit. It is based on PageVi

Yalantis 657 Jan 5, 2023
This is PageControl Component for OS X. Inspired by UIPageControl and BFPageControl

NSPageControl This is PageControl Component for OS X. Inspired by UIPageControl and BFPageControl. Demo ##Installation NSPageControl supports multiple

Kohei Tabata 13 Jan 19, 2022
A demo project using VIPER architecture and building user interface programmatically

ProductDiscovery A demo project that building a UIKit user interface programmatically. Because the UI is made of code very long so I have separated it

Vinh Vo 7 Oct 1, 2021
A Demo using Vision Framework building on Core ML Framework

Core-ML-Sample A Demo using Core ML, Vision Framework and Swift 4. This demo is based on Inception V3 network. You must run it with Xcode 9 and iOS 11

ζ¨θ§ηŽ‰ 215 Nov 9, 2022
Swift tool to generate Module Interfaces for Swift projects.

ModuleInterface Swift tool to generate Module Interfaces for Swift projects. What is a Module Interface A Module Interface is what we commonly get usi

Jorge Revuelta 75 Dec 21, 2022