Add extensions to package

This commit is contained in:
Robert McGovern 2021-07-06 01:27:25 +01:00
parent fa5ca2aa20
commit a16a62b365
16 changed files with 439 additions and 18 deletions

View File

@ -5,6 +5,9 @@ import PackageDescription
let package = Package(
name: "SwiftExtensions",
platforms: [
.iOS(.v14)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
@ -21,8 +24,32 @@ let package = Package(
.target(
name: "SwiftExtensions",
dependencies: []),
.testTarget(
name: "SwiftExtensionsTests",
dependencies: ["SwiftExtensions"]),
// .testTarget(
// name: "SwiftExtensionsTests",
// dependencies: ["SwiftExtensions"]),
]
)
/*
name: "textStickersSwiftUIViews",
platforms: [
.iOS(.v14)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "textStickersSwiftUIViews",
targets: ["textStickersSwiftUIViews"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "textStickersSwiftUIViews",
dependencies: [])
]
*/

View File

@ -1,3 +1,3 @@
# SwiftExtensions
A description of this package.
Handy extensions for use in different projects.

View File

@ -0,0 +1,18 @@
//
// AnyTransition+scaleAndFade.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 16/02/2021.
//
import SwiftUI
extension AnyTransition {
static var scaleAndFade: AnyTransition {
let insertion = AnyTransition.scale
.combined(with: .opacity)
let removal = AnyTransition.scale
.combined(with: .opacity).animation(Animation.easeOut.speed(10))
return .asymmetric(insertion: insertion, removal: removal)
}
}

View File

@ -0,0 +1,27 @@
//
// Array+removeDuplicates.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 17/02/2021.
//
// extensoin from Paul Hudson - https://www.hackingwithswift.com/example-code/language/how-to-remove-duplicate-items-from-an-array
import Foundation
/*
provides two methods: one called removingDuplicates() that returns an array with duplicates removed, and one called removeDuplicates() that changes the array in place.
*/
extension Array where Element: Hashable {
func removingDuplicates() -> [Element] {
var addedDict = [Element: Bool]()
return filter {
addedDict.updateValue(true, forKey: $0) == nil
}
}
mutating func removeDuplicates() {
self = self.removingDuplicates()
}
}

View File

@ -0,0 +1,23 @@
//
// Bindig+didSet.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 26/11/2020.
//
import SwiftUI
extension Binding {
func didSet(execute: @escaping (Value) -> Void) -> Binding {
return Binding(
get: {
return self.wrappedValue
},
set: {
self.wrappedValue = $0
execute($0)
}
)
}
}

View File

@ -0,0 +1,31 @@
//
// Color+fromString+ToString.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 25/11/2020.
//
import SwiftUI
extension Color {
func toString() -> String {
let uiColor = UIColor(self)
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return "\(red),\(green),\(blue),\(alpha)"
}
static func fromString(_ string: String) -> Color {
let rgbArray = string.components(separatedBy: ",")
if let red = Double(rgbArray[0]), let green = Double(rgbArray[1]), let blue = Double(rgbArray[2]), let alpha = Double(rgbArray[3]) {
return Color(.sRGB, red: red, green: green, blue: blue, opacity: alpha)
} else {
return Color.pink
}
}
}

View File

@ -0,0 +1,14 @@
//
// Color+random.swift
// kaomojiEmoticonKeyboard (iOS)
//
// Created by Robert McGovern on 24/11/2020.
//
import SwiftUI
extension Color {
static var random: Color {
[Color.red, Color.orange, Color.yellow, Color.blue, Color.purple, Color.pink, Color.green].randomElement()!
}
}

View File

@ -0,0 +1,102 @@
//
// View+directories.swift
// kaomojiEmoticonKeyboard (iOS)
//
// Created by Robert McGovern on 24/11/2020.
//
import SwiftUI
class Directories {
// Get user's documents directory path
static func getDocumentsDirectoryPath() -> URL {
let arrayPaths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let docDirectoryPath = arrayPaths[0]
return docDirectoryPath
}
// Get user's cache directory path
static func getCacheDirectoryPath() -> URL {
let arrayPaths = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
let cacheDirectoryPath = arrayPaths[0]
return cacheDirectoryPath
}
// Get user's temp directory path
static func getTempDirectoryPath() -> URL {
let tempDirectoryPath = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
return tempDirectoryPath
}
// Get user's temp directory path
static func getAppSharedGroupPath() -> URL? {
let sharedContainerURL :URL? = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.net.tarasis.kaomojiEmoticonKeyboard")
return sharedContainerURL
}
static func clearCache(){
let cacheURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
let fileManager = FileManager.default
do {
// Get the directory contents urls (including subfolders urls)
let directoryContents = try FileManager.default.contentsOfDirectory( at: cacheURL, includingPropertiesForKeys: nil, options: [])
for file in directoryContents {
do {
try fileManager.removeItem(at: file)
}
catch let error as NSError {
debugPrint("Ooops! Something went wrong: \(error)")
}
}
} catch let error as NSError {
print(error)
}
}
static func clearAppGroup(){
guard let cacheURL = getAppSharedGroupPath() else { fatalError("Error getting app group url") }
let fileManager = FileManager.default
do {
// Get the directory contents urls (including subfolders urls)
let directoryContents = try FileManager.default.contentsOfDirectory( at: cacheURL, includingPropertiesForKeys: nil, options: [])
for file in directoryContents {
do {
try fileManager.removeItem(at: file)
}
catch let error as NSError {
debugPrint("Ooops! Something went wrong: \(error)")
}
}
} catch let error as NSError {
print(error)
}
}
static func clearCachedStickers(){
guard let cacheURL = getAppSharedGroupPath() else { fatalError("Error getting app group url") }
let stickerDirectoryPath = cacheURL.appendingPathComponent("Stickers")
let fileManager = FileManager.default
do {
// Get the directory contents urls (including subfolders urls)
let directoryContents = try FileManager.default.contentsOfDirectory( at: stickerDirectoryPath, includingPropertiesForKeys: nil, options: [])
for file in directoryContents {
do {
try fileManager.removeItem(at: file)
}
catch let error as NSError {
debugPrint("Ooops! Something went wrong: \(error)")
}
}
} catch let error as NSError {
print(error)
}
}
}

View File

@ -0,0 +1,14 @@
//
// String+subscript.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 16/02/2021.
//
import Foundation
extension String {
subscript(idx: Int) -> String {
String(self[index(startIndex, offsetBy: idx)])
}
}

View File

@ -1,3 +0,0 @@
struct SwiftExtensions {
var text = "Hello, World!"
}

View File

@ -0,0 +1,39 @@
//
// File.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 26/11/2020.
//
import SwiftUI
extension UIHostingController {
func capture(transparentBackground: Bool = true) -> UIImage {
let size = sizeThatFits(in: UIScreen.main.bounds.size)
// makes background transparent
if (transparentBackground) {
view.backgroundColor = UIColor.clear
view.isOpaque = false
view.layer.isOpaque = false
view.layer.backgroundColor = UIColor.clear.cgColor
}
view.bounds.size = size
view.sizeToFit()
//suggested version
// UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0)
// view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
// let snapshotImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
// UIGraphicsEndImageContext()
//cleaner ver
let renderer = UIGraphicsImageRenderer(size: self.view.bounds.size)
let snapshotImage = renderer.image { ctx in
self.view.drawHierarchy(in: self.view.bounds, afterScreenUpdates: true)
}
return snapshotImage
}
}

View File

@ -0,0 +1,87 @@
//
// UIImage+scaleImage.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 28/11/2020.
//
import UIKit
extension UIImage {
func resizeImage(newWidth: CGFloat) -> UIImage? {
let scale = newWidth / self.size.width
let newHeight = self.size.height * scale
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
self.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
func scaleToSize(_ newSize: CGSize) -> UIImage? {
var newImage: UIImage?
let newRect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height).integral
UIGraphicsBeginImageContextWithOptions(newSize, false, 0)
if let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage {
context.interpolationQuality = .high
let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newSize.height)
context.concatenate(flipVertical)
context.draw(cgImage, in: newRect)
if let img = context.makeImage() {
// newImage = UIImage(cgImage: img) -- orig
let scale = UIScreen.main.scale
newImage = UIImage(cgImage: img, scale: scale, orientation: .up)
}
UIGraphicsEndImageContext()
}
return newImage
}
func scaleToWidth(_ newWidth: CGFloat) -> UIImage? {
var newImage: UIImage?
let scale = newWidth / self.size.width
let newHeight = self.size.height * scale
let newRect = CGRect(x: 0, y: 0, width: newWidth, height: newHeight).integral
UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newHeight), false, 0)
if let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage {
context.interpolationQuality = .high
let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newHeight)
context.concatenate(flipVertical)
context.draw(cgImage, in: newRect)
if let img = context.makeImage() {
// newImage = UIImage(cgImage: img) -- orig
let scale = UIScreen.main.scale
newImage = UIImage(cgImage: img, scale: scale, orientation: .up)
}
UIGraphicsEndImageContext()
}
return newImage
}
// don't need, kept because erm
// static func scaleImage(_ image: UIImage, toNewWidth newWidth: CGFloat) -> UIImage? {
// var newImage: UIImage?
// let scale = newWidth / image.size.width
// let newHeight = image.size.height * scale
//
// let newRect = CGRect(x: 0, y: 0, width: newWidth, height: newHeight).integral
// UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: newHeight), false, 0)
// if let context = UIGraphicsGetCurrentContext(), let cgImage = image.cgImage {
// context.interpolationQuality = .high
// let flipVertical = CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: newHeight)
// context.concatenate(flipVertical)
// context.draw(cgImage, in: newRect)
// if let img = context.makeImage() {
// // newImage = UIImage(cgImage: img) -- orig
// let scale = UIScreen.main.scale
// newImage = UIImage(cgImage: img, scale: scale, orientation: .up)
// }
// UIGraphicsEndImageContext()
// }
// return newImage
// }
}

