Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions AltSwiftUI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@
2CD1A04C2512066D00E2CCBA /* ViewEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CD1A00B2512066D00E2CCBA /* ViewEnvironment.swift */; };
2CD1A04E2512066D00E2CCBA /* AltSwiftUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CD1A00D2512066D00E2CCBA /* AltSwiftUI.h */; settings = {ATTRIBUTES = (Public, ); }; };
2CD1A056251206C200E2CCBA /* ViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CD1A054251206C200E2CCBA /* ViewTests.swift */; };
306E5231266F2FF60030FEA9 /* LinearGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306E5230266F2FF60030FEA9 /* LinearGradient.swift */; };
306E5235266F30060030FEA9 /* RadialGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306E5234266F30060030FEA9 /* RadialGradient.swift */; };
306E5239266F300D0030FEA9 /* Gradients.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306E5238266F300D0030FEA9 /* Gradients.swift */; };
306E523D266F30150030FEA9 /* GradientLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306E523C266F30150030FEA9 /* GradientLayer.swift */; };
68CBD3E12578AADB00A3F033 /* SecureField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68CBD3E02578AADB00A3F033 /* SecureField.swift */; };
7D2D4D6B25148269000F5DDC /* Capsule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2D4D6525148269000F5DDC /* Capsule.swift */; };
7D2D4D6C25148269000F5DDC /* Circle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2D4D6625148269000F5DDC /* Circle.swift */; };
Expand Down Expand Up @@ -166,6 +170,10 @@
2CD1A00D2512066D00E2CCBA /* AltSwiftUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AltSwiftUI.h; sourceTree = "<group>"; };
2CD1A054251206C200E2CCBA /* ViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewTests.swift; sourceTree = "<group>"; };
2CD1A055251206C200E2CCBA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
306E5230266F2FF60030FEA9 /* LinearGradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinearGradient.swift; sourceTree = "<group>"; };
306E5234266F30060030FEA9 /* RadialGradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadialGradient.swift; sourceTree = "<group>"; };
306E5238266F300D0030FEA9 /* Gradients.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Gradients.swift; sourceTree = "<group>"; };
306E523C266F30150030FEA9 /* GradientLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientLayer.swift; sourceTree = "<group>"; };
68CBD3E02578AADB00A3F033 /* SecureField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureField.swift; sourceTree = "<group>"; };
7D2D4D6525148269000F5DDC /* Capsule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Capsule.swift; sourceTree = "<group>"; };
7D2D4D6625148269000F5DDC /* Circle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Circle.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -362,6 +370,10 @@
2CD19FEB2512066D00E2CCBA /* Picker.swift */,
2CD19FEC2512066D00E2CCBA /* Spacer.swift */,
2CD19FEF2512066D00E2CCBA /* Text.swift */,
306E5238266F300D0030FEA9 /* Gradients.swift */,
306E5230266F2FF60030FEA9 /* LinearGradient.swift */,
306E5234266F30060030FEA9 /* RadialGradient.swift */,
306E523C266F30150030FEA9 /* GradientLayer.swift */,
);
path = ReadOnly;
sourceTree = "<group>";
Expand Down Expand Up @@ -582,7 +594,9 @@
2CD1A02B2512066D00E2CCBA /* ViewPropertyTransitionTypes.swift in Sources */,
7D2D4D6E25148269000F5DDC /* Rectangle.swift in Sources */,
2CD1A0432512066D00E2CCBA /* List.swift in Sources */,
306E5239266F300D0030FEA9 /* Gradients.swift in Sources */,
2CD1A01F2512066D00E2CCBA /* UIKitNavigationViews.swift in Sources */,
306E5231266F2FF60030FEA9 /* LinearGradient.swift in Sources */,
2CD1A0112512066D00E2CCBA /* UIHostingController.swift in Sources */,
2CD1A02D2512066D00E2CCBA /* ViewBuilder.swift in Sources */,
2CD1A0172512066D00E2CCBA /* Binding.swift in Sources */,
Expand All @@ -596,6 +610,7 @@
2CD1A04B2512066D00E2CCBA /* UIApplicationExtensions.swift in Sources */,
68CBD3E12578AADB00A3F033 /* SecureField.swift in Sources */,
2CD1A01D2512066D00E2CCBA /* Published.swift in Sources */,
306E5235266F30060030FEA9 /* RadialGradient.swift in Sources */,
7D2D4D6F25148269000F5DDC /* Shapes.swift in Sources */,
2CD1A0122512066D00E2CCBA /* ScreenViewController.swift in Sources */,
2CD1A03B2512066D00E2CCBA /* Slider.swift in Sources */,
Expand All @@ -606,6 +621,7 @@
2CD1A0322512066D00E2CCBA /* Image.swift in Sources */,
2CD1A0312512066D00E2CCBA /* Spacer.swift in Sources */,
7D2D4D6D25148269000F5DDC /* Ellipse.swift in Sources */,
306E523D266F30150030FEA9 /* GradientLayer.swift in Sources */,
2CD1A0382512066D00E2CCBA /* DatePicker.swift in Sources */,
2CD1A0222512066D00E2CCBA /* UIKitCollections.swift in Sources */,
2CD1A0282512066D00E2CCBA /* ViewPropertyRenderingTypes.swift in Sources */,
Expand Down
4 changes: 4 additions & 0 deletions Example/AltSwiftUIExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
2CE5E2A2231398DA0072F907 /* AltSwiftUIExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE5E2A1231398DA0072F907 /* AltSwiftUIExampleTests.swift */; };
2CE5E2AD231398DA0072F907 /* AltSwiftUIExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE5E2AC231398DA0072F907 /* AltSwiftUIExampleUITests.swift */; };
2CFE2AC025AD487800C925FC /* ScrollView2AxisExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CFE2ABF25AD487800C925FC /* ScrollView2AxisExampleView.swift */; };
306E5243266F30860030FEA9 /* GradientExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306E5240266F30860030FEA9 /* GradientExampleView.swift */; };
35D1A58825C7EDA100861DC4 /* AlertsExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35D1A58525C7EDA100861DC4 /* AlertsExampleView.swift */; };
682C3A7C2594B18A005E798E /* SecureFieldExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 682C3A7B2594B18A005E798E /* SecureFieldExampleView.swift */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -94,6 +95,7 @@
2CE5E2AC231398DA0072F907 /* AltSwiftUIExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AltSwiftUIExampleUITests.swift; sourceTree = "<group>"; };
2CE5E2AE231398DA0072F907 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2CFE2ABF25AD487800C925FC /* ScrollView2AxisExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollView2AxisExampleView.swift; sourceTree = "<group>"; };
306E5240266F30860030FEA9 /* GradientExampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientExampleView.swift; sourceTree = "<group>"; };
35D1A58525C7EDA100861DC4 /* AlertsExampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertsExampleView.swift; sourceTree = "<group>"; };
682C3A7B2594B18A005E798E /* SecureFieldExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureFieldExampleView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -143,6 +145,7 @@
2CADC316251CA15400EA3F17 /* ShapesExampleView.swift */,
2C49E3CB2535382F00543E7D /* TextExampleView.swift */,
2CDCE7F225C40D2500BB52D1 /* StackUpdateExample.swift */,
306E5240266F30860030FEA9 /* GradientExampleView.swift */,
);
path = ExampleViews;
sourceTree = "<group>";
Expand Down Expand Up @@ -370,6 +373,7 @@
35D1A58825C7EDA100861DC4 /* AlertsExampleView.swift in Sources */,
2C83ED522554E50400C378DC /* NavigationExampleView.swift in Sources */,
2CADC30F251CA0DF00EA3F17 /* RamenExampleView.swift in Sources */,
306E5243266F30860030FEA9 /* GradientExampleView.swift in Sources */,
2CADC317251CA15400EA3F17 /* ShapesExampleView.swift in Sources */,
2CFE2AC025AD487800C925FC /* ScrollView2AxisExampleView.swift in Sources */,
2CE5E28F231398D70072F907 /* ViewController.swift in Sources */,
Expand Down
67 changes: 67 additions & 0 deletions Example/AltSwiftUIExample/ExampleViews/GradientExampleView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//
// GradientExampleView.swift
// AltSwiftUIExample
//
// Created by yang.q.wang on 2021/5/26.
// Copyright © 2021 Rakuten Travel. All rights reserved.
//

