Rupert  Beatty

Rupert Beatty

1668130560

Pika: An Open-source Colour Picker App for MacOS

Pika

Pika (pronounced pi·kuh, like picker) is an easy to use, open-source, native colour picker for macOS. Pika makes it easy to quickly find colours onscreen, in the format you need, so you can get on with being a speedy, successful designer.

Screenshots of the dark and light Pika interface

Requirements

OS

  • macOS Catalina (Version 10.15+) and newer

Development

Getting started with contributing

Make sure you have mint installed, and bootstrap the toolchain dependencies:

brew install mint
mint bootstrap

Open Pika.xcodeproj and you should be good to go. If you run into any problems, please detail them in an issue.

Contributions

Any and all contributions are welcomed. Check for open issues, look through the project roadmap, and submit a PR.

Dependencies and thanks

And a huge thank you to Stormnoid for the incredible 2D vector field visualisation on Shadertoy.

Download the latest version of the app at superhighfives.com/pika.

Learn more about the motivations behind the project, and the product vision.

Download Details:

Author: Superhighfives
Source Code: https://github.com/superhighfives/pika 
License: MIT license

#swift #macos #app #xcode #swiftui 

Pika: An Open-source Colour Picker App for MacOS

Yoav Reisler

1667794173

Create Stylish Minimal App Animation Challenge Using SwiftUI 4.0

In this Video I'm going to teach how to create Stylish Minimal App Animation Challenge Using SwiftUI 4.0 | SwiftUI 3.0 Plant App UI | SwiftUI Snap Carousel | SwiftUI Animated Carousel | SwiftUI Complex UI | SwiftUI Complex Animations

► Timestamps
   0:00 Intro
   0:31 Project SetUp
   1:10 Building Custom Tab Bar
   5:32 Building Home View
   9:33 Implementing Snap Carousel
   16:18 Building Detail View With Animation's

► My MacBook Specs 
    M1 MacBook Pro(16GB)
    Xcode Version: 14.1 Beta
    macOS Version: 12.5 Monetary

► Source Code: https://www.patreon.com/posts/minimal-app-ui-73230695 

► Subscribe : https://www.youtube.com/Kavsoft?sub_confirmation=1 

#swift #swiftui 

Create Stylish Minimal App Animation Challenge Using SwiftUI 4.0

Yoav Reisler

1667793929

Create Stylish Coffee App With Complex Animations Using SwiftUI 4.0

In this Video I'm going to teach how to create Stylish Coffee App With Complex Animations Using SwiftUI 4.0 | SwiftUI Complex UI | SwiftUI Coffee App UI | SwiftUI Complex Animation | SwiftUI Animation Challenge.

► Timestamps
   0:00 Intro
   0:30 Project SetUp
   1:12 Building UI With Animation'

► My MacBook Specs 
    M1 MacBook Pro(16GB)
    Xcode Version: 14.1
    macOS Version: 13.0 Ventura

► Source Code: https://www.patreon.com/posts/early-access-app-74319204n 

► Subscribe For More: https://www.youtube.com/Kavsoft?sub_confirmation=1 

#swift #swiftui 

Create Stylish Coffee App With Complex Animations Using SwiftUI 4.0
Rupert  Beatty

Rupert Beatty

1667791579

Sample-food-truck: SwiftUI Sample Code From WWDC22

Food Truck: Building a SwiftUI multiplatform app

Create a single codebase and app target for Mac, iPad, and iPhone.

Overview

Using the Food Truck app, someone who operates a food truck can keep track of orders, discover the most-popular menu items, and check the weather at their destination. The sample implements the new NavigationSplitView to manage the app's views, Layout to show the main interface and pending orders, Charts to show trends, and WeatherService to get weather data. Food Truck also implements Live Activities to show the remaining order preparation time with ActivityKit on the lock screen, and with DynamicIsland on the home screen.

You can access the source code for this sample on GitHub.

The Food Truck sample project contains two types of app targets:

Simple app target you can build using personal team signing. This app runs in Simulator, and only requires a standard Apple ID to install on a device. It includes in-app purchase, and a widget extension that enable users to add a widget to their iOS Home Screen or the macOS Notification Center.

Full-featured Food Truck All app target. The full app runs in Simulator, and on devices with an Apple Developer membership. It also allows you to create and sign in with passkeys.

Configure the sample code project

To configure the Food Truck app without an Apple Developer account, follow these steps:

  1. In the Food Truck target's Signing & Capabilities panes click Add Account, and log in with your Apple ID.
  2. Chose Your Name (Personal Team) from the team menu for the Food Truck and Widgets targets.
  3. Build and run your app.
  4. On iOS and iPadOS devices navigate to Settings > General > VPN & Device Management and trust your developer certificate.

To configure the Food Truck All app to run on your devices, follow these steps:

  1. Open the sample with Xcode 14 or later.
  2. Select the top-level Food Truck project.
  3. For all targets, choose your team from the Team menu in the Signing & Capabilities pane, so Xcode can automatically manage your provisioning profile.
  4. Add the Associated Domains capability, and specify your domain with the webcredentials service. For more information about the webcredentials service, see Associated Domains Entitlement.
  5. Ensure an apple-app-site-association (AASA) file is present on your domain, in the .well-known directory, and it contains an entry for this app’s App ID for the webcredentials service. For more information about the apple-app-site-association file, see Supporting Associated Domains.
  6. In the AccountManager.swift file, replace all occurrences of example.com with the name of your domain.
  • Note: To use the weather forecast feature in the sample, you need to perform additional steps to configure WeatherKit, as described in the Configure the project for WeatherKit section below, or the sample will detect an error and use static data included in the project.

Create a multiplatform app

Food Truck is a multiplatform app, and there are no separate targets to run on macOS or iOS. Instead, there is only one app target that builds for macOS, iPadOS, and iOS.

Define a default navigation destination

The sample's navigation interface consists of a NavigationSplitView with a Sidebar view, and a NavigationStack:

NavigationSplitView {
    Sidebar(selection: $selection)
} detail: {
    NavigationStack(path: $path) {
        DetailColumn(selection: $selection, model: model)
    }
}

At app launch, the sample presents the TruckView as the default view. The Panel enum encodes the views the user can select in the sidebar, and hence appear in the detail view. The value corresponding to TruckView is .truck, and the app sets this to be the default selection.

@State private var selection: Panel? = Panel.truck

Construct a dynamic layout

In the Truck view, the New Orders panel shows the five most-recent orders, and each order shows a DonutStackView, which is a diagonal stack of donut thumbnails. The Layout protocol allows the app to define a DiagonalDonutStackLayout that arranges the donut thumbnails into the diagonal layout. The layout's placeSubviews(in:proposal:subviews:cache:) implementation calculates the donuts' positions.

