SwiftCrossUI - A cross-platform SwiftUI-like UI framework built on SwiftGtk.

Overview

SwiftCrossUI

A SwiftUI-like framework for creating cross-platform apps in Swift. It uses SwiftGtk as its backend.

This package is still quite a work-in-progress so don't expect it to be very useful or stable yet.

NOTE: SwiftCrossUI does not attempt to replicate SwiftUI's API because SwiftCrossUI is intended to be simpler than SwiftUI. However, many concepts from SwiftUI should still be transferrable.

Example

Here's a simple example app demonstrate how easy it is to get started with SwiftCrossUI:

import SwiftCrossUI

class CounterState: AppState {
    @Observed var count = 0
}

@main
struct CounterApp: App {
    let identifier = "dev.stackotter.CounterApp"
    
    let state = CounterState()
    
    let windowProperties = WindowProperties(title: "CounterApp")
    
    var body: some ViewContent {
        HStack {
            Button("-") { state.count -= 1 }
            Text("Count: \(state.count)")
            Button("+") { state.count += 1 }
        }
    }
}

To run this example, run these commands:

git clone https://github.com/stackotter/swift-cross-ui
cd swift-cross-ui
swift run CounterExample

To see all of the examples, run these commands:

swift run CounterExample
swift run RandomNumberGeneratorExample
swift run WindowPropertiesExample

Documentation

Here's the documentation site. Keep in mind that the project is still very much a work-in-progress, proper documentation and tutorials will be created once the project has matured a bit, because otherwise I have to spend too much time keeping the documentation up-to-date.

Dependencies

  1. Swift 5.5 or higher
  2. Gtk+ 3
  3. clang (only required on Linux)

macOS: Installing Gtk+ 3

Install Gtk+ 3 using homebrew or the package manager of your choice.

brew install gtk+3

Linux: Installing Gtk+ 3 and clang

Install Gtk+3 and Clang using apt or the package manager of your choice.

sudo apt install libgtk-3-dev clang

Usage

Just add SwiftCrossUI as a dependency in your Package.swift. See below for an example package manifest:

import PackageDescription