import AltSwiftUI
import UIKit

struct GradientExampleView: View {
var viewStore = ViewValues()
let width: CGFloat = 150
let height: CGFloat = 150
@State var isColor = true
@State var startPoint: CGPoint = .top
@State var endPoint: CGPoint = .bottom
@State var startRadius: CGFloat = 10
@State var endRadius: CGFloat = 30
@State var colors:[Color] = [.red, .yellow, .green, .blue, .purple]
var body: View {
VStack(alignment: .center, spacing: 10) { () -> View in
Text("Hello World!").background(LinearGradient(gradient: Gradient(colors: self.colors), startPoint:self.startPoint, endPoint:self.endPoint))
.frame(width: width, height: height)
.clipShape(RoundedRectangle(cornerRadius: 20))
.animation(.linear(duration: 1))
LinearGradient(gradient: Gradient(colors: self.colors), startPoint:self.startPoint, endPoint:self.endPoint)
.frame(width: width, height: height).clipShape(Circle())
.animation(.linear(duration: 1))

RadialGradient(gradient: Gradient(colors: self.colors), center: self.startPoint, startRadius: startRadius, endRadius: endRadius)
.frame(width: width, height: height)
.animation(.linear(duration: 1))

Ellipse().background(LinearGradient(gradient: Gradient(colors: self.colors), startPoint:self.startPoint, endPoint:self.endPoint))
.frame(width: width, height: 120)
.clipShape(Ellipse())
.animation(.linear(duration: 1))
HStack{
Button("Colors Change") {
self.isColor = !self.isColor
if self.isColor {
colors = [.red, .yellow, .green, .blue, .purple]
}else{
colors = [.purple, .blue, .green, .yellow, .red]
}
}
Button("Point Change") {
if self.startPoint == .bottom {
self.startPoint = .top
self.endPoint = .bottom
}else{
self.startPoint = .bottom
self.endPoint = .top
}
if endRadius <= width {
endRadius += 40
}else{
endRadius = 30
}

}
}
}
}
}
3 changes: 2 additions & 1 deletion Example/AltSwiftUIExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ struct ExampleView: View {
ExampleViewData(title: "Texts", destination: TextExampleView()),
ExampleViewData(title: "Navigation", destination: NavigationExampleView()),
ExampleViewData(title: "SecureField", destination: SecureFieldExampleView()),
ExampleViewData(title: "Stack Update", destination: StackUpdateExample())
ExampleViewData(title: "Stack Update", destination: StackUpdateExample()),
ExampleViewData(title: "Gradient Example", destination: GradientExampleView())
]

