diff --git a/Classes/Extensions/Image+Awesome.swift b/Classes/Extensions/Amazing+Image.swift similarity index 99% rename from Classes/Extensions/Image+Awesome.swift rename to Classes/Extensions/Amazing+Image.swift index 425b3a3..ea8cf6e 100755 --- a/Classes/Extensions/Image+Awesome.swift +++ b/Classes/Extensions/Amazing+Image.swift @@ -1,5 +1,5 @@ // -// Image+Awesome.swift +// Amazing+Image.swift // Awesome // // Created by Ondrej Rafaj on 13/10/2017. diff --git a/Classes/Extensions/Amazing+Tools.swift b/Classes/Extensions/Amazing+Tools.swift index 84c1fc6..aadf008 100755 --- a/Classes/Extensions/Amazing+Tools.swift +++ b/Classes/Extensions/Amazing+Tools.swift @@ -45,6 +45,18 @@ public extension Amazing { } } +#if canImport(SwiftUI) +import SwiftUI + +@available(iOS 13, macOS 11, watchOS 6, tvOS 13, *) +public extension Amazing { + /// A SwiftUI Image of the icon + var image: Awesome.Image { + Awesome.Image(icon: self) + } +} +#endif + extension Amazing { /// Returns an unique identifier string that contains the font name, font style and icon name diff --git a/Classes/Libs/Crossplatform.swift b/Classes/Libs/Crossplatform.swift index d7b2426..412840b 100644 --- a/Classes/Libs/Crossplatform.swift +++ b/Classes/Libs/Crossplatform.swift @@ -9,7 +9,7 @@ import Foundation #if os(iOS) || os(watchOS) || os(tvOS) - import UIKit +import UIKit extension Amazing { public typealias Color = UIColor @@ -19,7 +19,7 @@ extension Amazing { #elseif os(OSX) - import Cocoa +import Cocoa extension Amazing { public typealias Color = NSColor diff --git a/Classes/SwiftUI/Awesome+Image.swift b/Classes/SwiftUI/Awesome+Image.swift new file mode 100644 index 0000000..30a5da8 --- /dev/null +++ b/Classes/SwiftUI/Awesome+Image.swift @@ -0,0 +1,132 @@ +// +// Awesome+Image.swift +// Awesome +// +// Created by David Walter on 22.02.22. +// + +#if canImport(SwiftUI) +import SwiftUI + +@available(iOS 13, macOS 11, watchOS 6, tvOS 13, *) +extension Awesome { + /// A view wrapper around an Awesome.Image + public struct Image: View where AmazingType: Amazing { + var icon: AmazingType + + @Environment(\.imageScale) var imageScale + @Environment(\.font) var font + + private var forcedSize: CGSize? + private var foregroundColor: Amazing.Color + private var backgroundColor: Amazing.Color + + private var isResizable: Bool + private var capInsets: EdgeInsets + private var resizingMode: SwiftUI.Image.ResizingMode + + var size: CGSize { + if let size = forcedSize { + return size + } + + let textStyle = self.font?.textStyle ?? .body + let size = Amazing.Font.preferredFont(forTextStyle: textStyle).pointSize * imageScale.value + return CGSize(width: size * 1.28571429, height: size) + } + + public var body: some View { + if isResizable { + image.resizable(capInsets: capInsets, resizingMode: resizingMode) + } else { + image + } + } + + var image: SwiftUI.Image { + #if os(iOS) || os(watchOS) || os(tvOS) + SwiftUI.Image(uiImage: icon.asImage(size: size, color: foregroundColor, backgroundColor: backgroundColor)) + #elseif os(macOS) + SwiftUI.Image(nsImage: icon.asImage(size: size, color: foregroundColor, backgroundColor: backgroundColor)) + #endif + } + + /// Creates a Font Awesome icon image. + /// + /// This initializer creates an image using a Font Awesome icon. + /// + /// - Parameters: + /// - icon: The icon to use + public init(icon: AmazingType) { + self.icon = icon + + self.forcedSize = nil + self.foregroundColor = .black + self.backgroundColor = .clear + + self.isResizable = false + self.capInsets = EdgeInsets() + self.resizingMode = .stretch + } + + /// Changes the size of the underlying image. This will disable the automatic sizing based on the font + /// + /// - Parameter size: The size to change to + /// + /// - Returns: An image that uses the size you supply + public func size(_ size: CGFloat) -> Self { + var view = self + view.forcedSize = CGSize(width: size, height: size) + return view + } + + /// Changes the size of the underlying image. This will disable the automatic sizing based on the font + /// + /// - Parameter size: The size to change to + /// + /// - Returns: An image that uses the size you supply + public func size(_ size: CGSize) -> Self { + var view = self + view.forcedSize = size + return view + } + + /// Sets the color of the icon. + /// + /// - Parameter color: The foreground color to use when displaying this icon. + /// + /// - Returns: A view that uses the foreground color you supply. + public func foregroundColor(_ color: Amazing.Color) -> Self { + var view = self + view.foregroundColor = color + return view + } + + /// Sets the background color of the icon. + /// + /// - Parameter color: The background color to use when displaying this icon. + /// + /// - Returns: An image that uses the background color you supply + public func backgroundColor(_ color: Amazing.Color) -> Self { + var view = self + view.backgroundColor = color + return view + } + + /// Sets the mode by which SwiftUI resizes an image to fit its space. + /// + /// - Parameters: + /// - capInsets: Inset values that indicate a portion of the image that SwiftUI doesn't resize. + /// - resizingMode: The mode by which SwiftUI resizes the image. + /// + /// - Returns: An image, with the new resizing behavior set. + public func resizable(capInsets: EdgeInsets = EdgeInsets(), resizingMode: SwiftUI.Image.ResizingMode = .stretch) -> Self { + var view = self + view.isResizable = true + view.capInsets = capInsets + view.resizingMode = resizingMode + return view + } + } +} +#endif diff --git a/Classes/SwiftUI/SwiftUI+Extensions.swift b/Classes/SwiftUI/SwiftUI+Extensions.swift new file mode 100644 index 0000000..1fd3aad --- /dev/null +++ b/Classes/SwiftUI/SwiftUI+Extensions.swift @@ -0,0 +1,62 @@ +// +// SwiftUI+Extensions.swift +// Awesome +// +// Created by David Walter on 23.02.22. +// + +#if canImport(SwiftUI) +import SwiftUI + +@available(iOS 13, macOS 11, watchOS 6, tvOS 13, *) +extension Font { + var textStyle: Amazing.Font.TextStyle? { + switch self { + case .largeTitle: + #if os(tvOS) + return nil + #else + return .largeTitle + #endif + case .title: + return .title1 + case .title: + return .title2 + case .title: + return .title3 + case .headline: + return .headline + case .subheadline: + return .subheadline + case .body: + return .body + case .callout: + return .callout + case .footnote: + return .footnote + case .caption: + return .caption1 + case .caption: + return .caption2 + default: + return nil + } + } +} + +@available(iOS 13, macOS 11, watchOS 6, tvOS 13, *) +extension Image.Scale { + var value: CGFloat { + switch self { + case .small: + return 1 / 1.28571429 + case .medium: + return 1 + case .large: + return 1.28571429 + @unknown default: + return 1 + } + } +} +#endif diff --git a/Package.swift b/Package.swift index 55ecdcb..091c374 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,7 @@ import PackageDescription let package = Package( name: "Awesome", - platforms: [.iOS(.v9), .macOS(.v10_11), .watchOS(.v2), .tvOS(.v9)], + platforms: [.iOS(.v11), .macOS(.v10_11), .watchOS(.v2), .tvOS(.v9)], products: [ .library( name: "Awesome", diff --git a/README.md b/README.md index 8008bd0..dc5ea21 100644 --- a/README.md +++ b/README.md @@ -64,11 +64,27 @@ import Awesome All icons are available through autogenerated enums like this: ```swift +// UKit and AppKit let image = Awesome.Solid.handScissors.asImage(size: 40.0) // or let image = Awesome.Brand.android.asImage(size: CGSize(width: 40, height: 40), color: .red, backgroundColor: .blue) // :trollface: // or let attributedText = Awesome.Regular.envelopeOpen.asAttributedText(fontSize: 17, color: .red, backgroundColor: .blue) + +// SwiftUI +Awesome.Brand.apple.image +// Set some modifiers +Awesome.Brand.android.image + .size(40) + .foregroundColor(.red) + .backgroundColor(.blue) +// Scales automatically with font +Awesome.Brand.android.image + .foregroundColor(.red) + .backgroundColor(.blue) + .font(.largeTitle) +// or +Awesome.Image(icon: Awesome.Brand.apple) ``` ### Font Awesome Pro