for index in subviews.indices {
    switch (index, subviews.count) {
    case (_, 1):
        subviews[index].place(
            at: center,
            anchor: .center,
            proposal: ProposedViewSize(size)
        )
        
    case (_, 2):
        let direction = index == 0 ? -1.0 : 1.0
        let offsetX = minBound * direction * 0.15
        let offsetY = minBound * direction * 0.20
        subviews[index].place(
            at: CGPoint(x: center.x + offsetX, y: center.y + offsetY),
            anchor: .center,
            proposal: ProposedViewSize(CGSize(width: size.width * 0.7, height: size.height * 0.7))
        )
    case (1, 3):
        subviews[index].place(
            at: center,
            anchor: .center,
            proposal: ProposedViewSize(CGSize(width: size.width * 0.65, height: size.height * 0.65))
        )
        
    case (_, 3):
        let direction = index == 0 ? -1.0 : 1.0
        let offsetX = minBound * direction * 0.15
        let offsetY = minBound * direction * 0.23
        subviews[index].place(
            at: CGPoint(x: center.x + offsetX, y: center.y + offsetY),
            anchor: .center,
            proposal: ProposedViewSize(CGSize(width: size.width * 0.7, height: size.height * 0.65))
        )

Display a chart of popular items

The sample contains several charts. The most popular items are shown on the TopFiveDonutsView. This chart is implemented in TopDonutSalesChart, which uses a BarMark to construct a bar chart.

Chart {
    ForEach(sortedSales) { sale in
        BarMark(
            x: .value("Donut", sale.donut.name),
            y: .value("Sales", sale.sales)
        )
        .cornerRadius(6, style: .continuous)
        .foregroundStyle(.linearGradient(colors: [Color("BarBottomColor"), .accentColor], startPoint: .bottom, endPoint: .top))
        .annotation(position: .top, alignment: .top) {
            Text(sale.sales.formatted())
                .padding(.vertical, 4)
                .padding(.horizontal, 8)
                .background(.quaternary.opacity(0.5), in: Capsule())
                .background(in: Capsule())
                .font(.caption)
        }
    }
}

The x axis of the chart shows labels with the names and thumbnails of the items that correspond to each data point.

.chartXAxis {
    AxisMarks { value in
        AxisValueLabel {
            let donut = donutFromAxisValue(for: value)
            VStack {
                DonutView(donut: donut)
                    .frame(height: 35)
                    
                Text(donut.name)
                    .lineLimit(2, reservesSpace: true)
                    .multilineTextAlignment(.center)
            }
            .frame(idealWidth: 80)
            .padding(.horizontal, 4)
            
        }
    }
}

Obtain a weather forecast

The app shows a forecasted temperature graph in the Forecast panel in the Truck view. The app obtains this data from the WeatherKit framework.

.task(id: city.id) {
    for parkingSpot in city.parkingSpots {
        do {
            let weather = try await WeatherService.shared.weather(for: parkingSpot.location)
            condition = weather.currentWeather.condition
            willRainSoon = weather.minuteForecast?.contains(where: { $0.precipitationChance >= 0.3 })
            cloudCover = weather.currentWeather.cloudCover
            temperature = weather.currentWeather.temperature
            symbolName = weather.currentWeather.symbolName
            
            let attribution = try await WeatherService.shared.attribution
            attributionLink = attribution.legalPageURL
            attributionLogo = colorScheme == .light ? attribution.combinedMarkLightURL : attribution.combinedMarkDarkURL
            
            if willRainSoon == false {
                spot = parkingSpot
                break
            }
        } catch {
            print("Could not gather weather information...", error.localizedDescription)
            condition = .clear
            willRainSoon = false
            cloudCover = 0.15
        }
    }
}

Configure the project for WeatherKit

The data from the WeatherService instance in WeatherKit requires additional configuration for the Food Truck All target. If you don't configure WeatherKit, the sample will detect an error and use static data in the project instead.

  1. Create a unique App ID on the Provisioning Portal, and select the WeatherKit service on the App Services tab.
  2. In Xcode, for the Food Truck All target on the Signing & Capabilities tab, change the bundle ID to be the same as the App ID from step 1, and add the WeatherKit capability.
  3. For the Widgets target on the Signing & Capabilities tab, change the bundle ID to make the part before .Widgets the same as the bundle ID for the Food Truck All target.
  4. Wait 30 minutes while the service registers your app's bundle ID.
  5. Build and run the Food Truck All target.

Track preparation time with Live Activity

The app allows the food truck operator to keep track of order preparation time, which is guaranteed to be 60 seconds or less. To facilitate this, the app implements a toolbar button on the order details screen for orders with placed status. Tapping this button changes the order status to preparing, and creates an Activity instance to start a Live Activity, which shows the countdown timer and order details on an iPhone lock screen.

let timerSeconds = 60
let activityAttributes = TruckActivityAttributes(
    orderID: String(order.id.dropFirst(6)),
    order: order.donuts.map(\.id),
    sales: order.sales,
    activityName: "Order preparation activity."
)

let initialContentState = TruckActivityAttributes.ContentState(timerRange: Date.now...Date(timeIntervalSinceNow: Double(timerSeconds)))

do {
    let myActivity = try Activity<TruckActivityAttributes>.request(attributes: activityAttributes, contentState: initialContentState,
        pushType: nil)
    print(" Requested MyActivity live activity. ID: \(myActivity.id)")
    postNotification()
} catch let error {
    print("Error requesting live activity: \(error.localizedDescription)")
}

The app also implements DynamicIsland to show the same information as on the lock screen in the Dynamic Island on iPhone 14 Pro devices.

DynamicIsland {
    DynamicIslandExpandedRegion(.leading) {
        ExpandedLeadingView()
    }

    DynamicIslandExpandedRegion(.trailing, priority: 1) {
        ExpandedTrailingView(orderNumber: context.attributes.orderID, timerInterval: context.state.timerRange)
            .dynamicIsland(verticalPlacement: .belowIfTooWide)
    }
} compactLeading: {
    Image("IslandCompactIcon")
        .padding(4)
        .background(.indigo.gradient, in: ContainerRelativeShape())
       
} compactTrailing: {
    Text(timerInterval: context.state.timerRange, countsDown: true)
        .monospacedDigit()
        .foregroundColor(Color("LightIndigo"))
        .frame(width: 40)
} minimal: {
    Image("IslandCompactIcon")
        .padding(4)
        .background(.indigo.gradient, in: ContainerRelativeShape())
}
.contentMargins(.trailing, 32, for: .expanded)
.contentMargins([.leading, .top, .bottom], 6, for: .compactLeading)
.contentMargins(.all, 6, for: .minimal)
.widgetURL(URL(string: "foodtruck://order/\(context.attributes.orderID)"))

Tapping the same button again changes the status to complete, and ends the Live Activity. This removes the Live Activity from the lock screen and from the Dynamic Island.

Task {
    for activity in Activity<TruckActivityAttributes>.activities {
        // Check if this is the activity associated with this order.
        if activity.attributes.orderID == String(order.id.dropFirst(6)) {
            await activity.end(dismissalPolicy: .immediate)
        }
    }
}

Download Details:

Author: apple
Source Code: https://github.com/apple/sample-food-truck 

#swift #swiftui 

Sample-food-truck: SwiftUI Sample Code From WWDC22
Rupert  Beatty

Rupert Beatty

1667657520

Inject: Hot Reloading for Swift Applications!

Inject

Hot reloading workflow helper that enables you to save hours of time each week, regardless if you are using UIKit, AppKit or SwiftUI.

TLDR: A single line of code change allows you to live code UIKit screen:

https://user-images.githubusercontent.com/26660989/161756368-b150bc25-b66f-4822-86ee-2e4aed713932.mp4

Read detailed article about this

The heavy lifting is done by the amazing InjectionForXcode. This library is just a thin wrapper to provide the best developer experience possible while requiring minimum effort.

I've been using it for years.

What is hot reloading?

Hot reloading is a technique allowing you to get rid of compiling your whole application and avoiding deploy/restart cycles as much as possible, all while allowing you to edit your running application code and see changes reflected as close as possible to real-time.

This makes you significantly more productive by reducing the time you spend waiting for apps to rebuild, restart, re-navigate to the previous location where you were in the app itself, re-produce the data you need.

This can save you literal hours off development time, each day!

Does it add manual overhead to my workflows?

Once you configured your project initially, it's practically free.

You don’t need to add conditional compilation or remove Inject code from your applications for production, it's already designed to behave as no-op inlined code that will get stripped by LLVM in non-debug builds.

Which means that you can enable it once per view and keep using it for years to come.

Integration

Initial project setup

To integrate Inject just add it as SPM dependency:

via Xcode

Open your project, click on File → Swift Packages → Add Package Dependency…, enter the repository url (https://github.com/krzysztofzablocki/Inject.git) and add the package product to your app target.

via SPM package.swift

dependencies: [
    .package(
      name: "Inject",
      url: "https://github.com/krzysztofzablocki/Inject.git",
      from: "1.0.5"
    )
]

via Cocoapods Podfile

pod 'Inject'

Individual Developer setup (once per machine)

If anyone in your project wants to use injection, they only need to:

  • You must add "-Xlinker -interposable" (without the double quotes) to the "Other Linker Flags" of all targets in your project for the Debug configuration (qualified by the simulator SDK to avoid complications with bitcode), refer to InjectionForXcode documentation if you run into any issues
  • Download newest version of Xcode Injection from it's GitHub Page
  • Unpack it and place under /Applications
  • Make sure that the Xcode version you are using to compile our projects is under the default location: /Applications/Xcode.app
  • Run the injection application
  • Select open project / open recent from it's menu and pick the right workspace file you are using

After choosing the project in Injection app, launch the app

  • If everything is configured correctly you should see similar log in the console:
💉 InjectionIII connected /Users/merowing/work/SourceryPro/App.xcworkspace
💉 Watching files under /Users/merowing/work/SourceryPro

Workflow integration

You can either add import Inject in individual files in your project or use @_exported import Inject in your project target to have it automatically available in all its files.

SwiftUI

Just 2 steps to enable injection in your SwiftUI Views

  • call .enableInjection() at the end of your body definition
  • add @ObserveInjection var inject to your view struct

Remember you don't need to remove this code when you are done, it's NO-OP in production builds.

If you want to see your changes in action, you can enable an optional Animation variable on Inject.animation that will be used when ever new source code is injected into your application.

Inject.animation = .interactiveSpring()

Using Inject is demoed in this example app

UIKit / AppKit

For standard imperative UI frameworks we need a way to clean-up state between code injection phases.

I create the concept of Hosts that work really well in that context, there are 2:

  • Inject.ViewControllerHost
  • Inject.ViewHost

How do we integrate this? We wrap the class we want to iterate on at the parent level, so we don’t modify the class we want to be injecting but we modify the parent callsite.

Eg. If you have a SplitViewController that creates PaneA and PaneB , and you want to iterate on layout/logic code in PaneA, you modify the callsite in SplitViewController:

paneA = Inject.ViewHost(
  PaneAView(whatever: arguments, you: want)
)

That is all the changes you need to do, your app now allows you to change anything in PaneAView except for its initialiser API and the changes will be almost immediately reflected in your App.

Make sure to call initializer inside Inject.ViewControllerHost(...) or Inject.ViewHost(...). Inject relies on @autoclosure to reload views when hot-reload happens. Example:

// WRONG
let viewController = YourViewController()
rootViewController.pushViewController(Inject.ViewControllerHost(viewController), animated: true)

// CORRECT
let viewController = Inject.ViewControllerHost(YourViewController())
rootViewController.pushViewController(viewController, animated: true)

Remember you don't need to remove this code when you are done, it's NO-OP in production builds.

iOS 12

You need to add -weak_framework SwiftUI to Other Linker Flags for iOS 12 to work.

The Composable Architecture

If like myself you love PointFree Composable Architecture, you’d probably want to inject reducer code, this isn’t possible in vanilla TCA because reducer code is a free function which isn’t as straightforward to replace with injection, but our fork at The Browser Company supports it.

Download Details:

Author: krzysztofzablocki
Source Code: https://github.com/krzysztofzablocki/Inject 
License: MIT license

#swift #ios #hot #reload #swiftui 

Inject: Hot Reloading for Swift Applications!
Rupert  Beatty

Rupert Beatty

1667586600

SwiftUI-animations: Animations Created with SwiftUI

SwiftUI-Animations

Animations created with SwiftUI.

Hello there, I'm Shubham and in this repository, I'll be posting the code for the animations that you see on my Instagram @shubham_iosdev.

I hope you'll learn something new and use these animations and concepts to achieve great effects and more for your apps.

If you like my work, and would like to see more content you can follow me here 

Animations

Add to cart button

Cart view

Link for Code

Chat Bar Animation

Chat Bar

Link for Code

Wi-Fi connectivity Animation

Wi-Fi Signal

Link for Code

Loader Animation

Loader

Link for Code

AddItem Animation

addItem

[Link for Code]https://github.com/Shubham0812/SwiftUI-Animations/tree/master/SwiftUI-Animations/Code/Animations/AddView)

Circle Loader

circle loader

Link for Code

Pill Loader

pill loader

Link for Code

Like

like

Link for Code

Submit Button

submitButton

Link for Code

Github Octocat Loader

octocatLoader

Link for Code

3-D Rotating Loader

rotatingLoader

Link for Code

Animated Login Flow

rotatingLoader

Link for Code

Book loading Animation

bookLoadingAnimation

Link for Code

Card Viewer Animation

cardAnimation

Link for Code

Infinity Loader

infinityLoader

Link for Code

Light Switch

lightswitch

Link for Code

Spinning Loader

spinningLoader

Link for Code

Download Button

downloadButton

Link for Code

Triangle Loader

triangleLoader

Link for Code

Spread the word!

Liked the project? Just give it a star ⭐️ and spread the word!

Credits

© Shubham Kumar Singh | 2021

Download Details:

Author: Shubham0812
Source Code: https://github.com/Shubham0812/SwiftUI-Animations 
License: Apache-2.0 license

#swift #swiftui #ios #opensource 

SwiftUI-animations: Animations Created with SwiftUI
Kevin  Taylor

Kevin Taylor

1666914300

ReNest: A Simple React Add-on for You to Write React Like SwiftUI

🪺 ReNest

Let SwiftUI nests in React.

  • ✨ Write function components like React function components with original react hooks
  • 🎨 Write class components just like SwiftUI, elegant and modern
  • ⚡️ Partial re-render by default
  • 🌐 Powerful contexts that enables passing props through multiple levels of components
  • ⌨️ More features like Theme, Navigation; components like VStack/HStack/ZStack/Spacer; intergrating with React Native, EXPO, Taro ...

📦 Install

npm install @renest/renest

❓ What brings ReNest?

React is a great framework, and function hooks make it even more elegant. But not HTML or CSS! It's 2022! React uses jsx to replace the ugly HTML and CSS, but...... What the difference between JSX and HTML! Why can't we code modern?

That was what in my mind when I first used SwiftUI back in 2019. Though it was(and is still) just a toy and though I've heard its idea was exactly from React, still, it's modern and elegant. So why don't we take a little bit back to React? Here comes ReNest...

Here is an example to create a list of buttons using react functional jsx/swiftui/renest

Comparison

JSX

const JsxButtons = ({nums}:{nums:number[]}) => {
  let [toggle, setToggle] = useState(false)
  
  return (
    <div>
      {nums.map((num: number) => 
        <button 
          onClick={()=>{
            console.log(`This is button ${num}`)
            setToggle(prev=>!prev)      
          }}
        >
          {num}
        </button>)}
    </div>
  )
}

ReNest as function

const RTFuncButtons = FuncView(({nums}:{nums:number[]}) => {
  let [toggle, setToggle] = useState(false)

  return (
    List(nums, (num:number) =>
      Button(num)
        .onClick(() => {
          console.log(`This is button ${num}`)
          setToggle(prev=>!prev)
        })
    )
  )
})

Except the way ReNest sets props, everything is the same with React functions.

SwiftUI

struct SwiftButtons: View {
  var nums: [Int]
  @State toggle = false
  
  var body: some View {
    List(this.nums) { num in 
      Button(num) {
        print("This is button \(num)")
        this.toggle = !this.toggle
      }
    }
  }
}

ReNest as class

class RTClassButtons extends View {
  @Prop nums: number[]
  @State toggle = false
  
  Body = () => 
    List(this.nums, (num:number) =>
      Button(num)
        .onClick(() => {
          console.log(`This is button ${num}`)
          this.toggle = !this.toggle
        })
    )
}

Basically every prop in React and CSSProperty can be used in ReNest as 'dot' function, and IDEs will autocomplete for you!

if there's some specific properties from third-party components, use setProp(key, value)to set additional prop

⚡️ Quick Start

// ---- src/App.tsx
import RTApp from 'RTApp';
function App() {
  return RTApp().asReactElement()
}

export default App;
// ---- src/RTApp.ts
import {FuncView} from "@renest/renest";
import {Text, Button, VStack} from "@renest/component";
import {useState} from "react";

const MyComponent = FuncView(({defaultNum}: any) => {
  let [num, setNum] = useState(defaultNum)
  return (
      Button(num)
        .onClick(()=>{setNum(num+1)})
  )
})

const RTApp = FuncView(() =>
  VStack(
      MyComponent({defaultNum: 10}),
      Text("Hello")
  )
    .alignment("center")
)

export default RTApp;

Every ReNest instance can convert to React element using .asReactElement()

Every ReNest instance can take

  1. another ReNest instance
  2. a react element
  3. jsx element

but we strongly suggest you to use pure ReNest for additional features, use TagView/ElementView to wrap your React Components

🤖 Useful Features

TagView

  • Turn every react component into ReNest instance no matter if it's a custom react function or a html tag
const RTDiv = TagView("div")()
const RTComponent = TagView(YourReactFunction)()
  • use the second parameter to offer some acceptable dotProp
const Button = TagView("button", ["onTap"])
let NewButton = Button("title").onTap("whatever value here will be saved into props when creactElement")

ElementView

  • Turn a react component instance to ReNest instance
const myJSX = <div>hello</div>
const RTInstance = ElementView(myJSX)()

ConditionView

  • Use this view to build a dynamic controllable page simple and fast.
const MyCondition = FuncView(() => {
    const [displayIdx, setDisplayIdx] = useState(0)
    
    return (
        VStack(
            Button("change")
                .onClick(() => {
                    setDisplayIdx(prev=> prev==2 ? 0 : prev+1)
                }),
            ConditionView(displayIdx.value, {
                0: () => Text("This is the default view"),
                1: () => Text("This is view 1"),
                2: () => Text("This is the second view")
            })
        )
    )
})

Router

  • Using react-router 6, the NavigationView in ReNest is pretty easy to use and supports regex path (which react-router 6 doesn't).
const MyPage = FuncView(() =>
    VStack(
        Text("this will show whatever the route is"),
        NavigationView({
          "": () => Text("this is home"),
          "what": () =>  Text("this is what"),
          ":abc+": (path: string) => Text(`this matches abcccccc: ${path}`),
          ":": (path: string) => Text(`this matches everything else: ${path}`)
        })
    )
)

🔆 Cool Things

  • This is the part where we write react like SwiftUI and get to know some cool features!

Class Component

A ReNest class component looks like this

// extends View to write a class component
class Counter extends View {   
  // @Prop is a decorator, it means Counter component takes an optional prop startNum with default value 0
  // so when you use this component, call => Counter() or Counter({startNum: 100})
  @Prop startNum: number = 0    
  // another two decorators: @State and @Derived
  // @State means in Body, you can use this property as a state variable in react hook
  // so { @State count = 1 } visually equals to { [count.value, count.setValue] = useState(1) }
  // @Derived takes another decorator as its argument
  // if we did't use @Derived, { @State count = this.startNum } would always equal to { @State count = 0 } because 0 is startNum's default value
  // so we use @Derived to get the updated value(set as prop from outside) in Body
  @Derived(State) count: any = () => this.startNum
 
  // the Body is just a clousure property, you can always do any logical things in Body to make it look like a function component and use any react hooks as you want, but that would miss the point to code elegantly
  Body = () =>
    VStack(
      HStack(
        Button("+")
          .onClick(() => {
            this.count ++
          }),
        Button("-")
          .onClick(() => {
            this.count --
          })
        )
          .spacing("20px"),
      Text(this.count),
      Button("clear")
        .onClick(() => {
          this.count = this.startNum
        })
    )
      .alignment("center")
}

export default ViewWrapper<{startNum?: number}>(Counter)

decorators

  1. @Ref text = "ok" <=> let text = useRef("ok")
  2. @State count = 1 <=> [count.value, count.setValue] = useState(1)
  3. @Hook(useAnyHook) value = "default" <=> let value = useAnyHook("default")
  4. @SHook(useMultiProps) value = ["prop1", "prop2"] <=> let value = useMultiProps("prop1", "prop2")
  5. @Prop myProp: string => call MyComponent({myProp: "fine"})
  6. @DotProp myDotProp: string => call MyComponent().myDotProp("any value")

ContextProvider

  • Use ContextProvider in ReNest to manage global states simple and powerful.
  • Use @Context to destructure the whole context into a specific variable
  • Use @Contexts to get the whole context
import {ContextProvider, ViewWrapper, View} from "@renest/renest";
class ComponentA extends View {
  @Context myFirstContext: any
  
  Body = () =>
      Text(`Current first state value is ${this.myFirstContext}`),
}

const ComponentAView = ViewWrapper(ComponentA)

class MyComponentWithContext extends View {
  @State myFirstContext = 0
  
  Body = () =>
    ContextProvider(
      VStack(
        Button("add")
        	.onClick(() => {
            this.myFirstContext
					})
        ComponentAView()
      )
    )
      .context({myFirstContext: this.myFirstContext})
}

ThemeProvider

  • Use ThemeProvider as a global state to manage any theme ralated props
  1. Theme in class component
class Paper extends View {
  defaultTheme = {
    bg: "#FBFCFC",
    shadow: "#E1E5E4"
  }

  Body = () =>
    Div()
      .backgroundColor(this.theme.bg)
      .width("200px")
      .height("280px")
      .borderRadius("7px")
      .boxShadow(`2px 2px 4px 1px ${this.theme.shadow}`)
}

export default ViewWrapper(Paper)

or

class Paper extends View {
  defaultThemes = {
    gray: {
      bg: "#FBFCFC",
      shadow: "#E1E5E4"
    },
    red: {
      bg: "#F1B1B1",
      shadow: "#832525"
    }
  }
  defaultThemeName = "gray"

  Body = () =>
    Div()
      .backgroundColor(this.theme.bg)
      .width("200px")
      .height("280px")
      .borderRadius("7px")
      .boxShadow(`2px 2px 4px 1px ${this.theme.shadow}`)
}

export default ViewWrapper(Paper)

// call to use red theme
Paper()
  .themeName("red")
  1. ThemeProvider
class MyComponentWithContext extends View {
  // default using class name(in this case is Paper) to set different theme for different class
  // if you don't want some class to be polluted, use a themeTag() to add a appendix(in this case is Paper_another)
  // @Theme in hook equals to useTheme(themes, initialThemeName)
  // any element inside ThemeProvider can directly current "myThemes" by using this.themeState to change theme
  @Theme myThemes = [{
    firstTheme: {
      Paper: {
        bg: "#118811",
        shadow: "#AAAA00"
      }
    },
    secondTheme: {
      Paper: {
        bg: "#22FFAA",
        shadow: "#997700"
      },
      Paper_another: {
        bg: "#22FFAA",
        shadow: "#997700"
      },
    }
  }, "secondTheme"]  // set initial theme as secondTheme
  
  Body = () =>
    ThemeProvider(
      VStack(
        Paper(),
        Paper()
          .themeTag("another")  // only have secondTheme, when themeName == firstTheme, using defeaultTheme inside Paper class
        Button("change theme")
          .onClick(() => {
            // use myThemes.is("xx") to check current theme name
            // use myThemes.themeName to get current theme name
            // use myThemes.to("xx") to change theme
            if (this.myThemes.is("firstTheme")) {
              this.myThemes.to("secondTheme")
            } else {
              this.myThemes.to("firstTheme")
            }
          })
      )
    )
      .useTheme(this.myThemes)
}

Lifecycle

  • React function uses useEffect to handle lifecycles, so you can still use it (remember, class's Body is nothing but a react function component, but we don't write any logical code blocks inside Body for the sake of love)
  • So ReNest handles lifecycles this way (and adds a strong feature: component wise lifecycles)
class SubComponent extends View {  
  Body = () =>
    Text("not related to MainComponent's states")
}

const SubComponentView = ViewWrapper(CoSubComponentmponentA)

class MainComponent extends View {
  @State toggle: any = false
  
  Body = () =>
    VStack(
      Button("refresh")
        .onClick(() => {
          this.toggle = !this.toggle
        })
      SubComponentView()
        .didUpdate(() => {
          console.log("re-rendered as subview")  // this will not be called when click refresh button => so called element-wise lifecycle
        })
    )
      .didMount(() => {
        console.log("mounted")
      })
      .didUpdate(() => {
        console.log("re-rendered")
      })
      .willUnmount(() => {
        console.log("will unmount")
      })
      .shouldUpdate((prevProps, currProps) => false)  // this equals to React.memo(xx, shouldUpdate)
}
  • Only Component that defined by a FuncView or View can use lifecycles, tags like Div, P, ... don't have this dot function
  • As the example above, remember the lifecycle is VStack and SubComponentView's, not MainComponent's
  • If you want to set MainComponent's lifecycle, you can do it this way
class SubComponent extends View {  
  Body = () =>
    Text("not related to MainComponent's states")
}

const SubComponentView = ViewWrapper(CoSubComponentmponentA)

class MainComponent extends View {
  @State toggle = false
  
  Body = () =>
    VStack(
      Button("refresh")
        .onClick(() => {
          this.toggle = !this.toggle
        })
      SubComponentView()
    )
    
  didMount: () => {
    console.log("mounted")
  }
  didUpdate: () => {
    console.log("re-rendered at any value")
  }
  willUnmount: () => {
    console.log("will unmount")
  })
  shouldUpdate: (prevProps, currProps) => false
  
}
  • @Observe: you can use this to observe any prop/dotProp/state
class Counter extends View {
  @State count: = 0
  @Observe $count = () => {
    console.log("log this every time click refresh")
  }
  
  Body = () =>
      Button("refresh")
        .onClick(() => {
          this.count ++
        })

  

Converter

  • You may need some 3rd ui libraries to provide some off-the-shelf components, to use this, for example, you can simply use TavView(tag, ...DotPropNames). However, if you're using a lot, this is exhausting, now we provide a function called Converter, the first prop is a Dict of tags, and the second is dotPropNames
const {Div, Button, P, WhateverSpan} = Converter(
{
  Div: "div",
  Button: "button",
  P: "p",
  WhateverSpan: "span"
}, {
  Div: ["goodBye", "look"]
})
  • Now you can use it anywhere in ReNest
let allGood = FuncView(() =>
  Div(
    Button("ok"),
    WhateverSpan("ha")
  )
    .look("don't look at me")
)
  • Suggest you to write a new file Convert.ts which contains all the tag you need, and import it from elsewhere
import {Converter} from "@renest/renest";

export const {Div, Button, Span, P} = Converter(
{
    Div: "div",
    Button: "button",
    Span: "span",
    P: "p"
})

Todo List

  •  Find a better way to debug and throw error
  •  Improve performance

Download Details:

Author: Re-Nest
Source Code: https://github.com/Re-Nest/ReNest

License: MIT license

#react #swiftui 

ReNest: A Simple React Add-on for You to Write React Like SwiftUI
Rupert  Beatty

Rupert Beatty

1666285080

RedditOS: A SwiftUI Reddit Client for MacOS

RedditOS

A SwiftUI Reddit client for macOS

About

This project is about two things:

  1. Building a good Reddit client.
  2. Building a good macOS application using mostly SwiftUI.

You'll need the latest version of Xcode 12 and macOS Big Sur to build it and enjoyt it. You can also download a pre built version in the release section if you don't want to build it youself.

I'm planning to drop Big Sur in the near future to focus execlusively on SwiftUI 3 + macOS Monterey. SwiftUI 3 add a ton of features, polish and performance improvements that this application can't live without.

Dev environment

If you want to login with your Reddit account building the project from the source you'll need to create a file secrets.plist in Packages/Backend/Sources/Backend/Resources with your Reddit app id as client_id key/value. Create an reddit app here and use redditos://auth as redirect url.

Image

Download Details:

Author: Dimillian
Source Code: https://github.com/Dimillian/RedditOS 
License: Apache-2.0 license

#swift #macos #reddit #swiftui 

RedditOS: A SwiftUI Reddit Client for MacOS
Rupert  Beatty

Rupert Beatty

1666261380

Clean Architecture for SwiftUI + Combine

Articles related to this project


Clean Architecture for SwiftUI + Combine

A demo project showcasing the setup of the SwiftUI app with Clean Architecture.

The app uses the restcountries.com REST API to show the list of countries and details about them.

Check out mvvm branch for the MVVM revision of the same app.

For the example of handling the authentication state in the app, you can refer to my other tiny project that harnesses the locks and keys principle for solving this problem.

Diagram

Key features

  • Vanilla SwiftUI + Combine implementation
  • Decoupled Presentation, Business Logic, and Data Access layers
  • Full test coverage, including the UI (thanks to the ViewInspector)
  • Redux-like centralized AppState as the single source of truth
  • Data persistence with CoreData
  • Native SwiftUI dependency injection
  • Programmatic navigation. Push notifications with deep link
  • Simple yet flexible networking layer built on Generics
  • Handling of the system events (such as didBecomeActive, willResignActive)
  • Built with SOLID, DRY, KISS, YAGNI in mind
  • Designed for scalability. It can be used as a reference for building large production apps

Architecture overview

Diagram

Presentation Layer

SwiftUI views that contain no business logic and are a function of the state.

Side effects are triggered by the user's actions (such as a tap on a button) or view lifecycle event onAppear and are forwarded to the Interactors.

State and business logic layer (AppState + Interactors) are natively injected into the view hierarchy with @Environment.

Business Logic Layer

Business Logic Layer is represented by Interactors.

Interactors receive requests to perform work, such as obtaining data from an external source or making computations, but they never return data back directly.

Instead, they forward the result to the AppState or to a Binding. The latter is used when the result of work (the data) is used locally by one View and does not belong to the AppState.

Previously, this app did not use CoreData for persistence, and all loaded data were stored in the AppState.

With the persistence layer in place we have a choice - either to load the DB content onto the AppState, or serve the data from Interactors on an on-demand basis through Binding.

The first option suits best when you don't have a lot of data, for example, when you just store the last used login email in the UserDefaults. Then, the corresponding string value can just be loaded onto the AppState at launch and updated by the Interactor when the user changes the input.

The second option is better when you have massive amounts of data and introduce a fully-fledged database for storing it locally.

Data Access Layer

Data Access Layer is represented by Repositories.

Repositories provide asynchronous API (Publisher from Combine) for making CRUD operations on the backend or a local database. They don't contain business logic, neither do they mutate the AppState. Repositories are accessible and used only by the Interactors.


Download Details:

Author: Nalexn
Source Code: https://github.com/nalexn/clean-architecture-swiftui 
License: MIT license

#swift #clean #architecture #swiftui 

Clean Architecture for SwiftUI + Combine
Debbie Clay

Debbie Clay

1663833813

Build UBER Clone with SwiftUI

In this tutorial, you'll learn how to build UBER Clone with SwiftUI.

Feature list: 
👉  Display the user's location on a responsive map view with SwiftUI
👉  Search for locations with an incredible auto complete feature
👉  Select a location to request a ride
👉  Build a beautiful user interface with custom pricing models, ride types and more!
👉  Add annotations and get directions on map

What is SwiftUI?

SwiftUI helps you build great-looking apps across all Apple platforms with the power of Swift — and surprisingly little code. You can bring even better experiences to everyone, on any Apple device, using just one set of tools and APIs.

SwiftUI provides views, controls, and layout structures for declaring your app’s user interface. The framework provides event handlers for delivering taps, gestures, and other types of input to your app, and tools to manage the flow of data from your app’s models down to the views and controls that users see and interact with.

Define your app structure using the App protocol, and populate it with scenes that contain the views that make up your app’s user interface. Create your own custom views that conform to the View protocol, and compose them with SwiftUI views for displaying text, images, and custom shapes using stacks, lists, and more. Apply powerful modifiers to built-in views and your own views to customize their rendering and interactivity. Share code between apps on multiple platforms with views and controls that adapt to their context and presentation.

An illustration of an app built using SwiftUI running on the Mac and iPhone.

You can integrate SwiftUI views with objects from the UIKit, AppKit, and WatchKit frameworks to take further advantage of platform-specific functionality. You can also customize accessibility support in SwiftUI, and localize your app’s interface for different languages, countries, or cultural regions.

🕐 TIMESTAMPS:
00:00 - Intro
05:34 - Source code 
06:37 - Project setup & Showing user location on map
31:20 - Uber SwiftUI Pro Demo
37:35 - Location Search UI
1:06:13 - Searching for locations
1:22:04 - Selecting a location 
1:37:22 - Getting location coordinates
1:47:59 - Adding annotation to map
1:57:32 - Generating route to destination
2:11:26 - MapView state management 
2:38:09 - Ride Request View UI
2:57:46 - Presentation logic for Ride Request View
3:10:44 - Ride type data model
3:27:55 - Pricing model
3:52:31 - Adding trip data to ride request view
4:05:29 - Dark mode support & bug fixes

🖥️ CODE + RESOURCES

🔴 Uber SwiftUI Pro Source Code (contains additional features): 
https://www.stephancodes.com/product-page/uber-swiftui 

🔴 Project assets & images: 
https://drive.google.com/file/d/1a9UdliiC5hyIuq_k1KTYqMZxi4XMSLpI/view?usp=sharing 

🔴 MVVM Diagram:
https://drive.google.com/file/d/1N8aD4I4xks5vDAt-c97ZyV7UK5VAG5SV/view?usp=sharing 

#swiftui #swift

Build UBER Clone with SwiftUI

Yoav Reisler

1663572371

How to Use SwiftUI's Canvas to Make fun Shape-Morphing Animations

In this video, we'll show you how to use SwiftUI's Canvas to make fun shape-morphing animations.

► Timestamps
   0:00 Intro
   0:29 Project SetUp
   1:00 Building UI
   5:06 Shape Morphing Animation

► My MacBook Specs 
    M1 MacBook Pro(16GB)
    Xcode Version: 14.1 Beta
    macOS Version: 12.5.1 Monetary

► Source Code: https://www.patreon.com/posts/early-access-14-72158573 

► Subscribe For More: https://www.youtube.com/Kavsoft?sub_confirmation=1 

#swiftui 

How to Use SwiftUI's Canvas to Make fun Shape-Morphing Animations
Aketch  Rachel

Aketch Rachel

1663252800

Suggest 7 Most Popular Colors in SwiftUI Libraries

In this SwiftUi article, let's learn about Colors: Suggest 7 Most Popular Colors in SwiftUi Libraries

Table of contents:

  • PrettyColors - Styles and colors text in the Terminal with ANSI escape codes. Conforms to ECMA Standard 48.
  • SheetyColors - An action sheet styled color picker for iOS.
  • SwiftGen-Colors - A tool to auto-generate enums for your UIColor constants.
  • SwiftHEXColors - HEX color handling as an extension for UIColor.
  • UIColor-Hex-Swift - Hex to UIColor converter.
  • UIGradient - A simple and powerful library for using gradient layer, image, color.

What is SwiftUI color?

SwiftUI only resolves a color to a concrete value just before using it in a given environment. This enables a context-dependent appearance for system defined colors, or those that you load from an Asset Catalog. For example, a color can have distinct light and dark variants that the system chooses from at render time.


Suggest 7 Most Popular Colors in SwiftUI Libraries

  1. PrettyColors

PrettyColors is a Swift library for styling and coloring text in the Terminal. The library outputs ANSI escape codes and conforms to ECMA Standard 48.

Example

import PrettyColors

let redText: String = Color.Wrap(foreground: .red).wrap("A red piece of text.")
println(redText)

Color.Wrap(foreground: .yellow, style: .bold)
Color.Wrap(foreground: .green, background: .black, style: .bold, .underlined)

// 8-bit (256) color support
Color.Wrap(foreground: 114)
Color.Wrap(foreground: 114, style: .bold)

More examples can be found in the tests.

Installation

Carthage

Add the following to your Cartfile:

github "jdhealy/PrettyColors"

CocoaPods

Add the following to your Podfile:

pod 'PrettyColors', :git => 'https://github.com/jdhealy/PrettyColors'

You will also need to make sure you're opting into using frameworks:

use_frameworks!

Then run pod install with CocoaPods 0.36 or newer.

View on GitHub


2.  SheetyColors

SheetyColors is an action sheet styled color picker for iOS:

  • 📱 Based on UIAlertController: The SheetyColors API is based on UIKit's UIAlertController. Simply add buttons to it as you would for any other Action Sheet by defining UIAlertAction instances. Therefore, it nicely integrates with the look & feel of all other native system dialogs. However, you can also chose to use the color picker it self without an action sheet.
  • 🎨 Fully configurable: You can choose between a variety of configurations such as
    • color model (RGB, HSB, or Grayscale)
    • alpha component support
    • haptic feedback
    • text/message label
  • 🎚️ Sliders and Hex input: You can create new colors by either using sliders or the newly added Hex input.
  • 👶 Intuitive UI: Each slider comes with a gradient that gives you an idea of how changing individual slider values affects the resulting color. All controls do support haptic feedback and will react to any errors such as invalid Hex values.
  • 🍏 SwiftUI & iOS 13 support: SheetyColors can also be used as part of your SwiftUI projects. Have a look at the Usage section to get further info. The library is also optimized to work well with the new Dark Mode.

Installation

There are currently four different ways to integrate SheetyColors into your apps.

CocoaPods

use_frameworks!

target 'MyApp' do
  pod 'SheetyColors'
end

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/chrs1885/SheetyColors.git", from: "1.2.1")
]

Carthage

github "chrs1885/SheetyColors"

View on GitHub


3.  SwiftGen

SwiftGen is a tool to automatically generate Swift code for resources of your projects (like images, localised strings, etc), to make them type-safe to use.

There are multiple benefits in using this:

  • Avoid any risk of typo when using a String
  • Free auto-completion
  • Avoid the risk of using a non-existing asset name
  • All this will be ensured by the compiler and thus avoid the risk of crashing at runtime.

Also, it's fully customizable thanks to Stencil templates, so even if it comes with predefined templates, you can make your own to generate whatever code fits your needs and your guidelines!

Configuration File

❗️ If you're migrating from older SwiftGen versions, don't forget to read the Migration Guide.

SwiftGen is provided as a single command-line tool which uses a configuration file to define the various parsers to run (depending on the type of input files you need to parse) and their parameters.

To create a sample configuration file as a starting point to adapt to your needs, run swiftgen config init.

Each parser described in the configuration file (strings, fonts, ib, …) typically corresponds to a type of input resources to parse (strings files, IB files, Font files, JSON files, …), allowing you to generate constants for each types of those input files.

To use SwiftGen, simply create a swiftgen.yml YAML file (either manually or using swiftgen config init) then edit it to adapt to your project. The config file should list all the parsers to invoke, and for each parser, the list of inputs/outputs/templates/parameters to use for it.

For example:

strings:
  inputs: Resources/Base.lproj
  outputs:
    - templateName: structured-swift5
      output: Generated/Strings.swift
xcassets:
  inputs:
    - Resources/Images.xcassets
    - Resources/MoreImages.xcassets
    - Resources/Colors.xcassets
  outputs:
    - templateName: swift5
      output: Generated/Assets.swift

Then you just have to invoke swiftgen config run, or even just swiftgen for short, and it will execute what's described in the configuration file.

View on GitHub


4.  SwiftHEXColors

HEX color handling as an extension for UIColor. Written in Swift.

Examples

iOS

// With hash
let color: UIColor = UIColor(hexString: "#ff8942")

// Without hash, with alpha
let secondColor: UIColor = UIColor(hexString: "ff8942", alpha: 0.5)

// Short handling
let shortColorWithHex: UIColor = UIColor(hexString: "fff")

For those who don't want to type the double quotation, you can init a color from a real hex value (an Int)

// With hash
let color: UIColor = UIColor(hex: 0xff8942)

// Without hash, with alpha
let secondColor: UIColor = UIColor(hex: 0xff8942, alpha: 0.5)

OSX

// With hash
let color: NSColor = NSColor(hexString: "#ff8942")

// Without hash, with alpha
let secondColor: NSColor = NSColor(hexString: "ff8942", alpha: 0.5)

// Short handling
let shortColorWithHex: NSColor = NSColor(hexString: "fff")

// From a real hex value (an `Int`)
// With hash
let color: NSColor = NSColor(hex: 0xff8942)

// Without hash, with alpha
let secondColor: NSColor = NSColor(hex: 0xff8942, alpha: 0.5)

Installation

Swift Package Manager

Add this as a dependency in your Package.swift:

import PackageDescription

let package = Package(
    name: "MyPackage",
        dependencies: [
        // Other dependencies
	.package(url: "https://github.com/thii/SwiftHEXColors.git", from: "1.3.1")
    ]
)

View on GitHub


5.  UIColor-Hex-Swift

Convenience method for creating autoreleased color using RGBA hex string.

    // Solid color
    let strokeColor = UIColor("#FFCC00").cgColor

    // Color with alpha
    let fillColor = UIColor("#FFCC00DD").cgColor

    // Supports shorthand 3 character representation
    let backgroundColor = UIColor("#FFF")

    // Supports shorthand 4 character representation (with alpha)
    let menuTextColor = UIColor("#013E")

    // "#FF0000FF"
    let hexString = UIColor.red.hexString()

    // Convert shorthand 4 character representation (with alpha) from argb to rgba
    if let rgba = "#AFFF".argb2rgba {
        let androidBackgroundColor = UIColor(rgba)
    }

    // Convert 8 character representation (with alpha) from argb to rgba
    if let rgba = "#AAFFFFFF".argb2rgba {
        let androidFrontColor = UIColor(rgba)
    }

Release Notes

  • Upgrade to Swift 5.
  • macOS gets supported.

Installation

Swift Package Manager

To add a package dependency to your Xcode project, select File > Swift Packages > Add Package Dependency and enter https://github.com/yeahdongcn/UIColor-Hex-Swift to the text field.

CocoaPods

Simply add the following lines to your Podfile:

# required by CocoaPods 0.36.0.rc.1 for Swift Pods
use_frameworks!

pod 'UIColor_Hex_Swift', '~> 5.1.9'

View on GitHub


6.  UIGradient

A simple and powerful library for using gradient layer, image, color

Installation

SPM

Add https://github.com/sindresorhus/Defaults to Swift Package Manager tab in Xcode

Cocoapods

Add pod 'UIGradient' to your Podfile

Usage

GradientLayer

Create a GradientLayer then add it to your view's

public extension UIView {

    func addGradientWithDirection(_ direction: GradientDirection, colors: [UIColor], cornerRadius: CGFloat = 0, locations: [Double]? = nil)

    func addGradient(_ gradientLayer: GradientLayer, cornerRadius: CGFloat = 0)
	
}

Example

let gradient = GradientLayer(direction: GradientDirection, colors: [UIColor])
view.addGradient(gradient)

UIGradient supports those directions below:

public enum GradientDirection {
    case topToBottom // top to bottom
    case bottomToTop // bottom to top
    case leftToRight // left to right
    case rightToLeft // right to left
    case topLeftToBottomRight // top left to bottom right
    case topRightToBottomLeft // top right to bottom left
    case bottomLeftToTopRight // bottom left to top right
    case bottomRightToTopLeft // bottom right to top left
}

You can also create a GradientLayer clone instance using this function:

open class GradientLayer: CAGradientLayer {
    ...
    public final func clone() -> GradientLayer
    ...
}

View on GitHub


Frequently asked questions about Colors of Swift

  • What is UIColor?

UIColor provides a list of class properties that create adaptable and fixed colors such as blue, green, purple, and more. UIColor also offers properties to specify system-provided colors for UI elements such as labels, text, and buttons.

  • How do I add color in Swift?

There are two ways to use your custom colors in Swift UI. Select your object in device preview. Choose “Color” under the attributes inspector. Your custom colors now show at the bottom of the list!

  • What are system colors?

A color system is a set of colors that represent a specific visual spectrum. * These few colors are mixed together to create a limited usable range, and that range is called a color system. Examples of a color system include RGB, CMYK, and Lab.


Related videos:

Color, UIColor, Color Literals, and Hex Colors in SwiftUI


Related posts:

#swift #swiftui 

Suggest 7 Most Popular Colors in SwiftUI Libraries
Joshua Yates

Joshua Yates

1662598959

Build a Movie Booking App with SwiftUI and Figma

This tutorial shows how to build a movie booking app with SwiftUI and Figma. Create an iOS app based on a design in Figma. Learn to create the Tinder-like card swipe interaction with custom design using the drag gesture. 

Additionally, we will create a custom tab bar and use Navigation Views to build a whole flow.

Chapters
[0:00] 1 - Intro
07:22] 2 -  Ticket Model
[12:26] 3 - Ticket Stack
[23:48] 4 - Drag Gesture
[29:48] 5 -Custom Tab Bar
[35:12] 6 -Tab Bar Animation
[41:45] 7 - Custom Search Bar
[46:11] 8 - Scroll Section
[51:15] 9 - Navigation
[01:03:38] 10 - Button Layout
[01:08:24] 11 - Seats View
[01:13:07] 12 Pop To Root

📂 Assets File
https://www.dropbox.com/sh/1twyal3vbw1uv7a/AAAC1f9QpMjeNy2P2vY_Ltd0a?dl=0 

#swiftui #swift #figma 

Build a Movie Booking App with SwiftUI and Figma
Yvonne  Hickle

Yvonne Hickle

1662483480

SVGView: SVG Parser and Renderer Written in SwiftUI

SVGView

SVG parser written in SwiftUI


We are a development agency building phenomenal apps.

Overview

The goal of this project is to bring the full power of SVG to Apple platforms. Out framework can parse SVG files and represent their content in SwiftUI. It provides you with the ability to not only render SVG files, but also add interactivity to them, handle user input and use SwiftUI to put your art into motion.

Usage

Get started with SVGView in a few lines of code:

struct ContentView: View {
    var body: some View {
        SVGView(fileURL: Bundle.main.url(forResource: "example", withExtension: "svg")!)
    }
}

Interact with vector elements

You may locate the desired part of your SVG file using standard identifiers to add gestures and change its properties in runtime:

struct ContentView: View {
    var body: some View {
        let view = SVGView(fileURL: Bundle.main.url(forResource: "example", withExtension: "svg")!)
        if let part = view.getNode(byId: "part") {
            part.onTapGesture {
                part.opacity = 0.2
            }
        }
        return view
    }
}

Animation

You can use stanard SwiftUI tools to animate your image:

if let part = view.getNode(byId: "part") {
    part.onTapGesture {
        withAnimation {
            part.opacity = 0.2
        }
    }
}

Complex effects

SVGView makes it easy to add custom effects to your app. For example, make this pikachu track finger movement:

var body: some View {
    let view = SVGView(fileURL: Bundle.main.url(forResource: "pikachu", withExtension: "svg")!)
    let delta = CGAffineTransform(translationX: getEyeX(), y: 0)
    view.getNode(byId: "eye1")?.transform = delta
    view.getNode(byId: "eye2")?.transform = delta

    return view.gesture(DragGesture().onChanged { g in
        self.x = g.location.x
    })
}

SVG Tests Coverage

Our mission is to provide 100% support of all SVG standards: 1.1 (Second Edition), Tiny 1.2 and 2.0. However, this project is at its very beginning, so you can follow our progress on this page. You can also check out SVGViewTests project to see how well this framework handles every single SVG test case.

Installation

CocoaPods

pod 'SVGView'

Carthage

github "Exyte/SVGView"

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/exyte/SVGView.git", from: "1.0.0")
]

Requirements

  • iOS 13+ / watchOS 13+ / tvOS 13+ / macOS 11+
  • Xcode 11+

Download Details:

Author:  exyte
Source code: https://github.com/exyte/SVGView

License: MIT license
#swift #swiftui 

SVGView: SVG Parser and Renderer Written in SwiftUI

Edhita: Fully Open Source Text Editor for IOS Written in SwiftUI

Edhita

Fully open source text editor for iOS written in SwiftUI.

What does Edhita mean?

Edhita (Japanese Romaji) == エディタ (Japanese Katakana) == Editor (English)

Development

$ cp Constants.swift Edhita/Models/
$ open Edhita.xcodeproj

The Swift Package Manager is used for dependencies.

.gitignore

# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## User settings
xcuserdata/

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3

## Obj-C/Swift specific
*.hmap

## App packaging
*.ipa
*.dSYM.zip
*.dSYM

## Playgrounds
timeline.xctimeline
playground.xcworkspace

# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
# *.xcodeproj
#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm

.build/

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build/

# Accio dependency management
Dependencies/
.accio/

# fastlane
#
# It is recommended to not store the screenshots in the git repo.
# Instead, use fastlane to re-generate the screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/

bin/swift-format
Edhita/Models/Constants.swift

SwiftUI

Edhita is currently built with SwiftUI.
Previous versions were built with Swift (UIKIt) or Objective-C.

YearVersionTechnologyBranch
20223.x.xSwiftUImaster
20142.x.xSwift (UIKit)uikit
20101.x.xObjective-CObjective-C

Mojicon

Icon images are created by Mojicon.

Acknowledgments

https://edhita.bornneet.com/


Download Details:

Author: tnantoka
Source code: https://github.com/tnantoka/edhita

License: MIT license
#swiftui 

Edhita: Fully Open Source Text Editor for IOS Written in SwiftUI