let package = Package(
  name: "Example",
  dependencies: [
    .package(url: "https://github.com/stackotter/swift-cross-ui", .branch("main"))
  ],
  targets: [
    .executableTarget(
      name: "Example",
      dependencies: [
        .product(name: "SwiftCrossUI", package: "swift-cross-ui")
      ]
    )
  ]
)
Comments
  • Basic Counter App project not working on linux

    Basic Counter App project not working on linux

    Hi, This is a really neat project and one that I'm definitely interested in contributing to.

    I tried creating a basic Counter App with the example Package.swift in the Readme.

    I got this error in my terminal when I ran swift build

    error: product 'SwiftGtk' required by 
    package 'swift-cross-ui' target 'SwiftCrossUI' not found.
    
    

    This is what my package.swift looks like

    // swift-tools-version:5.5
    // The swift-tools-version declares the minimum version of Swift required to build this package.
    
    import PackageDescription
    
    let package = Package(
        name: "Example",
        dependencies: [
                .package(url: "https://github.com/stackotter/swift-cross-ui", .branch("main"))
    
        ],
        targets: [
                 .executableTarget(
                name: "Example",
                 dependencies: [
            .product(name: "SwiftCrossUI", package: "swift-cross-ui")
          ]),
            .testTarget(
                name: "ExampleTests",
                dependencies: ["Example"]),
        ]
    )
    

    I'm running Pop OS which is a Ubuntu fork/derivative.

    opened by ajstrand 7
  • Implement more view types

    Implement more view types

    Currently only HStack, VStack, Button and Text are supported. The following view types would also be useful to have:

    • [x] TextField
    • [x] Slider
    • [x] ForEach
    • [x] Image

    If you think of any more, reply below.

    For reference on how to implement a container view, see the VStack implementation. For how to implement a non-container view, see the Button implementation.

    feature 
    opened by stackotter 3
  • Add WindowProperties to App protocol

    Add WindowProperties to App protocol

    Allows defining window properties from your app. Currently it has the following properties:

    • title

    • defaultWidth

    • defaultHeight

    • resizable

    title is required, while the other values are optional and default to the previously hard-coded values if not set.

    opened by NinjaCheetah 2
  • Setup SwiftLint

    Setup SwiftLint

    Linting is a great way of ensuring that a repository's code is neat. Setting up SwiftLint consists of two steps:

    • [x] Create the SwiftLint configuration file and decide which rules to use
    • [x] Create a GitHub action to automatically run SwiftLint
    enhancement 
    opened by stackotter 2
  • Create GitHub action

    Create GitHub action

    A GitHub action would be useful because it allows all supported platforms to be tested for each commit, making it a lot harder to break platform support.

    The following two GitHub actions would be the most useful:

    • [ ] SwiftLint
    • [x] swift build on macOS
    • [x] swift build on Linux
    enhancement 
    opened by stackotter 2
  • Critical errors logged by Gtk when closing an app

    Critical errors logged by Gtk when closing an app

    When closing the example app, the following output can be seen in the console:

    (<unknown>:58068): GLib-GObject-WARNING **: 08:43:20.945: instance with invalid (NULL) class pointer
    
    (<unknown>:58068): GLib-GObject-CRITICAL **: 08:43:20.945: g_signal_handler_disconnect: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
    
    (<unknown>:58068): GLib-GObject-WARNING **: 08:43:20.945: instance with invalid (NULL) class pointer
    
    (<unknown>:58068): GLib-GObject-CRITICAL **: 08:43:20.945: g_signal_handler_disconnect: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
    
    (<unknown>:58068): GLib-GObject-WARNING **: 08:43:20.945: instance with invalid (NULL) class pointer
    
    (<unknown>:58068): GLib-GObject-CRITICAL **: 08:43:20.945: g_signal_handler_disconnect: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
    
    (<unknown>:58068): GLib-GObject-WARNING **: 08:43:20.945: instance with invalid (NULL) class pointer
    
    (<unknown>:58068): GLib-GObject-CRITICAL **: 08:43:20.945: g_signal_handler_disconnect: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
    
    (<unknown>:58068): GLib-GObject-WARNING **: 08:43:20.945: instance with invalid (NULL) class pointer
    
    (<unknown>:58068): GLib-GObject-CRITICAL **: 08:43:20.945: g_signal_handler_disconnect: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed
    
    opened by stackotter 1
  • Add basic

    Add basic "Getting Started" documentation

    Here's some basic documentation for getting started, basically all pulled from the README. I mainly thought this would be helpful because it means you can find all of the info you need to start working on the documentation site. Definitely can reword anything that needs to be reworded.

    opened by NinjaCheetah 0
  • ci: Split workflow into two files to show statuses for both platforms

    ci: Split workflow into two files to show statuses for both platforms

    I split swift.yml into swift-macos.yml and swift-linux.yml so that you can have a badge for each in the README to show if a specific platform is failing. The images currently don't exist and are just question marks but that will be fixed once the workflows are there.

    opened by NinjaCheetah 0
  • Make certain view modifiers independent of order

    Make certain view modifiers independent of order

    Currently doing padding before frame produces different behaviour than padding after frame when the frame height is set such that the content can scroll (the padding is either inside or outside of the scrolling area). This is clearly not the intended behaviour and will have to be solved eventually.

    bug 
    opened by stackotter 0
  • Create Picker view

    Create Picker view

    SwiftUI has a Picker view that allows a user to select an option from a list, which is implemented by the Menu widget in Gtk. It'd be nice for SwiftCrossUI to have a dropdown menu type too (called Picker for consistency with SwiftUI).

    feature 
    opened by stackotter 0
  • Windows support

    Windows support

    Theoretically, SwiftCrossUI should work on Windows, but I haven't managed to install Gtk on Windows in a way that Swift can use yet. If you use Swift on Windows, you'll probably have more luck than I did! Feel free to try and get it running.

    If you do manage to get it working, please let us now how, so that we can setup a GitHub action for Windows builds. And if an code changes are required to get it running, just make a PR.

    help wanted 
    opened by stackotter 0
  • Don't update a widget unless its state has changed

    Don't update a widget unless its state has changed

    For example, currently buttons have their text updated every time the state of their parent view changes, which is completely unnecessary given that most of the time their label is static.

    This could be achieved by adding extra checks to the update function for each view type (currently only text and button implement this).

    enhancement 
    opened by stackotter 0
  • Support multiple windows

    Support multiple windows

    SwiftUI approaches this by having the body of App be of type some Scene where a scene can define windows using a result builder.

    The way I plan on approaching this is making App.body be of type some AppContent and having a Window struct that AppContentBuilder accepts. Then _App can setup the windows accordingly in run.

    feature 
    opened by stackotter 0
Owner
Creator of Delta Client. Loves Swift and Rust.
null
Custom segue for OSX Storyboards with slide and cross fade effects (NSViewControllerTransitionOptions)

