From 7d695079983b6be048931ed2cf59e583da4c9e43 Mon Sep 17 00:00:00 2001 From: bullinnyc Date: Sun, 2 Jul 2023 20:38:09 +0700 Subject: [PATCH] Minor improvements. --- Examples/ExampleArtLetterView.swift | 13 +- Examples/ExampleBubbleView.swift | 13 +- Examples/ExampleCharmedLetterView.swift | 13 +- Examples/ExampleCharmedView.swift | 12 +- Examples/ExampleFantasyView.swift | 13 +- README.md | 2 +- .../AnimationCompletionViewModifier.swift | 8 +- .../Resources/ResourcesManager.swift | 119 ++++++++++-------- Sources/MagicText/Services/DataManager.swift | 5 +- .../ViewModifiers/MaskViewModifier.swift | 5 +- Sources/MagicText/Views/ArtLetterView.swift | 8 +- Sources/MagicText/Views/BubbleView.swift | 8 +- .../MagicText/Views/CharmedLetterView.swift | 8 +- Sources/MagicText/Views/CharmedView.swift | 8 +- Sources/MagicText/Views/FantasyView.swift | 8 +- Sources/MagicText/Views/MagicView.swift | 33 +++-- 16 files changed, 177 insertions(+), 99 deletions(-) diff --git a/Examples/ExampleArtLetterView.swift b/Examples/ExampleArtLetterView.swift index 5cf2d23..0dae1d0 100644 --- a/Examples/ExampleArtLetterView.swift +++ b/Examples/ExampleArtLetterView.swift @@ -12,6 +12,7 @@ import MagicText struct ExampleArtLetterView: View { // MARK: - Private Properties + private let singleLineExampleText = "Life is like a box of chocolates, you never know what you’re gonna get." private let multiLineExampleText = """ @@ -22,18 +23,19 @@ struct ExampleArtLetterView: View { """ private let colors = [ - candy, coffee, flower, forest, newyork, - night, sky, smoke, theia, venus + RM.candy, RM.coffee, RM.flower, RM.forest, RM.newyork, + RM.night, RM.sky, RM.smoke, RM.theia, RM.venus ] - // MARK: - body Property + // MARK: - Body Property + var body: some View { VStack(spacing: 25) { // Art letter magic text. MagicView( text: singleLineExampleText, textColors: [.black.opacity(0.7)], - fontSize: 25, + fontSize: 28, magicType: .artLetter ) { print("Animation finished") @@ -44,7 +46,7 @@ struct ExampleArtLetterView: View { MagicView( text: multiLineExampleText, textColors: colors.map { Color($0) }, - fontSize: 25, + fontSize: 28, magicType: .artLetter, delayStart: 5 ) { @@ -55,6 +57,7 @@ struct ExampleArtLetterView: View { } // MARK: - Preview Provider + struct ExampleArtLetterView_Previews: PreviewProvider { static var previews: some View { ExampleArtLetterView() diff --git a/Examples/ExampleBubbleView.swift b/Examples/ExampleBubbleView.swift index d9e001a..7fde6d1 100644 --- a/Examples/ExampleBubbleView.swift +++ b/Examples/ExampleBubbleView.swift @@ -12,6 +12,7 @@ import MagicText struct ExampleBubbleView: View { // MARK: - Private Properties + private let singleLineExampleText = "Life is like a box of chocolates, you never know what you’re gonna get." private let multiLineExampleText = """ @@ -22,18 +23,19 @@ struct ExampleBubbleView: View { """ private let colors = [ - candy, coffee, flower, forest, newyork, - night, sky, smoke, theia, venus + RM.candy, RM.coffee, RM.flower, RM.forest, RM.newyork, + RM.night, RM.sky, RM.smoke, RM.theia, RM.venus ] - // MARK: - body Property + // MARK: - Body Property + var body: some View { VStack(spacing: 25) { // Bubble magic text. MagicView( text: singleLineExampleText, textColors: [.black.opacity(0.7)], - fontSize: 30, + fontSize: 28, magicType: .bubble ) { print("Animation finished") @@ -44,7 +46,7 @@ struct ExampleBubbleView: View { MagicView( text: multiLineExampleText, textColors: colors.map { Color($0) }, - fontSize: 30, + fontSize: 28, magicType: .bubble, delayStart: 5 ) { @@ -55,6 +57,7 @@ struct ExampleBubbleView: View { } // MARK: - Preview Provider + struct ExampleBubbleView_Previews: PreviewProvider { static var previews: some View { ExampleBubbleView() diff --git a/Examples/ExampleCharmedLetterView.swift b/Examples/ExampleCharmedLetterView.swift index d734ed8..95a1127 100644 --- a/Examples/ExampleCharmedLetterView.swift +++ b/Examples/ExampleCharmedLetterView.swift @@ -12,6 +12,7 @@ import MagicText struct ExampleCharmedLetterView: View { // MARK: - Private Properties + private let singleLineExampleText = "Life is like a box of chocolates, you never know what you’re gonna get." private let multiLineExampleText = """ @@ -22,18 +23,19 @@ struct ExampleCharmedLetterView: View { """ private let colors = [ - candy, coffee, flower, forest, newyork, - night, sky, smoke, theia, venus + RM.candy, RM.coffee, RM.flower, RM.forest, RM.newyork, + RM.night, RM.sky, RM.smoke, RM.theia, RM.venus ] - // MARK: - body Property + // MARK: - Body Property + var body: some View { VStack(spacing: 25) { // Charmed letter magic text. MagicView( text: singleLineExampleText, textColors: [.black.opacity(0.7)], - fontSize: 30, + fontSize: 28, magicType: .charmedLetter() ) { print("Animation finished") @@ -44,7 +46,7 @@ struct ExampleCharmedLetterView: View { MagicView( text: multiLineExampleText, textColors: colors.map { Color($0) }, - fontSize: 30, + fontSize: 28, magicType: .charmedLetter(backgroundColor: .blue), delayStart: 5 ) { @@ -55,6 +57,7 @@ struct ExampleCharmedLetterView: View { } // MARK: - Preview Provider + struct ExampleCharmedLetterView_Previews: PreviewProvider { static var previews: some View { ExampleCharmedLetterView() diff --git a/Examples/ExampleCharmedView.swift b/Examples/ExampleCharmedView.swift index 4d40b03..804adab 100644 --- a/Examples/ExampleCharmedView.swift +++ b/Examples/ExampleCharmedView.swift @@ -12,6 +12,7 @@ import MagicText struct ExampleCharmedView: View { // MARK: - Private Properties + private let singleLineExampleText = "Life is like a box of chocolates, you never know what you’re gonna get." private let multiLineExampleText = """ @@ -22,17 +23,18 @@ struct ExampleCharmedView: View { """ private let colors = [ - candy, coffee, flower, forest, newyork, - night, sky, smoke, theia, venus + RM.candy, RM.coffee, RM.flower, RM.forest, RM.newyork, + RM.night, RM.sky, RM.smoke, RM.theia, RM.venus ] - // MARK: - body Property + // MARK: - Body Property + var body: some View { VStack(spacing: 25) { // Charmed magic text (default). MagicView( text: singleLineExampleText, - fontSize: 30 + fontSize: 28 ) { print("Animation finished") } @@ -42,7 +44,7 @@ struct ExampleCharmedView: View { MagicView( text: multiLineExampleText, textColors: [.black, .red, .orange, .yellow, .green, .blue], - fontSize: 30, + fontSize: 28, delayStart: 5 ) { print("Animation finished") diff --git a/Examples/ExampleFantasyView.swift b/Examples/ExampleFantasyView.swift index 0d048da..c424ec8 100644 --- a/Examples/ExampleFantasyView.swift +++ b/Examples/ExampleFantasyView.swift @@ -12,6 +12,7 @@ import MagicText struct ExampleFantasyView: View { // MARK: - Private Properties + private let singleLineExampleText = "Life is like a box of chocolates, you never know what you’re gonna get." private let multiLineExampleText = """ @@ -22,18 +23,19 @@ struct ExampleFantasyView: View { """ private let colors = [ - candy, coffee, flower, forest, newyork, - night, sky, smoke, theia, venus + RM.candy, RM.coffee, RM.flower, RM.forest, RM.newyork, + RM.night, RM.sky, RM.smoke, RM.theia, RM.venus ] - // MARK: - body Property + // MARK: - Body Property + var body: some View { VStack(spacing: 25) { // Fantasy magic text. MagicView( text: singleLineExampleText, textColors: [.black.opacity(0.7)], - fontSize: 30, + fontSize: 28, magicType: .fantasy ) { print("Animation finished") @@ -44,7 +46,7 @@ struct ExampleFantasyView: View { MagicView( text: multiLineExampleText, textColors: colors.map { Color($0) }, - fontSize: 30, + fontSize: 28, magicType: .fantasy, delayStart: 5 ) { @@ -55,6 +57,7 @@ struct ExampleFantasyView: View { } // MARK: - Preview Provider + struct ExampleFantasyView_Previews: PreviewProvider { static var previews: some View { ExampleFantasyView() diff --git a/README.md b/README.md index 1fa1a86..2962901 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Magic text is the perfect solution when you need to show a small amount of infor ## Installation ### [Swift Package Manager](https://swift.org/package-manager/) -Going to Xcode `File` > `Add Packages...` and add the repository by giving the URL `https://github.com/bullinnyc/MagicText` +Going to Xcode `File` > `Add Packages...` and add the repository by giving the URL `https://github.com/bullinnyc/MagicText` Enjoy! ## Usage diff --git a/Sources/MagicText/AnimatableModifiers/AnimationCompletionViewModifier.swift b/Sources/MagicText/AnimatableModifiers/AnimationCompletionViewModifier.swift index 37f16d4..95d93f2 100644 --- a/Sources/MagicText/AnimatableModifiers/AnimationCompletionViewModifier.swift +++ b/Sources/MagicText/AnimatableModifiers/AnimationCompletionViewModifier.swift @@ -12,6 +12,7 @@ struct AnimationCompletionAnimatableModifier: AnimatableModifier where Value: VectorArithmetic { // MARK: - Animatable Protocol Properties + var animatableData: Value { didSet { notifyCompletionIfFinished() @@ -19,22 +20,26 @@ struct AnimationCompletionAnimatableModifier: } // MARK: - Private Properties + private let targetValue: Value private let completion: () -> Void // MARK: - Initializers + init(value: Value, completion: @escaping () -> Void) { self.completion = completion animatableData = value targetValue = value } - // MARK: - body Method + // MARK: - Body Method + func body(content: Content) -> some View { content } // MARK: - Private Methods + private func notifyCompletionIfFinished() { guard animatableData == targetValue else { return } @@ -45,6 +50,7 @@ struct AnimationCompletionAnimatableModifier: } // MARK: - Ext. View + extension View { func onAnimationCompleted( value: Value, diff --git a/Sources/MagicText/Resources/ResourcesManager.swift b/Sources/MagicText/Resources/ResourcesManager.swift index ce00d5c..3dbc1eb 100644 --- a/Sources/MagicText/Resources/ResourcesManager.swift +++ b/Sources/MagicText/Resources/ResourcesManager.swift @@ -9,64 +9,81 @@ #if canImport(UIKit) import UIKit -// Colors. -public let candy = UIColor( - named: "candy", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() +/// Resources manager typealias. +public typealias RM = ResourcesManager -public let coffee = UIColor( - named: "coffee", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() +/// Resources manager. +public final class ResourcesManager { + // MARK: - Public Properties + + /// An object that stores color data. + public static let candy = UIColor( + named: "candy", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let flower = UIColor( - named: "flower", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let coffee = UIColor( + named: "coffee", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let forest = UIColor( - named: "forest", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let flower = UIColor( + named: "flower", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let newyork = UIColor( - named: "newyork", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let forest = UIColor( + named: "forest", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let night = UIColor( - named: "night", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let newyork = UIColor( + named: "newyork", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let sky = UIColor( - named: "sky", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let night = UIColor( + named: "night", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let smoke = UIColor( - named: "smoke", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let sky = UIColor( + named: "sky", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let theia = UIColor( - named: "theia", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let smoke = UIColor( + named: "smoke", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() -public let venus = UIColor( - named: "venus", - in: Bundle.module, - compatibleWith: nil -) ?? UIColor() + /// An object that stores color data. + public static let theia = UIColor( + named: "theia", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() + + /// An object that stores color data. + public static let venus = UIColor( + named: "venus", + in: Bundle.module, + compatibleWith: nil + ) ?? UIColor() +} #endif diff --git a/Sources/MagicText/Services/DataManager.swift b/Sources/MagicText/Services/DataManager.swift index a995a21..0ad7fd9 100644 --- a/Sources/MagicText/Services/DataManager.swift +++ b/Sources/MagicText/Services/DataManager.swift @@ -10,8 +10,9 @@ import Foundation class DataManager { // MARK: - Public Properties + static let colorsName = [ - candy, coffee, flower, forest, newyork, - night, sky, smoke, theia, venus + RM.candy, RM.coffee, RM.flower, RM.forest, RM.newyork, + RM.night, RM.sky, RM.smoke, RM.theia, RM.venus ] } diff --git a/Sources/MagicText/ViewModifiers/MaskViewModifier.swift b/Sources/MagicText/ViewModifiers/MaskViewModifier.swift index 2d2269a..8b64171 100644 --- a/Sources/MagicText/ViewModifiers/MaskViewModifier.swift +++ b/Sources/MagicText/ViewModifiers/MaskViewModifier.swift @@ -10,11 +10,13 @@ import SwiftUI private struct MaskViewModifier: ViewModifier { // MARK: - Public Properties + let text: String let fontName: String let fontScale: CGFloat - // MARK: - body Method + // MARK: - Body Method + func body(content: Content) -> some View { if #available(iOS 15.0, *) { content @@ -33,6 +35,7 @@ private struct MaskViewModifier: ViewModifier { } // MARK: - Ext. View + extension View { func mask( text: String, diff --git a/Sources/MagicText/Views/ArtLetterView.swift b/Sources/MagicText/Views/ArtLetterView.swift index aee2f88..afff275 100644 --- a/Sources/MagicText/Views/ArtLetterView.swift +++ b/Sources/MagicText/Views/ArtLetterView.swift @@ -10,10 +10,12 @@ import SwiftUI struct ArtLetterView: View { // MARK: - Property Wrappers + @State private var opacity: Double = 0 @State private var isAnimationCompleted = false // MARK: - Public Properties + let symbol: String let textColor: Color let fontName: String @@ -21,7 +23,8 @@ struct ArtLetterView: View { let delay: Double let completion: () -> Void - // MARK: - body Property + // MARK: - Body Property + var body: some View { let updatedSymbol = symbol == " " ? " " : symbol let colors = DataManager.colorsName.map { Color($0) } @@ -51,13 +54,14 @@ struct ArtLetterView: View { } // MARK: - Preview Provider + struct ArtLetterView_Previews: PreviewProvider { static var previews: some View { ArtLetterView( symbol: "K", textColor: .black, fontName: "Baskerville", - fontSize: 30, + fontSize: 28, delay: 0 ) {} } diff --git a/Sources/MagicText/Views/BubbleView.swift b/Sources/MagicText/Views/BubbleView.swift index dcebbdf..d71a40e 100644 --- a/Sources/MagicText/Views/BubbleView.swift +++ b/Sources/MagicText/Views/BubbleView.swift @@ -10,10 +10,12 @@ import SwiftUI struct BubbleView: View { // MARK: - Property Wrappers + @State private var blur: CGFloat = 10 @State private var isAnimationCompleted = false // MARK: - Public Properties + let symbol: String let textColor: Color let fontName: String @@ -22,7 +24,8 @@ struct BubbleView: View { let delay: Double let completion: () -> Void - // MARK: - body Property + // MARK: - Body Property + var body: some View { let updatedSymbol = symbol == " " ? " " : symbol @@ -73,13 +76,14 @@ struct BubbleView: View { } // MARK: - Preview Provider + struct BubbleView_Previews: PreviewProvider { static var previews: some View { BubbleView( symbol: "K", textColor: .black, fontName: "Baskerville", - fontSize: 30, + fontSize: 28, isMask: true, delay: 0 ) {} diff --git a/Sources/MagicText/Views/CharmedLetterView.swift b/Sources/MagicText/Views/CharmedLetterView.swift index 3c92fd8..ac1a0c3 100644 --- a/Sources/MagicText/Views/CharmedLetterView.swift +++ b/Sources/MagicText/Views/CharmedLetterView.swift @@ -10,10 +10,12 @@ import SwiftUI struct CharmedLetterView: View { // MARK: - Property Wrappers + @State private var blur: CGFloat = 10 @State private var isAnimationCompleted = false // MARK: - Public Properties + let symbol: String let textColor: Color let fontName: String @@ -23,7 +25,8 @@ struct CharmedLetterView: View { let delay: Double let completion: () -> Void - // MARK: - body Property + // MARK: - Body Property + var body: some View { let updatedSymbol = symbol == " " ? " " : symbol @@ -74,13 +77,14 @@ struct CharmedLetterView: View { } // MARK: - Preview Provider + struct CharmedLetterView_Previews: PreviewProvider { static var previews: some View { CharmedLetterView( symbol: "K", textColor: .black, fontName: "Baskerville", - fontSize: 30, + fontSize: 28, backgroundColor: .red, isMask: true, delay: 0 diff --git a/Sources/MagicText/Views/CharmedView.swift b/Sources/MagicText/Views/CharmedView.swift index 2f1d6d7..87477eb 100644 --- a/Sources/MagicText/Views/CharmedView.swift +++ b/Sources/MagicText/Views/CharmedView.swift @@ -10,10 +10,12 @@ import SwiftUI struct CharmedView: View { // MARK: - Property Wrappers + @State private var blur: CGFloat = 10 @State private var isAnimationCompleted = false // MARK: - Public Properties + let symbol: String let textColor: Color let fontName: String @@ -22,7 +24,8 @@ struct CharmedView: View { let delay: Double let completion: () -> Void - // MARK: - body Property + // MARK: - Body Property + var body: some View { Group { if isMask { @@ -61,13 +64,14 @@ struct CharmedView: View { } // MARK: - Preview Provider + struct CharmedView_Previews: PreviewProvider { static var previews: some View { CharmedView( symbol: "K", textColor: .black, fontName: "Baskerville", - fontSize: 30, + fontSize: 28, isMask: true, delay: 0 ) {} diff --git a/Sources/MagicText/Views/FantasyView.swift b/Sources/MagicText/Views/FantasyView.swift index dbe7ef7..73d1749 100644 --- a/Sources/MagicText/Views/FantasyView.swift +++ b/Sources/MagicText/Views/FantasyView.swift @@ -10,10 +10,12 @@ import SwiftUI struct FantasyView: View { // MARK: - Property Wrappers + @State private var blur: CGFloat = 10 @State private var isAnimationCompleted = false // MARK: - Public Properties + let symbol: String let textColor: Color let fontName: String @@ -22,7 +24,8 @@ struct FantasyView: View { let delay: Double let completion: () -> Void - // MARK: - body Property + // MARK: - Body Property + var body: some View { let updatedSymbol = symbol == " " ? " " : symbol @@ -74,13 +77,14 @@ struct FantasyView: View { } // MARK: - Preview Provider + struct FantasyView_Previews: PreviewProvider { static var previews: some View { FantasyView( symbol: "K", textColor: .black, fontName: "Baskerville", - fontSize: 30, + fontSize: 28, isMask: true, delay: 0 ) {} diff --git a/Sources/MagicText/Views/MagicView.swift b/Sources/MagicText/Views/MagicView.swift index 2bb97a2..5519184 100644 --- a/Sources/MagicText/Views/MagicView.swift +++ b/Sources/MagicText/Views/MagicView.swift @@ -11,9 +11,11 @@ import SwiftUI /// Show a magic view. public struct MagicView: View { // MARK: - Property Wrappers + @State private var animationCounter = 0 // MARK: - Private Properties + private let text: String private let textColors: [Color] private let textAlignment: HorizontalAlignment @@ -25,6 +27,7 @@ public struct MagicView: View { private let completion: (() -> Void)? // MARK: - Public Enums + public enum MagicType { case charmed case artLetter @@ -33,22 +36,28 @@ public struct MagicView: View { case charmedLetter(backgroundColor: Color = .red) } - // MARK: - body Property + // MARK: - Body Property + public var body: some View { VStack(alignment: textAlignment) { - let texts = createTexts(text, minCharactersPerLine: minCharactersPerLine) + let texts = createTexts( + text: text, + minCharactersPerLine: minCharactersPerLine + ) + let textCount = texts.joined().count ForEach(texts, id: \.self) { element in HStack(spacing: 0.5) { ForEach(0 ..< element.count, id: \.self) { index in - let perLineDelay = delayStart + Double.random(in: 0.1 ... 1.8) + let perLineDelay = delayStart + + Double.random(in: 0.1 ... 1.8) let firstDelay = perLineDelay + Double(index) * 0.5 * - Double.random(in: 0.004 ... 0.5) + Double.random(in: 0.004 ... 0.5) let secondDelay = perLineDelay + Double(index) * - Double.random(in: 0.1 ... 0.3) + Double.random(in: 0.1 ... 0.3) let symbol = String(Array(element)[index]) let textColor = textColors.randomElement() ?? .black @@ -193,6 +202,7 @@ public struct MagicView: View { } // MARK: - Initializers + /// - Parameters: /// - text: Text to be displayed. /// - textColors: Colors for text. Default value `.black`. @@ -228,12 +238,18 @@ public struct MagicView: View { } // MARK: - Private Methods - private func createTexts(_ text: String, minCharactersPerLine: Int) -> [String] { + + private func createTexts( + text: String, + minCharactersPerLine: Int + ) -> [String] { var texts: [String] = [] var lineOfText = "" + let isNewline = text.first(where: { $0.isNewline }) != nil + text.enumerated().forEach { index, character in - if text.contains(where: { $0.isNewline }) { + if isNewline { if character == "\n" { texts.append(lineOfText) lineOfText = "" @@ -280,13 +296,14 @@ public struct MagicView: View { } // MARK: - Preview Provider + struct MagicView_Previews: PreviewProvider { static var previews: some View { let text = "Life is like a box of chocolates, you never know what you’re gonna get." MagicView( text: text, - fontSize: 30, + fontSize: 28, minCharactersPerLine: 10 ) }