var body: View {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,47 @@ extension View {
view.viewStore.background = color?.color
return view
}

public func background(_ Background: View?) -> View {
var view = self
if let color = Background as? Color {
view.viewStore.background = color.color
return view
}
if let gradient = Background as? LinearGradient {
return GradientView<LinearGradient>(contentView: self, gradient: gradient)
}
if let gradient = Background as? RadialGradient {
return GradientView<RadialGradient>(contentView: self, gradient: gradient)
}
return view
}
public func clipShape(_ shape: Shape?) -> View {
var view = self
let dimension = view.viewStore.viewDimensions
guard let width = dimension?.width, let height = dimension?.height else {
return view
}
if let _ = shape as? Circle {
view.viewStore.path = UIBezierPath(arcCenter: CGPoint(x: width / 2, y: height / 2), radius: min(width / 2, height / 2), startAngle: 0, endAngle: .pi * 2, clockwise: false).cgPath
}
if let _ = shape as? Capsule {
view.viewStore.path = UIBezierPath(
roundedRect: CGRect(x: 0, y: 0, width: width, height: height),
cornerRadius: min(width, height)/2).cgPath
}
if let _ = shape as? Ellipse {
view.viewStore.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: width, height: height)).cgPath
}
if let _ = shape as? Rectangle {
view.viewStore.path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: width, height: height)).cgPath
}
if let roundRect = shape as? RoundedRectangle {
view.viewStore.path = UIBezierPath(
roundedRect: CGRect(x: 0, y: 0, width: width, height: height),
cornerRadius: roundRect.cornerRadius).cgPath
}
return view
}
/// Creates a view that pads this view using the specified
/// edge instets with a specified value.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,49 @@ extension Animation {
}
}

