mirror of https://github.com/xaoxuu/ProHUD
适配iPad多窗口;去除对Inspire的依赖
This commit is contained in:
parent
e64976bb08
commit
27138a49e9
|
@ -12,13 +12,12 @@
|
||||||
CD6537C328C35E6200A5981B /* ToastVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6537C228C35E6200A5981B /* ToastVC.swift */; };
|
CD6537C328C35E6200A5981B /* ToastVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6537C228C35E6200A5981B /* ToastVC.swift */; };
|
||||||
CD6537C528C35F2C00A5981B /* SheetVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6537C428C35F2C00A5981B /* SheetVC.swift */; };
|
CD6537C528C35F2C00A5981B /* SheetVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD6537C428C35F2C00A5981B /* SheetVC.swift */; };
|
||||||
CD6AE8A32A7CC1BA0044E53D /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = CD6AE8A22A7CC1BA0044E53D /* SnapKit */; };
|
CD6AE8A32A7CC1BA0044E53D /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = CD6AE8A22A7CC1BA0044E53D /* SnapKit */; };
|
||||||
CD6AE8A62A7CC1C70044E53D /* Inspire in Frameworks */ = {isa = PBXBuildFile; productRef = CD6AE8A52A7CC1C70044E53D /* Inspire */; };
|
|
||||||
CD8EEF3B28BC5C7200E660EA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8EEF3A28BC5C7200E660EA /* AppDelegate.swift */; };
|
CD8EEF3B28BC5C7200E660EA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8EEF3A28BC5C7200E660EA /* AppDelegate.swift */; };
|
||||||
CD8EEF3D28BC5C7200E660EA /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8EEF3C28BC5C7200E660EA /* SceneDelegate.swift */; };
|
CD8EEF3D28BC5C7200E660EA /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8EEF3C28BC5C7200E660EA /* SceneDelegate.swift */; };
|
||||||
CD8EEF4228BC5C7200E660EA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CD8EEF4028BC5C7200E660EA /* Main.storyboard */; };
|
CD8EEF4228BC5C7200E660EA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CD8EEF4028BC5C7200E660EA /* Main.storyboard */; };
|
||||||
CD8EEF4428BC5C7300E660EA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD8EEF4328BC5C7300E660EA /* Assets.xcassets */; };
|
CD8EEF4428BC5C7300E660EA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD8EEF4328BC5C7300E660EA /* Assets.xcassets */; };
|
||||||
CD8EEF4728BC5C7300E660EA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CD8EEF4528BC5C7300E660EA /* LaunchScreen.storyboard */; };
|
CD8EEF4728BC5C7300E660EA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CD8EEF4528BC5C7300E660EA /* LaunchScreen.storyboard */; };
|
||||||
CD9C7B1E28CB8972006190CD /* Scenes.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD9C7B1D28CB8972006190CD /* Scenes.swift */; };
|
CD9C7B1E28CB8972006190CD /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD9C7B1D28CB8972006190CD /* Extensions.swift */; };
|
||||||
CDA83DB928C601E60025F0DF /* TableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDA83DB828C601E60025F0DF /* TableHeaderView.swift */; };
|
CDA83DB928C601E60025F0DF /* TableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDA83DB828C601E60025F0DF /* TableHeaderView.swift */; };
|
||||||
CDB6A2A228BC5F4600DEC80D /* ProHUD in Frameworks */ = {isa = PBXBuildFile; productRef = CDB6A2A128BC5F4600DEC80D /* ProHUD */; };
|
CDB6A2A228BC5F4600DEC80D /* ProHUD in Frameworks */ = {isa = PBXBuildFile; productRef = CDB6A2A128BC5F4600DEC80D /* ProHUD */; };
|
||||||
CDB7A1D028C32A7400E034D8 /* AlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB7A1CF28C32A7400E034D8 /* AlertVC.swift */; };
|
CDB7A1D028C32A7400E034D8 /* AlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDB7A1CF28C32A7400E034D8 /* AlertVC.swift */; };
|
||||||
|
@ -36,7 +35,7 @@
|
||||||
CD8EEF4328BC5C7300E660EA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
CD8EEF4328BC5C7300E660EA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
CD8EEF4628BC5C7300E660EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
CD8EEF4628BC5C7300E660EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
CD8EEF4828BC5C7300E660EA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
CD8EEF4828BC5C7300E660EA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
CD9C7B1D28CB8972006190CD /* Scenes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scenes.swift; sourceTree = "<group>"; };
|
CD9C7B1D28CB8972006190CD /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
|
||||||
CDA83DB828C601E60025F0DF /* TableHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableHeaderView.swift; sourceTree = "<group>"; };
|
CDA83DB828C601E60025F0DF /* TableHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableHeaderView.swift; sourceTree = "<group>"; };
|
||||||
CDB6A29F28BC5F0F00DEC80D /* ProHUD */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = ProHUD; path = ..; sourceTree = "<group>"; };
|
CDB6A29F28BC5F0F00DEC80D /* ProHUD */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = ProHUD; path = ..; sourceTree = "<group>"; };
|
||||||
CDB7A1CF28C32A7400E034D8 /* AlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertVC.swift; sourceTree = "<group>"; };
|
CDB7A1CF28C32A7400E034D8 /* AlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertVC.swift; sourceTree = "<group>"; };
|
||||||
|
@ -47,7 +46,6 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
CD6AE8A62A7CC1C70044E53D /* Inspire in Frameworks */,
|
|
||||||
CDB6A2A228BC5F4600DEC80D /* ProHUD in Frameworks */,
|
CDB6A2A228BC5F4600DEC80D /* ProHUD in Frameworks */,
|
||||||
CD6AE8A32A7CC1BA0044E53D /* SnapKit in Frameworks */,
|
CD6AE8A32A7CC1BA0044E53D /* SnapKit in Frameworks */,
|
||||||
);
|
);
|
||||||
|
@ -81,7 +79,7 @@
|
||||||
CD8EEF3C28BC5C7200E660EA /* SceneDelegate.swift */,
|
CD8EEF3C28BC5C7200E660EA /* SceneDelegate.swift */,
|
||||||
CD6537BE28C3311B00A5981B /* ListModel.swift */,
|
CD6537BE28C3311B00A5981B /* ListModel.swift */,
|
||||||
CDA83DB828C601E60025F0DF /* TableHeaderView.swift */,
|
CDA83DB828C601E60025F0DF /* TableHeaderView.swift */,
|
||||||
CD9C7B1D28CB8972006190CD /* Scenes.swift */,
|
CD9C7B1D28CB8972006190CD /* Extensions.swift */,
|
||||||
CD6537C028C35E1C00A5981B /* ListVC.swift */,
|
CD6537C028C35E1C00A5981B /* ListVC.swift */,
|
||||||
CDB7A1CF28C32A7400E034D8 /* AlertVC.swift */,
|
CDB7A1CF28C32A7400E034D8 /* AlertVC.swift */,
|
||||||
CD6537C228C35E6200A5981B /* ToastVC.swift */,
|
CD6537C228C35E6200A5981B /* ToastVC.swift */,
|
||||||
|
@ -128,7 +126,6 @@
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
CDB6A2A128BC5F4600DEC80D /* ProHUD */,
|
CDB6A2A128BC5F4600DEC80D /* ProHUD */,
|
||||||
CD6AE8A22A7CC1BA0044E53D /* SnapKit */,
|
CD6AE8A22A7CC1BA0044E53D /* SnapKit */,
|
||||||
CD6AE8A52A7CC1C70044E53D /* Inspire */,
|
|
||||||
);
|
);
|
||||||
productName = PHDemo;
|
productName = PHDemo;
|
||||||
productReference = CD8EEF3728BC5C7200E660EA /* PHDemo.app */;
|
productReference = CD8EEF3728BC5C7200E660EA /* PHDemo.app */;
|
||||||
|
@ -160,7 +157,6 @@
|
||||||
mainGroup = CD8EEF2E28BC5C7200E660EA;
|
mainGroup = CD8EEF2E28BC5C7200E660EA;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
CD6AE8A12A7CC1BA0044E53D /* XCLocalSwiftPackageReference "../../SnapKit" */,
|
CD6AE8A12A7CC1BA0044E53D /* XCLocalSwiftPackageReference "../../SnapKit" */,
|
||||||
CD6AE8A42A7CC1C70044E53D /* XCLocalSwiftPackageReference "../../Inspire" */,
|
|
||||||
);
|
);
|
||||||
productRefGroup = CD8EEF3828BC5C7200E660EA /* Products */;
|
productRefGroup = CD8EEF3828BC5C7200E660EA /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
@ -196,7 +192,7 @@
|
||||||
CD6537C128C35E1C00A5981B /* ListVC.swift in Sources */,
|
CD6537C128C35E1C00A5981B /* ListVC.swift in Sources */,
|
||||||
CD8EEF3B28BC5C7200E660EA /* AppDelegate.swift in Sources */,
|
CD8EEF3B28BC5C7200E660EA /* AppDelegate.swift in Sources */,
|
||||||
CD8EEF3D28BC5C7200E660EA /* SceneDelegate.swift in Sources */,
|
CD8EEF3D28BC5C7200E660EA /* SceneDelegate.swift in Sources */,
|
||||||
CD9C7B1E28CB8972006190CD /* Scenes.swift in Sources */,
|
CD9C7B1E28CB8972006190CD /* Extensions.swift in Sources */,
|
||||||
CD6537BF28C3311B00A5981B /* ListModel.swift in Sources */,
|
CD6537BF28C3311B00A5981B /* ListModel.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -423,10 +419,6 @@
|
||||||
isa = XCLocalSwiftPackageReference;
|
isa = XCLocalSwiftPackageReference;
|
||||||
relativePath = ../../SnapKit;
|
relativePath = ../../SnapKit;
|
||||||
};
|
};
|
||||||
CD6AE8A42A7CC1C70044E53D /* XCLocalSwiftPackageReference "../../Inspire" */ = {
|
|
||||||
isa = XCLocalSwiftPackageReference;
|
|
||||||
relativePath = ../../Inspire;
|
|
||||||
};
|
|
||||||
/* End XCLocalSwiftPackageReference section */
|
/* End XCLocalSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
@ -434,10 +426,6 @@
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = SnapKit;
|
productName = SnapKit;
|
||||||
};
|
};
|
||||||
CD6AE8A52A7CC1C70044E53D /* Inspire */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
productName = Inspire;
|
|
||||||
};
|
|
||||||
CDB6A2A128BC5F4600DEC80D /* ProHUD */ = {
|
CDB6A2A128BC5F4600DEC80D /* ProHUD */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = ProHUD;
|
productName = ProHUD;
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
//
|
||||||
|
// File.swift
|
||||||
|
// PHDemo
|
||||||
|
//
|
||||||
|
// Created by xaoxuu on 2022/9/9.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import ProHUD
|
||||||
|
|
||||||
|
public extension ViewModel {
|
||||||
|
// static var plain: ViewModel {
|
||||||
|
// ViewModel()
|
||||||
|
// }
|
||||||
|
// static var note: ViewModel {
|
||||||
|
// ViewModel(icon: UIImage(named: "prohud.note"))
|
||||||
|
// }
|
||||||
|
// MARK: note
|
||||||
|
static var note: ViewModel {
|
||||||
|
.init(icon: UIImage(named: "demo.note"))
|
||||||
|
}
|
||||||
|
static func note(_ seconds: TimeInterval) -> ViewModel {
|
||||||
|
.init(icon: UIImage(named: "demo.note"), duration: seconds)
|
||||||
|
}
|
||||||
|
static var msg: ViewModel {
|
||||||
|
ViewModel(icon: UIImage(named: "demo.message"))
|
||||||
|
}
|
||||||
|
static func msg(_ seconds: TimeInterval) -> ViewModel {
|
||||||
|
ViewModel(icon: UIImage(named: "demo.message"), duration: seconds)
|
||||||
|
}
|
||||||
|
static var delete: ViewModel {
|
||||||
|
ViewModel(icon: UIImage(named: "demo.trash"))
|
||||||
|
}
|
||||||
|
// MARK: confirm
|
||||||
|
static var confirm: ViewModel {
|
||||||
|
.init(icon: UIImage(named: "demo.questionmark"))
|
||||||
|
}
|
||||||
|
static func confirm(_ seconds: TimeInterval) -> ViewModel {
|
||||||
|
.init(icon: UIImage(named: "demo.questionmark"), duration: seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
// static func loading(_ seconds: TimeInterval) -> ViewModel {
|
||||||
|
// let obj = ViewModel(icon: UIImage(named: "prohud.rainbow.circle"), duration: seconds)
|
||||||
|
// obj.rotation = .init(repeatCount: .infinity)
|
||||||
|
// return obj
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension CALayer {
|
||||||
|
var cornerRadiusWithContinuous: CGFloat {
|
||||||
|
set {
|
||||||
|
cornerRadius = newValue
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
cornerCurve = .continuous
|
||||||
|
} else {
|
||||||
|
// Fallback on earlier versions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get { cornerRadius }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension UIColor {
|
||||||
|
|
||||||
|
/// 根据hex字符串创建颜色
|
||||||
|
///
|
||||||
|
/// - Parameter hex: hex字符串
|
||||||
|
convenience init(_ hex: String) {
|
||||||
|
func filter(hex: String) -> NSString{
|
||||||
|
let set = NSCharacterSet.whitespacesAndNewlines
|
||||||
|
var str = hex.trimmingCharacters(in: set).lowercased()
|
||||||
|
if str.hasPrefix("#") {
|
||||||
|
str = String(str.suffix(str.count-1))
|
||||||
|
} else if str.hasPrefix("0x") {
|
||||||
|
str = String(str.suffix(str.count-2))
|
||||||
|
}
|
||||||
|
return NSString(string: str)
|
||||||
|
}
|
||||||
|
let hex = filter(hex: hex)
|
||||||
|
let length = hex.length
|
||||||
|
guard length == 3 || length == 4 || length == 6 || length == 8 else {
|
||||||
|
print("无效的hex")
|
||||||
|
self.init("000")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func floatValue(from hex: String) -> CGFloat {
|
||||||
|
var result = Float(0)
|
||||||
|
Scanner(string: "0x"+hex).scanHexFloat(&result)
|
||||||
|
var maxStr = "0xf"
|
||||||
|
if length > 5 {
|
||||||
|
maxStr = "0xff"
|
||||||
|
}
|
||||||
|
var max = Float(0)
|
||||||
|
Scanner(string: maxStr).scanHexFloat(&max)
|
||||||
|
result = result / max
|
||||||
|
return CGFloat(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func substring(of hex: NSString, loc: Int) -> String {
|
||||||
|
if length == 3 || length == 4 {
|
||||||
|
return hex.substring(with: NSRange.init(location: loc, length: 1))
|
||||||
|
} else if length == 6 || length == 8 {
|
||||||
|
return hex.substring(with: NSRange.init(location: 2*loc, length: 2))
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = floatValue(from: substring(of: hex, loc: 0))
|
||||||
|
let g = floatValue(from: substring(of: hex, loc: 1))
|
||||||
|
let b = floatValue(from: substring(of: hex, loc: 2))
|
||||||
|
var a = CGFloat(1)
|
||||||
|
if length == 4 || length == 8 {
|
||||||
|
a = floatValue(from: substring(of: hex, loc: 3))
|
||||||
|
}
|
||||||
|
self.init(red: r, green: g, blue: b, alpha: a)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
//
|
|
||||||
// File.swift
|
|
||||||
// PHDemo
|
|
||||||
//
|
|
||||||
// Created by xaoxuu on 2022/9/9.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import ProHUD
|
|
||||||
|
|
||||||
public extension ViewModel {
|
|
||||||
// static var plain: ViewModel {
|
|
||||||
// ViewModel()
|
|
||||||
// }
|
|
||||||
// static var note: ViewModel {
|
|
||||||
// ViewModel(icon: UIImage(named: "prohud.note"))
|
|
||||||
// }
|
|
||||||
// MARK: note
|
|
||||||
static var note: ViewModel {
|
|
||||||
.init(icon: UIImage(named: "demo.note"))
|
|
||||||
}
|
|
||||||
static func note(_ seconds: TimeInterval) -> ViewModel {
|
|
||||||
.init(icon: UIImage(named: "demo.note"), duration: seconds)
|
|
||||||
}
|
|
||||||
static var msg: ViewModel {
|
|
||||||
ViewModel(icon: UIImage(named: "demo.message"))
|
|
||||||
}
|
|
||||||
static func msg(_ seconds: TimeInterval) -> ViewModel {
|
|
||||||
ViewModel(icon: UIImage(named: "demo.message"), duration: seconds)
|
|
||||||
}
|
|
||||||
static var delete: ViewModel {
|
|
||||||
ViewModel(icon: UIImage(named: "demo.trash"))
|
|
||||||
}
|
|
||||||
// MARK: confirm
|
|
||||||
static var confirm: ViewModel {
|
|
||||||
.init(icon: UIImage(named: "demo.questionmark"))
|
|
||||||
}
|
|
||||||
static func confirm(_ seconds: TimeInterval) -> ViewModel {
|
|
||||||
.init(icon: UIImage(named: "demo.questionmark"), duration: seconds)
|
|
||||||
}
|
|
||||||
|
|
||||||
// static func loading(_ seconds: TimeInterval) -> ViewModel {
|
|
||||||
// let obj = ViewModel(icon: UIImage(named: "prohud.rainbow.circle"), duration: seconds)
|
|
||||||
// obj.rotation = .init(repeatCount: .infinity)
|
|
||||||
// return obj
|
|
||||||
// }
|
|
||||||
}
|
|
|
@ -295,7 +295,7 @@ class ToastVC: ListVC {
|
||||||
}
|
}
|
||||||
toast.add(action: "纯色") { toast in
|
toast.add(action: "纯色") { toast in
|
||||||
toast.contentMaskView.effect = .none
|
toast.contentMaskView.effect = .none
|
||||||
toast.contentMaskView.backgroundColor = .red.lighten()
|
toast.contentMaskView.backgroundColor = .red
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,11 @@ let package = Package(
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(url: "https://github.com/SnapKit/SnapKit.git", "5.0.0" ..< "6.0.0"),
|
.package(url: "https://github.com/SnapKit/SnapKit.git", "5.0.0" ..< "6.0.0"),
|
||||||
.package(url: "https://github.com/xaoxuu/Inspire.git", "3.0.0" ..< "4.0.0"),
|
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
name: "ProHUD",
|
name: "ProHUD",
|
||||||
dependencies: ["SnapKit", "Inspire"],
|
dependencies: ["SnapKit"],
|
||||||
resources: [.process("Resources/ProHUD.xcassets")]
|
resources: [.process("Resources/ProHUD.xcassets")]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -21,13 +21,13 @@ class AlertWindow: Window {
|
||||||
}
|
}
|
||||||
let w: AlertWindow
|
let w: AlertWindow
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
if let scene = config.windowScene ?? UIWindowScene.mainWindowScene {
|
if let scene = AppContext.windowScene {
|
||||||
w = .init(windowScene: scene)
|
w = .init(windowScene: scene)
|
||||||
} else {
|
} else {
|
||||||
w = .init(frame: UIScreen.main.bounds)
|
w = .init(frame: AppContext.appBounds)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
w = .init(frame: UIScreen.main.bounds)
|
w = .init(frame: AppContext.appBounds)
|
||||||
}
|
}
|
||||||
AlertWindow.current = w
|
AlertWindow.current = w
|
||||||
// 比原生alert层级低一点
|
// 比原生alert层级低一点
|
||||||
|
|
|
@ -11,24 +11,6 @@ public class Configuration: NSObject {
|
||||||
|
|
||||||
/// 是否允许log输出
|
/// 是否允许log输出
|
||||||
public static var enablePrint = true
|
public static var enablePrint = true
|
||||||
|
|
||||||
/// 根控制器,默认可以自动获取,如果获取失败请主动设置
|
|
||||||
public var rootViewController: UIViewController?
|
|
||||||
|
|
||||||
/// iOS13必须设置此值,默认可以自动获取,如果获取失败请主动设置
|
|
||||||
@available(iOS 13.0, *)
|
|
||||||
private static var sharedWindowScene: UIWindowScene?
|
|
||||||
|
|
||||||
/// iOS13必须设置此值,默认可以自动获取,如果获取失败请主动设置
|
|
||||||
@available(iOS 13.0, *)
|
|
||||||
public var windowScene: UIWindowScene? {
|
|
||||||
set {
|
|
||||||
Self.sharedWindowScene = newValue
|
|
||||||
}
|
|
||||||
get {
|
|
||||||
return Self.sharedWindowScene
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public lazy var dynamicBackgroundColor: UIColor = {
|
public lazy var dynamicBackgroundColor: UIColor = {
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
|
@ -78,12 +60,12 @@ public class Configuration: NSObject {
|
||||||
/// 最大宽度(用于优化横屏或者iPad显示)
|
/// 最大宽度(用于优化横屏或者iPad显示)
|
||||||
public var cardMaxWidth: CGFloat?
|
public var cardMaxWidth: CGFloat?
|
||||||
var cardMaxWidthByDefault: CGFloat {
|
var cardMaxWidthByDefault: CGFloat {
|
||||||
cardMaxWidth ?? .minimum(UIScreen.main.bounds.width * 0.72, 400)
|
cardMaxWidth ?? .minimum(AppContext.appBounds.width * 0.72, 400)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var cardMaxHeight: CGFloat?
|
public var cardMaxHeight: CGFloat?
|
||||||
var cardMaxHeightByDefault: CGFloat {
|
var cardMaxHeightByDefault: CGFloat {
|
||||||
cardMaxHeight ?? (UIScreen.main.bounds.height - 100)
|
cardMaxHeight ?? (AppContext.appBounds.height - 100)
|
||||||
}
|
}
|
||||||
/// 最小宽度
|
/// 最小宽度
|
||||||
public var cardMinWidth = CGFloat(32)
|
public var cardMinWidth = CGFloat(32)
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
//
|
||||||
|
// AppContext.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by xaoxuu on 2023/8/5.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public struct AppContext {
|
||||||
|
|
||||||
|
@available(iOS 13.0, *)
|
||||||
|
private static var storedAppWindowScene: UIWindowScene?
|
||||||
|
|
||||||
|
private static var storedAppWindow: UIWindow?
|
||||||
|
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension AppContext {
|
||||||
|
|
||||||
|
@available(iOS 13.0, *)
|
||||||
|
static var windowScene: UIWindowScene? {
|
||||||
|
set { storedAppWindowScene = newValue }
|
||||||
|
get {
|
||||||
|
if let ws = storedAppWindowScene {
|
||||||
|
return ws
|
||||||
|
} else {
|
||||||
|
return UIApplication.shared.connectedScenes.first(where: { scene in
|
||||||
|
guard let ws = scene as? UIWindowScene else { return false }
|
||||||
|
return ws.activationState == .foregroundActive
|
||||||
|
}) as? UIWindowScene
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 所有的窗口
|
||||||
|
static var windows: [UIWindow] {
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
return windowScene?.windows ?? UIApplication.shared.windows
|
||||||
|
} else {
|
||||||
|
return UIApplication.shared.windows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 可见的窗口
|
||||||
|
static var visibleWindows: [UIWindow] {
|
||||||
|
windows.filter { $0.isHidden == false }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// App主程序窗口
|
||||||
|
static var appWindow: UIWindow? {
|
||||||
|
get {
|
||||||
|
if let w = storedAppWindow {
|
||||||
|
return w
|
||||||
|
} else {
|
||||||
|
return visibleWindows.filter { window in
|
||||||
|
return "\(type(of: window))" == "UIWindow" && window.windowLevel == .normal
|
||||||
|
}.first
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set { storedAppWindow = newValue }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// App主程序窗口的尺寸
|
||||||
|
static var appBounds: CGRect {
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
return appWindow?.bounds ?? UIScreen.main.bounds
|
||||||
|
} else {
|
||||||
|
return UIScreen.main.bounds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// App主程序窗口的安全边距
|
||||||
|
static var safeAreaInsets: UIEdgeInsets { appWindow?.safeAreaInsets ?? .zero }
|
||||||
|
|
||||||
|
}
|
|
@ -6,11 +6,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Inspire
|
|
||||||
|
|
||||||
var screenSafeAreaInsets: UIEdgeInsets {
|
|
||||||
Inspire.shared.screen.safeAreaInsets
|
|
||||||
}
|
|
||||||
|
|
||||||
extension UIImage {
|
extension UIImage {
|
||||||
public convenience init?(inProHUD named: String) {
|
public convenience init?(inProHUD named: String) {
|
||||||
|
@ -23,8 +18,11 @@ extension UIImage {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// 是否是手机竖屏模式
|
/// 是否是竖屏(紧凑布局)模式
|
||||||
internal var isPortrait: Bool {
|
internal var isPortrait: Bool {
|
||||||
|
if AppContext.appBounds.width < 450 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone {
|
if UIDevice.current.userInterfaceIdiom == .phone {
|
||||||
if UIApplication.shared.statusBarOrientation.isPortrait {
|
if UIApplication.shared.statusBarOrientation.isPortrait {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -52,15 +52,3 @@ class Window: UIWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
|
||||||
extension UIWindowScene {
|
|
||||||
|
|
||||||
static var mainWindowScene: UIWindowScene? {
|
|
||||||
UIApplication.shared.connectedScenes.first(where: { scene in
|
|
||||||
guard let ws = scene as? UIWindowScene else { return false }
|
|
||||||
return ws.activationState == .foregroundActive
|
|
||||||
}) as? UIWindowScene
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public extension Sheet {
|
||||||
|
|
||||||
override var cardMaxWidthByDefault: CGFloat { cardMaxWidth ?? 500 }
|
override var cardMaxWidthByDefault: CGFloat { cardMaxWidth ?? 500 }
|
||||||
|
|
||||||
override var cardMaxHeightByDefault: CGFloat { cardMaxHeight ?? (UIScreen.main.bounds.height - 50) }
|
override var cardMaxHeightByDefault: CGFloat { cardMaxHeight ?? (AppContext.appBounds.height - 50) }
|
||||||
|
|
||||||
override var animateDurationForBuildInByDefault: CGFloat {
|
override var animateDurationForBuildInByDefault: CGFloat {
|
||||||
animateDurationForBuildIn ?? 0.5
|
animateDurationForBuildIn ?? 0.5
|
||||||
|
|
|
@ -44,7 +44,7 @@ extension Sheet: DefaultLayout {
|
||||||
loadContentMaskViewIfNeeded()
|
loadContentMaskViewIfNeeded()
|
||||||
// layout
|
// layout
|
||||||
let maxWidth = config.cardMaxWidthByDefault
|
let maxWidth = config.cardMaxWidthByDefault
|
||||||
var width = UIScreen.main.bounds.width - config.screenEdgeInset * 2
|
var width = AppContext.appBounds.width - config.screenEdgeInset * 2
|
||||||
if width > maxWidth {
|
if width > maxWidth {
|
||||||
// landscape iPhone or iPad
|
// landscape iPhone or iPad
|
||||||
width = maxWidth
|
width = maxWidth
|
||||||
|
@ -54,14 +54,15 @@ extension Sheet: DefaultLayout {
|
||||||
make.edges.equalToSuperview()
|
make.edges.equalToSuperview()
|
||||||
} else {
|
} else {
|
||||||
make.centerX.equalToSuperview()
|
make.centerX.equalToSuperview()
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone {
|
if UIDevice.current.userInterfaceIdiom == .pad && width >= maxWidth {
|
||||||
if width < maxWidth {
|
// iPad且窗口宽度较宽时居中弹出
|
||||||
|
make.centerY.equalToSuperview()
|
||||||
|
} else {
|
||||||
|
if isPortrait {
|
||||||
make.bottom.equalToSuperview().inset(config.screenEdgeInset)
|
make.bottom.equalToSuperview().inset(config.screenEdgeInset)
|
||||||
} else {
|
} else {
|
||||||
make.bottom.equalToSuperview().inset(screenSafeAreaInsets.bottom)
|
make.bottom.equalToSuperview().inset(AppContext.safeAreaInsets.bottom)
|
||||||
}
|
}
|
||||||
} else if UIDevice.current.userInterfaceIdiom == .pad {
|
|
||||||
make.centerY.equalToSuperview()
|
|
||||||
}
|
}
|
||||||
make.width.equalTo(width)
|
make.width.equalTo(width)
|
||||||
make.height.greaterThanOrEqualTo(config.cardCornerRadiusByDefault * 2)
|
make.height.greaterThanOrEqualTo(config.cardCornerRadiusByDefault * 2)
|
||||||
|
@ -80,7 +81,7 @@ extension Sheet: DefaultLayout {
|
||||||
contentStack.snp.remakeConstraints { make in
|
contentStack.snp.remakeConstraints { make in
|
||||||
let safeArea: UIEdgeInsets
|
let safeArea: UIEdgeInsets
|
||||||
if config.isFullScreen {
|
if config.isFullScreen {
|
||||||
safeArea = screenSafeAreaInsets
|
safeArea = AppContext.safeAreaInsets
|
||||||
} else {
|
} else {
|
||||||
safeArea = .zero
|
safeArea = .zero
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,13 @@ class SheetWindow: Window {
|
||||||
init(sheet: Sheet) {
|
init(sheet: Sheet) {
|
||||||
self.sheet = sheet
|
self.sheet = sheet
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
if let scene = sheet.config.windowScene ?? UIWindowScene.mainWindowScene {
|
if let scene = AppContext.windowScene {
|
||||||
super.init(windowScene: scene)
|
super.init(windowScene: scene)
|
||||||
} else {
|
} else {
|
||||||
super.init(frame: UIScreen.main.bounds)
|
super.init(frame: AppContext.appBounds)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
super.init(frame: UIScreen.main.bounds)
|
super.init(frame: AppContext.appBounds)
|
||||||
}
|
}
|
||||||
sheet.window = self
|
sheet.window = self
|
||||||
windowLevel = .init(rawValue: UIWindow.Level.alert.rawValue - 2)
|
windowLevel = .init(rawValue: UIWindow.Level.alert.rawValue - 2)
|
||||||
|
|
|
@ -34,7 +34,7 @@ public extension Toast {
|
||||||
}
|
}
|
||||||
|
|
||||||
override var cardMaxHeightByDefault: CGFloat {
|
override var cardMaxHeightByDefault: CGFloat {
|
||||||
cardMaxHeight ?? (UIScreen.main.bounds.height / 3)
|
cardMaxHeight ?? (AppContext.appBounds.height / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
override var animateDurationForBuildInByDefault: CGFloat {
|
override var animateDurationForBuildInByDefault: CGFloat {
|
||||||
|
|
|
@ -19,7 +19,7 @@ class ToastWindow: Window {
|
||||||
self.toast = toast
|
self.toast = toast
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
windowScene = toast.config.windowScene ?? UIWindowScene.mainWindowScene
|
windowScene = AppContext.windowScene
|
||||||
}
|
}
|
||||||
toast.window = self
|
toast.window = self
|
||||||
windowLevel = .init(rawValue: UIWindow.Level.alert.rawValue + 1000)
|
windowLevel = .init(rawValue: UIWindow.Level.alert.rawValue + 1000)
|
||||||
|
@ -49,8 +49,9 @@ class ToastWindow: Window {
|
||||||
isNew = true
|
isNew = true
|
||||||
}
|
}
|
||||||
let config = toast.config
|
let config = toast.config
|
||||||
|
|
||||||
// frame
|
// frame
|
||||||
let width = CGFloat.minimum(UIScreen.main.bounds.width - config.cardEdgeInsets.left - config.cardEdgeInsets.right, config.cardMaxWidthByDefault)
|
let width = CGFloat.minimum(AppContext.appBounds.width - config.cardEdgeInsets.left - config.cardEdgeInsets.right, config.cardMaxWidthByDefault)
|
||||||
toast.view.frame.size = CGSize(width: width, height: config.cardMaxHeightByDefault)
|
toast.view.frame.size = CGSize(width: width, height: config.cardMaxHeightByDefault)
|
||||||
toast.titleLabel.sizeToFit()
|
toast.titleLabel.sizeToFit()
|
||||||
toast.bodyLabel.sizeToFit()
|
toast.bodyLabel.sizeToFit()
|
||||||
|
@ -59,7 +60,7 @@ class ToastWindow: Window {
|
||||||
let height = toast.calcHeight()
|
let height = toast.calcHeight()
|
||||||
toast.view.frame.size = CGSize(width: width, height: height)
|
toast.view.frame.size = CGSize(width: width, height: height)
|
||||||
// 应用到frame
|
// 应用到frame
|
||||||
window.frame = CGRect(x: (UIScreen.main.bounds.width - width) / 2, y: 0, width: width, height: height)
|
window.frame = CGRect(x: (AppContext.appBounds.width - width) / 2, y: 0, width: width, height: height)
|
||||||
window.rootViewController = toast // 此时toast.view.frame.size会自动更新为window.frame.size
|
window.rootViewController = toast // 此时toast.view.frame.size会自动更新为window.frame.size
|
||||||
if windows.contains(window) == false {
|
if windows.contains(window) == false {
|
||||||
windows.append(window)
|
windows.append(window)
|
||||||
|
@ -108,16 +109,11 @@ fileprivate var updateToastsLayoutWorkItem: DispatchWorkItem?
|
||||||
fileprivate extension ToastWindow {
|
fileprivate extension ToastWindow {
|
||||||
|
|
||||||
static func setToastWindowsLayout() {
|
static func setToastWindowsLayout() {
|
||||||
let top = screenSafeAreaInsets.top
|
|
||||||
for (i, window) in windows.enumerated() {
|
for (i, window) in windows.enumerated() {
|
||||||
let config = window.toast.config
|
let config = window.toast.config
|
||||||
var y = window.frame.origin.y
|
var y = window.frame.origin.y
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
if isPortrait {
|
y = max(AppContext.appWindow?.layoutMargins.top ?? config.margin, config.margin)
|
||||||
y = top
|
|
||||||
} else {
|
|
||||||
y = config.margin
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if i - 1 < windows.count && i > 0 {
|
if i - 1 < windows.count && i > 0 {
|
||||||
y = config.margin + windows[i-1].frame.maxY
|
y = config.margin + windows[i-1].frame.maxY
|
||||||
|
|
Loading…
Reference in New Issue