add swiftUI code

This commit is contained in:
zeus
2025-01-22 14:09:10 +08:00
parent 68e7b7347c
commit 8a99853829
2531 changed files with 486215 additions and 0 deletions
@@ -0,0 +1,27 @@
//
// ChatViewControllerWrapper.swift
// SFI
//
// Created by Mac on 2024/10/24.
//
import SwiftUI
import UIKit
import Crisp
// Step 2: Create a SwiftUI wrapper for ChatViewController
struct ChatViewControllerWrapper: UIViewControllerRepresentable {
// Initialize any properties needed to pass to ChatViewController
typealias UIViewControllerType = ChatViewController
func makeUIViewController(context: Context) -> ChatViewController {
// Return the ChatViewController
let chatViewController = ChatViewController()
return chatViewController
}
func updateUIViewController(_ uiViewController: ChatViewController, context: Context) {
// Update the view controller when needed
}
}
@@ -0,0 +1,92 @@
//
// CustomCorners.swift
// CustomCorners
//
// Created by Balaji on 12/09/21.
//
import SwiftUI
struct CustomCorners: Shape {
var radius: CGFloat
var corners: UIRectCorner
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}
func getSafeAreaInsets() -> UIEdgeInsets {
let windowScene = UIApplication.shared.connectedScenes
.filter({ $0.activationState == .foregroundActive })
.map({ $0 as? UIWindowScene })
.compactMap({ $0 })
.first
guard let keyWindow = windowScene?.windows.filter({ $0.isKeyWindow }).first else {
return .zero
}
return keyWindow.safeAreaInsets
}
func getRect() -> CGRect {
return UIScreen.main.bounds
}
@ViewBuilder
func BackgroundBg()->some View{
ZStack{
LinearGradient(colors: [
Color("BG1"),
Color("BG1"),
Color("BG2"),
Color("BG2"),
], startPoint: .top, endPoint: .bottom)
// Little Planet and little stars....
Image("mars")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 30, height: 30)
.scaleEffect(getRect().height < 750 ? 0.8 : 1)
// not using offset...
// using postiton..
// this will position the object using screen basis...
.position(x: 50, y: getRect().height < 750 ? 200 : 220)
.opacity(0.7)
// Sample star points....
let stars: [CGPoint] = [
CGPoint(x: 15, y: 190),
CGPoint(x: 25, y: 250),
CGPoint(x: 20, y: 350),
CGPoint(x: getRect().width - 30, y: 240),
]
ForEach(stars,id: \.x){star in
Circle()
.fill(.white.opacity(0.3))
.frame(width: 5, height: 5)
.position(star)
.offset(y: getRect().height < 750 ? -20 : 0)
}
Spacer()
}
.ignoresSafeArea()
}
@@ -0,0 +1,33 @@
//
// HTMLTextView.swift
// SFI
//
// Created by Mac on 2024/10/27.
//
import Foundation
import SwiftUI
import UIKit
struct HTMLTextView: UIViewRepresentable {
let htmlString: String
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.isEditable = false
textView.isScrollEnabled = true
textView.backgroundColor = .clear
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
guard let data = htmlString.data(using: .utf8) else { return }
do {
let attributedString = try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
uiView.attributedText = attributedString
} catch {
print("Error loading HTML: \(error)")
}
}
}
@@ -0,0 +1,78 @@
//
// CustomTF.swift
// LoginKit
//
// Created by Balaji on 04/08/23.
//
import SwiftUI
struct CustomTF: View {
var sfIcon: String
var iconTint: Color = .gray
var hint: String
/// Hides TextField
var isPassword: Bool = false
var hasDriveLine: Bool = true
@Binding var value: String
/// View Properties
@State private var showPassword: Bool = false
/// When Switching Between Hide/Reveal Password Field, The Keyboard is Closing, to avoid that using the FocusState
@FocusState private var passwordState: HideState?
enum HideState {
case hide
case reveal
}
var body: some View {
HStack(alignment: .top, spacing: 8, content: {
Image(systemName: sfIcon)
.foregroundStyle(iconTint)
/// Since I Need Same Width to Align TextFields Equally
.frame(width: 30)
/// Slightly Bringing Down
.offset(y: 2)
VStack(alignment: .leading, spacing: 8, content: {
if isPassword {
Group {
/// Revealing Password when users wants to show Password
if showPassword {
TextField(hint, text: $value)
.focused($passwordState, equals: .reveal)
} else {
SecureField(hint, text: $value)
.focused($passwordState, equals: .hide)
}
}
} else {
TextField(hint, text: $value)
}
if hasDriveLine {
Divider()
}
})
.overlay(alignment: .trailing) {
/// Password Reveal Button
if isPassword {
Button(action: {
withAnimation {
showPassword.toggle()
}
passwordState = showPassword ? .reveal : .hide
}, label: {
Image(systemName: showPassword ? "eye.slash" : "eye")
.foregroundStyle(.gray)
.padding(10)
.contentShape(.rect)
})
}
}
})
}
}
@@ -0,0 +1,28 @@
//
// GradientButton.swift
// LoginKit
//
// Created by Balaji on 04/08/23.
//
import SwiftUI
struct GradientButton: View {
var title: String
var icon: String
var onClick: () -> ()
var body: some View {
Button(action: onClick, label: {
HStack(spacing: 15) {
Text(title)
Image(systemName: icon)
}
////.fontWeight(.bold)
.foregroundStyle(.white)
.padding(.vertical, 12)
.padding(.horizontal, 35)
.background(.linearGradient(colors: [.main, .main2, ], startPoint: .top, endPoint: .bottom), in: .capsule)
})
}
}
@@ -0,0 +1,87 @@
//
// OTPVerificationView.swift
// AutoOtpTF
//
// Created by Balaji on 23/12/22.
//
import SwiftUI
struct OTPVerificationView: View {
/// - View Properties
@Binding var otpText: String
/// - Keyboard State
@FocusState private var isKeyboardShowing: Bool
var body: some View {
HStack(spacing: 0){
/// - OTP Text Boxes
/// Change Count Based on your OTP Text Size
ForEach(0..<6,id: \.self){index in
OTPTextBox(index)
}
}
.background(content: {
TextField("", text: $otpText.limit(6))
.keyboardType(.numberPad)
.textContentType(.oneTimeCode)
/// - Hiding it Out
.frame(width: 1, height: 1)
.opacity(0.001)
.blendMode(.screen)
.focused($isKeyboardShowing)
})
.contentShape(Rectangle())
/// - Opening Keyboard When Tapped
.onTapGesture {
isKeyboardShowing = true
}
.toolbar {
ToolbarItem(placement: .keyboard) {
Button("Done"){
isKeyboardShowing = false
}
.tint(.white)
////.fontWeight(.heavy)
.hSpacing(.trailing)
}
}
}
// MARK: OTP Text Box
@ViewBuilder
func OTPTextBox(_ index: Int)->some View{
ZStack{
if otpText.count > index{
/// - Finding Char At Index
let startIndex = otpText.startIndex
let charIndex = otpText.index(startIndex, offsetBy: index)
let charToString = String(otpText[charIndex])
Text(charToString)
}else{
Text(" ")
}
}
.frame(width: 45, height: 45)
.background {
/// - Highlighting Current Active Box
let status = (isKeyboardShowing && otpText.count == index)
RoundedRectangle(cornerRadius: 6, style: .continuous)
.stroke(status ? .main : Color.gray,lineWidth: status ? 3 : 0.5)
/// - Adding Animation
.animation(.easeInOut(duration: 0.2), value: isKeyboardShowing)
}
.frame(maxWidth: .infinity)
}
}
// MARK: Binding <String> Extension
extension Binding where Value == String{
func limit(_ length: Int)->Self{
if self.wrappedValue.count > length{
DispatchQueue.main.async {
self.wrappedValue = String(self.wrappedValue.prefix(length))
}
}
return self
}
}
@@ -0,0 +1,31 @@
//
// LottieView.swift
// VPNUI
//
// Created by Mac on 2024/9/26.
//
import Foundation
//import Lottie
import SwiftUI
import Lottie
struct LottieView: UIViewRepresentable {
var animationFileName: String
let loopMode: LottieLoopMode
func updateUIView(_ uiView: UIViewType, context: Context) {
}
func makeUIView(context: Context) -> Lottie.LottieAnimationView {
let animationView = LottieAnimationView(name: animationFileName)
animationView.loopMode = loopMode
animationView.play()
animationView.contentMode = .scaleAspectFit
return animationView
}
}
@@ -0,0 +1,20 @@
//
// Unitity.swift
// SFI
//
// Created by Mac on 2024/10/20.
//
import Foundation
struct TimestampConverter {
// Function to convert a timestamp to a formatted date string
static func convertTimestampToDateString(_ timestamp: Int, format: String = "yyyy-MM-dd HH:mm:ss") -> String {
let timeInterval = TimeInterval(timestamp)
let date = Date(timeIntervalSince1970: timeInterval)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: date)
}
}
@@ -0,0 +1,93 @@
//
// UniversalAlert.swift
// CustomUniversalAlert
//
// Created by Balaji Venkatesh on 18/09/23.
//
import SwiftUI
/// Alert Config
struct AlertConfig {
fileprivate var enableBackgroundBlur: Bool = true
fileprivate var disableOutsideTap: Bool = true
fileprivate var transitionType: TransitionType = .slide
fileprivate var slideEdge: Edge = .bottom
fileprivate var show: Bool = false
fileprivate var showView: Bool = false
init(enableBackgroundBlur: Bool = true, disableOutsideTap: Bool = true, transitionType: TransitionType = .slide, slideEdge: Edge = .bottom) {
self.enableBackgroundBlur = enableBackgroundBlur
self.disableOutsideTap = disableOutsideTap
self.transitionType = transitionType
self.slideEdge = slideEdge
}
/// TransitionType
enum TransitionType {
case slide
case opacity
}
/// Alert Present/Dismiss Methods
mutating
func present() {
show = true
}
mutating
func dismiss() {
show = false
}
}
fileprivate struct AlertView<Content: View>: View {
@Binding var config: AlertConfig
/// View Tag
var tag: Int
@ViewBuilder var content: () -> Content
/// View Properties
@State private var showView: Bool = false
var body: some View {
GeometryReader(content: { geometry in
if showView && config.transitionType == .slide {
content()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.move(edge: config.slideEdge))
} else {
content()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.opacity(showView ? 1 : 0)
}
})
.background {
ZStack {
if config.enableBackgroundBlur {
Rectangle()
.fill(.ultraThinMaterial)
} else {
Rectangle()
.fill(.primary.opacity(0.25))
}
}
.ignoresSafeArea()
.contentShape(.rect)
.onTapGesture {
if !config.disableOutsideTap {
config.dismiss()
}
}
.opacity(showView ? 1 : 0)
}
.onAppear(perform: {
config.showView = true
})
// .onChange(of: config.showView) { oldValue, newValue in
// withAnimation(.smooth(duration: 0.35, extraBounce: 0)) {
// showView = newValue
// }
// }
}
}
@@ -0,0 +1,190 @@
//
// View+Extensions.swift
// LoginKit
//
// Created by Balaji on 04/08/23.
//
import SwiftUI
/// Custom SwiftUI View Extensions
extension View {
/// View Alignments
@ViewBuilder
func hSpacing(_ alignment: Alignment = .center) -> some View {
self
.frame(maxWidth: .infinity, alignment: alignment)
}
@ViewBuilder
func vSpacing(_ alignment: Alignment = .center) -> some View {
self
.frame(maxHeight: .infinity, alignment: alignment)
}
/// Disable With Opacity
@ViewBuilder
func disableWithOpacity(_ condition: Bool) -> some View {
self
.disabled(condition)
.opacity(condition ? 0.5 : 1)
}
}
// Extedning View to get Screen Size and Frame....
extension View{
func getRect()->CGRect{
UIScreen.main.bounds
}
func getSafeArea()->UIEdgeInsets{
guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else{
return .zero
}
guard let safeArea = screen.windows.first?.safeAreaInsets else{
return .zero
}
return safeArea
}
}
extension Text {
init(_ attributedString: NSAttributedString) {
self.init("") // initial, empty Text
// scan the attributed string for distinctly attributed regions
attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length),
options: []) { (attrs, range, _) in
let string = attributedString.attributedSubstring(from: range).string
var text = Text(string)
// then, read applicable attributes and apply them to the Text
if let font = attrs[.font] as? UIFont {
// this takes care of the majority of formatting - text size, font family,
// font weight, if it's italic, etc.
text = text.font(.init(font))
}
if let color = attrs[.foregroundColor] as? UIColor {
text = text.foregroundColor(Color(color))
}
if let kern = attrs[.kern] as? CGFloat {
text = text.kerning(kern)
}
if #available(iOS 14.0, *) {
if let tracking = attrs[.tracking] as? CGFloat {
text = text.tracking(tracking)
}
}
if let strikethroughStyle = attrs[.strikethroughStyle] as? NSNumber,
strikethroughStyle != 0 {
if let strikethroughColor = (attrs[.strikethroughColor] as? UIColor) {
text = text.strikethrough(true, color: Color(strikethroughColor))
} else {
text = text.strikethrough(true)
}
}
if let underlineStyle = attrs[.underlineStyle] as? NSNumber,
underlineStyle != 0 {
if let underlineColor = (attrs[.underlineColor] as? UIColor) {
text = text.underline(true, color: Color(underlineColor))
} else {
text = text.underline(true)
}
}
if let baselineOffset = attrs[.baselineOffset] as? NSNumber {
text = text.baselineOffset(CGFloat(baselineOffset.floatValue))
}
// append the newly styled subtext to the rest of the text
self = self + text
}
}
}
extension Text {
init(html htmlString: String, // the HTML-formatted string
raw: Bool = false, // set to true if you don't want to embed in the doc skeleton
size: CGFloat? = nil, // optional document-wide text size
fontFamily: String = "-apple-system") { // optional document-wide font family
let fullHTML: String
if raw {
fullHTML = htmlString
} else {
var sizeCss = ""
if let size = size {
sizeCss = "font-size: \(size)px;"
}
fullHTML = """
<!doctype html>
<html>
<head>
<style>
body {
font-family: \(fontFamily);
\(sizeCss)
}
</style>
</head>
<body>
\(htmlString)
</body>
</html>
"""
}
let attributedString: NSAttributedString
if let data = fullHTML.data(using: .unicode),
let attrString = try? NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil) {
attributedString = attrString
} else {
attributedString = NSAttributedString()
}
self.init(attributedString) // uses the NSAttributedString initializer
}
}
public extension View {
// View
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
func transparentScrolling() -> some View {
if #available(iOS 16.0, *) {
return scrollContentBackground(.hidden)
} else {
return onAppear {
UITextView.appearance().backgroundColor = .clear
}
}
}
}
struct TriangleShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.minX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
path.closeSubpath()
return path
}
}