7 Commits

Author SHA1 Message Date
Daniel Arantes Loverde
a24b79f443 only remote crypto kit 2026-05-24 10:26:25 -03:00
c0eb5f95c6 Merge pull request 'fix: update keyboard notification handling for Swift concurrency' (#7) from bugfix/snackbar_for_iOS26 into main
Reviewed-on: #7
2026-04-07 11:22:02 -03:00
a15d95ed59 Merge branch 'main' into bugfix/snackbar_for_iOS26 2026-04-07 11:21:55 -03:00
Daniel Arantes Loverde
40581d791a fix: update keyboard notification handling for Swift concurrency
Keep snackbar keyboard animations on the main actor and read UIKit keyboard values using the expected notification payload types.

Made-with: Cursor
2026-04-07 11:19:39 -03:00
57ce0dc87a Merge pull request 'iPhone UIDevice names updated' (#6) from feature/LCECryptoKit into main
Reviewed-on: #6
2026-02-11 20:57:39 +00:00
Daniel Arantes Loverde
d06a66226e iPhone UIDevice names updated 2026-02-11 17:56:53 -03:00
336b47ace2 Merge pull request 'Optional' (#5) from feature/LCECryptoKit into main
Reviewed-on: #5
2026-02-06 15:38:09 +00:00
8 changed files with 144 additions and 104 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
.DS_Store .DS_Store
/.build /.build
/build
/Packages /Packages
xcuserdata/ xcuserdata/
DerivedData/ DerivedData/

View File

@@ -22,3 +22,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
Autor: Daniel Arantes Loverde

View File

@@ -3,8 +3,8 @@
"pins" : [ "pins" : [
{ {
"identity" : "lcecryptokitbinary", "identity" : "lcecryptokitbinary",
"kind" : "localSourceControl", "kind" : "remoteSourceControl",
"location" : "/Users/loverde_co/Documents/Loverde_JOBs/Producao/Loverde Co/GIT/XCODE/Repositorios/LCECryptoKit/PrivateLib/LCECryptoKitBinary", "location" : "https://60c260c85d3a2fe840411b0ff98f521b5eca3c56@git.loverde.com.br/Loverde-Company-LTDA/LCECryptoKitBinary.git",
"state" : { "state" : {
"revision" : "2c5c47cebef40a8adc5557d071a35be405c05e30", "revision" : "2c5c47cebef40a8adc5557d071a35be405c05e30",
"version" : "1.0.2" "version" : "1.0.2"

View File

@@ -2,7 +2,7 @@
import PackageDescription import PackageDescription
import Foundation import Foundation
let isLocalDevelopment = FileManager.default.fileExists(atPath: "../LCECryptoKit/PrivateLib/LCECryptoKitBinary") let isLocalDevelopment = false //FileManager.default.fileExists(atPath: "../LCECryptoKit/PrivateLib/LCECryptoKitBinary")
let enableCryptoBinary = ProcessInfo.processInfo.environment["LCE_ENABLE_CRYPTO_BINARY"] != "0" let enableCryptoBinary = ProcessInfo.processInfo.environment["LCE_ENABLE_CRYPTO_BINARY"] != "0"
let cryptoPackageURL = isLocalDevelopment let cryptoPackageURL = isLocalDevelopment

View File

@@ -59,12 +59,11 @@ And then import `LCEssentials ` wherever you import UIKit or SwiftUI
import LCEssentials import LCEssentials
``` ```
Author:
----
Any question or doubts, please send thru email Any question or doubts, please send thru email
Daniel Arantes Loverde - <daniel@loverde.com.br> Daniel Arantes Loverde - <daniel@loverde.com.br>
[![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "My Resume")](https://github.com/loverde-co/resume/) [![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "My Resume")](https://github.com/loverde-co/resume/)
[![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "Loverde Co. Github")](https://github.com/loverde-co) [![Alt text](https://loverde.com.br/_signature/loverde_github_mail.gif "Loverde Co. Github")](https://github.com/loverde-co)
Autor: Daniel Arantes Loverde

View File

@@ -66,59 +66,104 @@ public extension UIDevice {
#if os(iOS) #if os(iOS)
switch identifier { switch identifier {
case "iPod5,1": return "iPod touch (5th generation)" case "iPod5,1": return "iPod touch (5th generation)"
case "iPod7,1": return "iPod touch (6th generation)" case "iPod7,1": return "iPod touch (6th generation)"
case "iPod9,1": return "iPod touch (7th generation)" case "iPod9,1": return "iPod touch (7th generation)"
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4" case "iPhone3,1", "iPhone3,2", "iPhone3,3": return "iPhone 4"
case "iPhone4,1": return "iPhone 4s" case "iPhone4,1": return "iPhone 4s"
case "iPhone5,1", "iPhone5,2": return "iPhone 5" case "iPhone5,1", "iPhone5,2": return "iPhone 5"
case "iPhone5,3", "iPhone5,4": return "iPhone 5c" case "iPhone5,3", "iPhone5,4": return "iPhone 5c"
case "iPhone6,1", "iPhone6,2": return "iPhone 5s" case "iPhone6,1", "iPhone6,2": return "iPhone 5s"
case "iPhone7,2": return "iPhone 6" case "iPhone7,2": return "iPhone 6"
case "iPhone7,1": return "iPhone 6 Plus" case "iPhone7,1": return "iPhone 6 Plus"
case "iPhone8,1": return "iPhone 6s" case "iPhone8,1": return "iPhone 6s"
case "iPhone8,2": return "iPhone 6s Plus" case "iPhone8,2": return "iPhone 6s Plus"
case "iPhone9,1", "iPhone9,3": return "iPhone 7" case "iPhone9,1", "iPhone9,3": return "iPhone 7"
case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus" case "iPhone9,2", "iPhone9,4": return "iPhone 7 Plus"
case "iPhone8,4", "iPhone12,8": return "iPhone SE" case "iPhone10,1", "iPhone10,4": return "iPhone 8"
case "iPhone10,1", "iPhone10,4": return "iPhone 8" case "iPhone10,2", "iPhone10,5": return "iPhone 8 Plus"
case "iPhone10,2", "iPhone10,5": return "iPhone 8 Plus" case "iPhone10,3", "iPhone10,6": return "iPhone X"
case "iPhone10,3", "iPhone10,6": return "iPhone X" case "iPhone11,2": return "iPhone XS"
case "iPhone11,2": return "iPhone XS" case "iPhone11,4", "iPhone11,6": return "iPhone XS Max"
case "iPhone11,4", "iPhone11,6": return "iPhone XS Max" case "iPhone11,8": return "iPhone XR"
case "iPhone11,8": return "iPhone XR" case "iPhone12,1": return "iPhone 11"
case "iPhone12,1": return "iPhone 11" case "iPhone12,3": return "iPhone 11 Pro"
case "iPhone12,3": return "iPhone 11 Pro" case "iPhone12,5": return "iPhone 11 Pro Max"
case "iPhone12,5": return "iPhone 11 Pro Max" case "iPhone13,1": return "iPhone 12 mini"
case "iPhone13,1": return "iPhone 12 mini" case "iPhone13,2": return "iPhone 12"
case "iPhone13,2": return "iPhone 12" case "iPhone13,3": return "iPhone 12 Pro"
case "iPhone13,3": return "iPhone 12 Pro" case "iPhone13,4": return "iPhone 12 Pro Max"
case "iPhone13,4": return "iPhone 12 Pro Max" case "iPhone14,4": return "iPhone 13 mini"
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2" case "iPhone14,5": return "iPhone 13"
case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad 3" case "iPhone14,2": return "iPhone 13 Pro"
case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad 4" case "iPhone14,3": return "iPhone 13 Pro Max"
case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air" case "iPhone14,7": return "iPhone 14"
case "iPad5,3", "iPad5,4": return "iPad Air 2" case "iPhone14,8": return "iPhone 14 Plus"
case "iPad6,11", "iPad6,12": return "iPad 5" case "iPhone15,2": return "iPhone 14 Pro"
case "iPad7,5", "iPad7,6": return "iPad 6" case "iPhone15,3": return "iPhone 14 Pro Max"
case "iPad7,11", "iPad7,12": return "iPad 7" case "iPhone15,4": return "iPhone 15"
case "iPad11,4", "iPad11,5": return "iPad Air (3rd generation)" case "iPhone15,5": return "iPhone 15 Plus"
case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad Mini" case "iPhone16,1": return "iPhone 15 Pro"
case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad Mini 2" case "iPhone16,2": return "iPhone 15 Pro Max"
case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad Mini 3" case "iPhone17,3": return "iPhone 16"
case "iPad5,1", "iPad5,2": return "iPad Mini 4" case "iPhone17,4": return "iPhone 16 Plus"
case "iPad11,1", "iPad11,2": return "iPad Mini 5" case "iPhone17,1": return "iPhone 16 Pro"
case "iPad6,3", "iPad6,4": return "iPad Pro (9.7-inch)" case "iPhone17,2": return "iPhone 16 Pro Max"
case "iPad6,7", "iPad6,8": return "iPad Pro (12.9-inch)" case "iPhone17,5": return "iPhone 16e"
case "iPad7,1", "iPad7,2": return "iPad Pro (12.9-inch) (2nd generation)" case "iPhone18,3": return "iPhone 17"
case "iPad7,3", "iPad7,4": return "iPad Pro (10.5-inch)" case "iPhone18,4": return "iPhone Air"
case "iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4":return "iPad Pro (11-inch)" case "iPhone18,1": return "iPhone 17 Pro"
case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8":return "iPad Pro (12.9-inch) (3rd generation)" case "iPhone18,2": return "iPhone 17 Pro Max"
case "AppleTV5,3": return "Apple TV" case "iPhone8,4": return "iPhone SE"
case "AppleTV6,2": return "Apple TV 4K" case "iPhone12,8": return "iPhone SE (2nd generation)"
case "AudioAccessory1,1": return "HomePod" case "iPhone14,6": return "iPhone SE (3rd generation)"
case "i386", "x86_64": return "Simulator \(identifier)" case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4": return "iPad 2"
default: return identifier case "iPad3,1", "iPad3,2", "iPad3,3": return "iPad (3rd generation)"
case "iPad3,4", "iPad3,5", "iPad3,6": return "iPad (4th generation)"
case "iPad6,11", "iPad6,12": return "iPad (5th generation)"
case "iPad7,5", "iPad7,6": return "iPad (6th generation)"
case "iPad7,11", "iPad7,12": return "iPad (7th generation)"
case "iPad11,6", "iPad11,7": return "iPad (8th generation)"
case "iPad12,1", "iPad12,2": return "iPad (9th generation)"
case "iPad13,18", "iPad13,19": return "iPad (10th generation)"
case "iPad15,7", "iPad15,8": return "iPad (11th generation)"
case "iPad4,1", "iPad4,2", "iPad4,3": return "iPad Air"
case "iPad5,3", "iPad5,4": return "iPad Air 2"
case "iPad11,3", "iPad11,4": return "iPad Air (3rd generation)"
case "iPad13,1", "iPad13,2": return "iPad Air (4th generation)"
case "iPad13,16", "iPad13,17": return "iPad Air (5th generation)"
case "iPad14,8", "iPad14,9": return "iPad Air (11-inch) (M2)"
case "iPad14,10", "iPad14,11": return "iPad Air (13-inch) (M2)"
case "iPad15,3", "iPad15,4": return "iPad Air (11-inch) (M3)"
case "iPad15,5", "iPad15,6": return "iPad Air (13-inch) (M3)"
case "iPad2,5", "iPad2,6", "iPad2,7": return "iPad mini"
case "iPad4,4", "iPad4,5", "iPad4,6": return "iPad mini 2"
case "iPad4,7", "iPad4,8", "iPad4,9": return "iPad mini 3"
case "iPad5,1", "iPad5,2": return "iPad mini 4"
case "iPad11,1", "iPad11,2": return "iPad mini (5th generation)"
case "iPad14,1", "iPad14,2": return "iPad mini (6th generation)"
case "iPad16,1", "iPad16,2": return "iPad mini (A17 Pro)"
case "iPad6,3", "iPad6,4": return "iPad Pro (9.7-inch)"
case "iPad7,3", "iPad7,4": return "iPad Pro (10.5-inch)"
case "iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4": return "iPad Pro (11-inch) (1st generation)"
case "iPad8,9", "iPad8,10": return "iPad Pro (11-inch) (2nd generation)"
case "iPad13,4", "iPad13,5", "iPad13,6", "iPad13,7": return "iPad Pro (11-inch) (3rd generation)"
case "iPad14,3", "iPad14,4": return "iPad Pro (11-inch) (4th generation)"
case "iPad16,3", "iPad16,4": return "iPad Pro (11-inch) (M4)"
case "iPad17,1", "iPad17,2": return "iPad Pro (11-inch) (M5)"
case "iPad6,7", "iPad6,8": return "iPad Pro (12.9-inch) (1st generation)"
case "iPad7,1", "iPad7,2": return "iPad Pro (12.9-inch) (2nd generation)"
case "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8": return "iPad Pro (12.9-inch) (3rd generation)"
case "iPad8,11", "iPad8,12": return "iPad Pro (12.9-inch) (4th generation)"
case "iPad13,8", "iPad13,9", "iPad13,10", "iPad13,11":return "iPad Pro (12.9-inch) (5th generation)"
case "iPad14,5", "iPad14,6": return "iPad Pro (12.9-inch) (6th generation)"
case "iPad16,5", "iPad16,6": return "iPad Pro (13-inch) (M4)"
case "iPad17,3", "iPad17,4": return "iPad Pro (13-inch) (M5)"
case "AppleTV5,3": return "Apple TV"
case "AppleTV6,2": return "Apple TV 4K"
case "AudioAccessory1,1": return "HomePod"
case "AudioAccessory5,1": return "HomePod mini"
default: return identifier
} }
#endif #endif
} }

View File

@@ -233,53 +233,36 @@ public extension LCSnackBarView {
/// Handles the `keyboardWillShowNotification` to adjust the snackbar's position. /// Handles the `keyboardWillShowNotification` to adjust the snackbar's position.
/// - Parameter notification: The `Notification` object containing keyboard information. /// - Parameter notification: The `Notification` object containing keyboard information.
@objc private func keyboardWillShow(_ notification: Notification?) -> Void { @MainActor
@objc private func keyboardWillShow(_ notification: Notification?) {
guard let info = notification?.userInfo else { return }
if let info = notification?.userInfo { systemKeyboardVisible = true
systemKeyboardVisible = true let animationCurveRaw = (info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue
// ?? UInt(UIView.AnimationCurve.easeOut.rawValue)
let curveUserInfoKey = UIResponder.keyboardAnimationCurveUserInfoKey let animationDuration = (info[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue
let durationUserInfoKey = UIResponder.keyboardAnimationDurationUserInfoKey ?? 0.25
let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey let keyboardFrame = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
// ?? .zero
var animationCurve: UIView.AnimationOptions = .curveEaseOut let height = keyboardFrame.height
var animationDuration: TimeInterval = 0.25 let animationCurve = UIView.AnimationOptions(rawValue: animationCurveRaw << 16)
var height:CGFloat = 0.0
// Getting keyboard animation. UIView.animate(
if let curve = info[curveUserInfoKey] as? UIView.AnimationOptions { withDuration: animationDuration,
animationCurve = curve delay: 0,
} options: animationCurve
) { [weak self] in
// Getting keyboard animation duration self?.frame.origin.y += height
if let duration = info[durationUserInfoKey] as? TimeInterval {
animationDuration = duration
}
// Getting UIKeyboardSize.
if let kbFrame = info[frameEndUserInfoKey] as? CGRect {
height = kbFrame.size.height
}
DispatchQueue.main.async { [weak self] in
UIView.animate(withDuration: animationDuration,
delay: 0,
options: animationCurve,
animations: {
self?.frame.origin.y += height
})
}
} }
} }
/// Handles the `keyboardWillHideNotification`. /// Handles the `keyboardWillHideNotification`.
/// - Parameter notification: The `Notification` object. /// - Parameter notification: The `Notification` object.
@objc private func keyboardWillHide(_ notification: Notification?) -> Void { @MainActor
DispatchQueue.main.async { [weak self] in @objc private func keyboardWillHide(_ notification: Notification?) {
self?.systemKeyboardVisible = false systemKeyboardVisible = false
// keyboard is hidded // keyboard is hidded
}
} }
/// Updates the snackbar's style properties, such as width and corner radius, based on `_style`. /// Updates the snackbar's style properties, such as width and corner radius, based on `_style`.

View File

@@ -47,6 +47,8 @@ class LCENavigationState: ObservableObject {
@Published var title: (any View) = Text("") @Published var title: (any View) = Text("")
/// The subtitle view of the navigation bar. /// The subtitle view of the navigation bar.
@Published var subTitle: (any View) = Text("") @Published var subTitle: (any View) = Text("")
/// The background color of the navigation bar.
@Published var navigationBarBackgroundColor: Color = .clear
} }
/// `LCENavigationView` is a SwiftUI `View` that provides a customizable navigation bar. /// `LCENavigationView` is a SwiftUI `View` that provides a customizable navigation bar.
@@ -79,7 +81,7 @@ public struct LCENavigationView<Content: View>: View {
/// The body of the `LCENavigationView`. /// The body of the `LCENavigationView`.
public var body: some View { public var body: some View {
VStack { VStack(spacing: 0) {
if !state.hideNavigationBar { if !state.hideNavigationBar {
NavigationBarView NavigationBarView
} }
@@ -100,7 +102,7 @@ public struct LCENavigationView<Content: View>: View {
.font(.headline) .font(.headline)
.padding() .padding()
.background { .background {
Color.clear.ignoresSafeArea(edges: .top) state.navigationBarBackgroundColor.ignoresSafeArea(edges: .top)
} }
} }
@@ -217,6 +219,14 @@ public struct LCENavigationView<Content: View>: View {
state.hideNavigationBar = hide state.hideNavigationBar = hide
return self return self
} }
/// Sets the background color for the navigation bar.
/// - Parameter color: The color to use as the navigation bar background.
/// - Returns: The `LCENavigationView` instance for chaining.
public func setNavigationBarBackgroundColor(_ color: Color) -> LCENavigationView {
state.navigationBarBackgroundColor = color
return self
}
} }
/// Extension to `FormatStyle` to format any value as a string. /// Extension to `FormatStyle` to format any value as a string.