GithubHelp home page GithubHelp logo

theikchan / altswiftui Goto Github PK

View Code? Open in Web Editor NEW

This project forked from rakutentech/altswiftui

0.0 1.0 0.0 979 KB

Open Source UI framework based on SwiftUI syntax and features, adding backwards compatibility.

License: MIT License

Ruby 0.19% Objective-C 0.10% Swift 99.71%

altswiftui's Introduction

logo

Build Pod Swift Package Manager Xcode iOS Swift

Open Source UI framework based on SwiftUI syntax and features, adding backwards compatibility.

Compatibility

  • Minimum iOS version: iOS 11.0
  • SwiftUI: Not interchangeable, but easy to share knowledge and migrate code both ways because of the high similarity in syntax.
  • UIKit: Compatible
  • Xcode: From Xcode 12
  • Platforms: iOS, iPadOS

Features

An overview of supported features can be seen here.

Installation

Swift Package Manager

Add Package url: https://github.com/rakutentech/AltSwiftUI

Cocoapods

Add the following to your Podfile:

pod 'AltSwiftUI'

Documentation

The complete source documentation contains functionality covered by AltSwiftUI including its unique features.

Usage

AltSwiftUI has some small differences to SwiftUI, where it handles certain features slightly differently and adds some missing features as well.

Getting Started

You can use a AltSwiftUI view hierarchy the same as in SwiftUI with AppDelegate or SceneDelegate.

Create a UIHostingController with a root View, and add it to the Window. Even though the names are similar, don't forget you should import AltSwiftUI instead of SwiftUI.

View Structure

The structure of a View is very similar to that of SwiftUI, with 2 key differences:

struct ExampleView: View {
	var viewStore = ViewValues() // Difference 1

	var body: View { // Difference 2
		Text("Welcome")
	}
}
  1. In order for the library to internally store generic properties of a view, you need to provide a viewStore property initialized with an empty ViewValues for each view you create.

  2. To target backwards compatibility, opaque return types (some View) which is supported from iOS 13 are not used. Instead, explicity return types are used.

State and Rendering

State management works the same way as in SwiftUI. When a view declares a property attributed with a property wrapper, it will update the view's body when that property's value changes.

@State private var exampleText = "Original text"
@ObservedObject var myModel = MyModel()

var body: View {
	VStack {
		Text(exampleText)
		Text(myModel.value)

		Divider()
			.padding(.vertical, 10)

		MyView($myModel.value) // Will update the view when 'MyView' updates the value
		Button("Update text") {
			exampleText = "Updated text" // Will update the view on button action
		}
	}
}

HStack and Multiline Texts

When using Text without lineLimit inside a HStack, make sure that all other elements have their width specified. Failing to do so may introduce undesired layouts.

Previews

To work with previews, there are 2 steps that need to be done:

  1. Write the preview code at the end of the file that contains the view(s) you want to preview. This works similar to SwiftUI, but the preview must also conform to AltPreviewProvider.
#if DEBUG && canImport(SwiftUI)

import protocol SwiftUI.PreviewProvider
import protocol AltSwiftUI.View

struct MyTextPreview : AltPreviewProvider, PreviewProvider {
    static var previewView: View {
        MyText()
    }
}

#endif
  1. Load the canvas: As of now (Xcode 12 beta), in order to display the preview Canvas, Xcode requires that Editor > Canvas is enabled and the current file contains this line: import SwiftUI. Since AltSwiftUI files won't contain import SwiftUI, you must go to a file that contains it in order to open the Canvas, and then pin it so that you can use it with AltSwiftUI previews. Adding import SwiftUI to your file temporally to open the Canvas is also an option.

Name conflicts for ObservableObject and Published

If you end up importing Foundation, either directly or by an umbrella framework, and try to use ObservableObject or Published, Xcode will have a hard time solving the ambiguity as Foundation currently also defines these types as typealias.

To solve this, you can either specify the type like AltSwiftUI.ObservableObject every time you use it, or you can explicitly import these 2 types, which will help resolve the ambiguity:

import Foundation
import protocol AltSwiftUI.ObservableObject
import class AltSwiftUI.Published

class MyClass: ObservableObject {
	@Published var property: Bool
}

High Performance

In AltSwiftUI, certain view modifiers can cause views to update with high performance. Modifiers in this category will indicate it in their function documentation. You can also refer to the list below:

  • List.contentOffset(_:): When the list updates the value of the binding
  • ScrollView.contentOffset(_:): When the scroll view updates the value of the binding
  • State changes that happen inside the closure of a DragGesture.onChanged().

High performance updates won't update children views of List or ScrollView types. It's generally recommended for view subhierarchies that you want to modify by high performance updates to be moved to a separate View while passing the state that causes the update as a Binding.

There are also a couple of modifiers you can use to alter the default behavior of high performance updates and increase performance gains. For more information see List.ignoreHighPerformance(), ScrollView.ignoreHighPerformance(), View.strictHighPerformanceUpdate() and View.skipHighPerformanceUpdate() in the documentation.

Additional Features

Some of AltSwiftUI additional features are listed in this section.

Geometry Listener

In addition to the GeometryReader view, AltSwiftUI also offers a View.geometryListener(_:) property. This property records changes in a view's frame and stores it in a binding, which can then be referenced in any part of the hierarchy.

Unlike GeometryReader, geometryListener doesn't generate a new view.

@State private var geometryProxy: GeometryProxy = .default

VStack {
	Text("Example")
		.geometryListener($geometryProxy)

	Color.red
		.frame(width: geometryProxy.size.width)
}

Interactive Pop Gesture

Interactive pop gesture is also enabled by default for navigation views that have custom left bar button items and regardless if they show the navigation bar or not. To set this behavior to false in all cases, set UIHostingController.isInteractivePopGestureEnabled to false.

Get Involved

If you find any issues or ideas of new features/improvements, you can submit an issue in GitHub.

We also welcome you to contribute by submitting a pull request.

For more information, see CONTRIBUTING.

License

MIT license. You can read the LICENSE for more details.

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.