View File

@ -0,0 +1,18 @@
//
// View+glow.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 18/11/2020.
//
import SwiftUI
extension View {
func glow(color: Color = .red, radius: CGFloat = 20) -> some View {
self
.overlay(self.blur(radius: radius / 6))
.shadow(color: color, radius: radius / 3)
.shadow(color: color, radius: radius / 3)
.shadow(color: color, radius: radius / 3)
}
}

View File

@ -0,0 +1,14 @@
//
// View+hideKeyboard.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 15/11/2020.
//
import SwiftUI
extension View {
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}

View File

@ -0,0 +1,21 @@
//
// View+multicolorGlow.swift
// kaomojiEmoticonKeyboard
//
// Created by Robert McGovern on 18/11/2020.
//
import SwiftUI
extension View {
func multicolorGlow() -> some View {
ForEach(0..<2) { i in
Rectangle()
.fill(AngularGradient(gradient: Gradient(colors: [.red, .yellow, .green, .blue, .purple, .red]), center: .center))
.frame(width: 50, height: 50)
.mask(self.blur(radius: 20))
.overlay(self.blur(radius: 5 - CGFloat(i * 5)))
}
}
}

View File

@ -1,11 +0,0 @@
import XCTest
@testable import SwiftExtensions
final class SwiftExtensionsTests: XCTestCase {
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(SwiftExtensions().text, "Hello, World!")
}
}