CustomSegue Custom segue for OSX Storyboards. Slide and cross fade effects, new customized window. class MyViewController: NSViewController { overr

Eric Marchand 123 May 21, 2022
A multi-platform SwiftUI component for tabular data

SwiftTabler A multi-platform SwiftUI component for tabular data. NOTE this component is BRAND NEW and under active development. If you need stability,

OpenAlloc 45 Jan 3, 2023
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
Blobmorphism is a brand new design language I've created to break free of the material overload in iOS, built in SwiftUI. Everything feels smooth and fluid.

Blobmorphism is a brand new design language I've created to break free of the material overload in iOS, built in SwiftUI. Everything feels smooth and fluid.

Ethan Lipnik 89 Nov 29, 2022
A SwiftUI bottom-up controller, like in the Maps app. Drag to expand or minimize.

SwiftUI Drawer A SwiftUI bottom-up controller, like in the Maps app. Drag to expand or minimize. Contents Add the Package Basic Usage Examples Credits

Michael Verges 695 Jan 3, 2023
A simple Elm-like Store for SwiftUI, based on ObservableObject

ObservableStore A simple Elm-like Store for SwiftUI, based on ObservableObject.

Gordon Brander 28 Nov 8, 2022
A custom stretchable header view for UIScrollView or any its subclasses with UIActivityIndicatorView and iPhone X safe area support for content reloading. Built for iOS 10 and later.

Arale A custom stretchable header view for UIScrollView or any its subclasses with UIActivityIndicatorView support for reloading your content. Built f

Putra Z. 43 Feb 4, 2022
Convenient domain specific language for writing programmatic UI built over UIKit and more.

XYKit Swifty and convenient domain specific language for creating programmatic UI in a more declarative way and more than that. Built on top of UIKit

Denis Goloborodko 1 Nov 5, 2021
A fancy hexagonal layout for displaying data like your Apple Watch

Hexacon is a new way to display content in your app like the Apple Watch SpringBoard Highly inspired by the work of lmmenge. Special thanks to zenly f

Gautier Gédoux 340 Dec 4, 2022
A horizontal scroll dial like Instagram.

HorizontalDial Preview Requirements iOS 8.0+ Swift 5 Storyboard support Installation CocoaPods use_frameworks! pod "HorizontalDial" Manually To instal

Lee Sun-Hyoup 210 Nov 22, 2022
You can dismiss modal viewcontroller like Facebook Messenger by pulling scrollview or navigationbar in Swift.

PullToDismiss PullToDismiss provides dismiss modal viewcontroller function like Facebook Messenger by pulling scrollview or navigationbar with smooth

Suguru Kishimoto 479 Dec 5, 2022
RangeSeedSlider provides a customizable range slider like a UISlider.

RangeSeekSlider Overview RangeSeekSlider provides a customizable range slider like a UISlider. This library is based on TomThorpe/TTRangeSlider (Objec

WorldDownTown 644 Dec 12, 2022
SAHistoryNavigationViewController realizes iOS task manager like UI in UINavigationContoller. Support 3D Touch!

SAHistoryNavigationViewController Support 3D Touch for iOS9!! SAHistoryNavigationViewController realizes iOS task manager like UI in UINavigationConto

Taiki Suzuki 1.6k Dec 29, 2022
🍞 Toast for Swift - Toaster Android-like toast with very simple interface

Toaster Android-like toast with very simple interface. (formerly JLToast) Screenshots Features Queueing: Centralized toast center manages the toast qu

Suyeol Jeon 1.6k Jan 3, 2023
🔍 Awesome fully customize search view like Pinterest written in Swift 5.0 + Realm support!

YNSearch + Realm Support Updates See CHANGELOG for details Intoduction ?? Awesome search view, written in Swift 5.0, appears search view like Pinteres

Kyle Yi 1.2k Dec 17, 2022
A window arrangement manager for macOS like BetterSnapTool and Magnet

A window arrangement manager for macOS like BetterSnapTool and Magnet. You can split the foremost window to the left half of the screen, the left two-thirds, etc.

Takuto NAKAMURA (Kyome) 65 Dec 9, 2022
Add the Notch on the menubar like the new MacBook Pro.

iNotch Add the Notch on the menubar like the new MacBook Pro. Installation This app works on macOS 11.0 or later. Download iNotch.zip from releases pa

Takuto NAKAMURA (Kyome) 8 Apr 3, 2022
Fully customizable Facebook reactions like control

Reactions is a fully customizable control to give people more ways to share their reaction in a quick and easy way. Requirements • Usage • Installatio

Yannick Loriot 585 Dec 28, 2022