func performCALayerCustomAnimation(layer: CALayer, keyPath: String, newValue: Any?, animation: CABasicAnimation){
switch curve {
case .easeInOut(duration: let duration):
animation.duration = duration
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
case .easeIn(duration: let duration):
animation.duration = duration
animation.timingFunction = CAMediaTimingFunction(name: .easeIn)
case .easeOut(duration: let duration):
animation.duration = duration
animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
case .linear(duration: let duration):
animation.duration = duration
animation.timingFunction = CAMediaTimingFunction(name: .linear)
case .spring(response: let response, dampingFraction: let dampingFraction, _):
let anim = CASpringAnimation(keyPath: keyPath)
let springParams = SpringParameters(dampingRatio: CGFloat(dampingFraction), response: CGFloat(response))
anim.mass = springParams.mass
anim.stiffness = springParams.stiffness
anim.damping = springParams.damping
anim.initialVelocity = 0
anim.duration = 0.6

}
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
if delay != 0 {
animation.beginTime = CACurrentMediaTime() + delay
}
if let count = repeatCount?.count {
animation.repeatCount = Float(count)
}
if repeatCount?.autoReverse == true {
animation.autoreverses = true
}
CATransaction.begin()
CATransaction.setCompletionBlock {
layer.setValue(newValue, forKey: keyPath)
layer.removeAnimation(forKey: keyPath)
}
layer.add(animation, forKey: keyPath)
CATransaction.commit()
}
func performCALayerAnimation(layer: CALayer, keyPath: String, newValue: Any?) {
var animation: CABasicAnimation?
switch curve {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ public struct Font {
font.font = fontWithWeight(font: font.font, weight: weight)
return font
}
/// Returns a version of the font accroding to system font , limit scope 17 - 21.
public static func dynamicalBarTitleFont(_ font: Font) -> Font {
let pointSize = font.font.fontDescriptor.pointSize
if pointSize > 21 {
let descriptor = font.font.fontDescriptor.withSize(21)
return Font(UIFont(descriptor: descriptor, size: 0))
} else if pointSize < 17 {
let descriptor = font.font.fontDescriptor.withSize(17)
return Font(UIFont(descriptor: descriptor, size: 0))
} else {
return font
}
}

// MARK: Internal methods

Expand Down
4 changes: 4 additions & 0 deletions Sources/AltSwiftUI/Source/ViewProperties/ViewValues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public struct ViewValues: AnimatedViewValuesHolder {
// to make sure view values are inherited in the right scenarios.

var background: UIColor?
var path: CGPath?
var direction: Direction?
var viewDimensions: ViewDimensions?
var buttonStyle: ButtonStyle?
Expand Down Expand Up @@ -156,6 +157,9 @@ extension ViewValues {
var mergedValues = merge(defaultValues: defaultValues)

if background == nil { mergedValues.background = defaultValues.background }
if path == nil {
mergedValues.path = defaultValues.path
}
if viewDimensions == nil { mergedValues.viewDimensions = defaultValues.viewDimensions }
if overlay == nil { mergedValues.overlay = defaultValues.overlay }
if border == nil { mergedValues.border = defaultValues.border }
Expand Down
17 changes: 16 additions & 1 deletion Sources/AltSwiftUI/Source/Views/ReadOnly/Color.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,22 @@ import UIKit
/// By default, a `Color` that is directly rendered in a view hierarchy
/// will expand both horizontally and vertically infinitely as much as
/// its parent view allows it to.
public struct Color: View {
public struct Color: View, Equatable {
public static func == (lhs: Color, rhs: Color) -> Bool {
var lhsRed: CGFloat = 0
var lhsGreen: CGFloat = 0
var lhsBlue: CGFloat = 0
var lhsAlpha: CGFloat = 0

var rhsRed: CGFloat = 0
var rhsGreen: CGFloat = 0
var rhsBlue: CGFloat = 0
var rhsAphpa: CGFloat = 0
lhs.rawColor.getRed(&lhsRed, green: &lhsGreen, blue: &lhsBlue, alpha: &lhsAlpha)
rhs.rawColor.getRed(&rhsRed, green: &rhsGreen, blue: &rhsBlue, alpha: &rhsAphpa)
return lhsRed == rhsRed && lhsGreen == rhsGreen && lhsBlue == rhsBlue && lhsAlpha == rhsAphpa
}

public var viewStore = ViewValues()

/// Stores the original color held by this view
Expand Down
Loading