diff --git a/Example-Old/Example/TestAlertVC.swift b/Example-Old/Example/TestAlertVC.swift index 69be621..68ce9a5 100644 --- a/Example-Old/Example/TestAlertVC.swift +++ b/Example-Old/Example/TestAlertVC.swift @@ -25,7 +25,8 @@ class TestAlertVC: BaseListVC { "极端场景:短时间内调用了多次同一个弹窗", "极端场景:多个不同的弹窗重叠", "测试较长的标题和内容", - "测试特别长的标题和内容"] + "测试特别长的标题和内容", + "场景:正在同步(更新进度)"] } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { @@ -188,6 +189,38 @@ class TestAlertVC: BaseListVC { vm.add(action: .default, title: "我知道了", handler: nil) } } + } else if row == 8 { + Alert.push("progress") { (a) in + a.update { (vm) in + vm.scene = .loading + vm.title = "正在同步" + vm.message = "请稍等片刻" + } + a.startRotate() + a.update(progress: 0) + let s = DispatchSemaphore(value: 1) + DispatchQueue.global().async { + for i in 0 ... 5 { + s.wait() + DispatchQueue.main.async { + Alert.find("progress", last: { (a) in + a.update(progress: CGFloat(i)/5) + print("\(CGFloat(i)/5)") + if i == 5 { + a.update { (vm) in + vm.scene = .success + vm.title = "同步成功" + vm.message = nil + } + } + }) + DispatchQueue.main.asyncAfter(deadline: .now()+1) { + s.signal() + } + } + } + } + } } } diff --git a/Example-Old/Example/TestToastVC.swift b/Example-Old/Example/TestToastVC.swift index 123e0bd..87d646f 100644 --- a/Example-Old/Example/TestToastVC.swift +++ b/Example-Old/Example/TestToastVC.swift @@ -19,6 +19,7 @@ class TestToastVC: BaseListVC { override var titles: [String] { return ["场景:正在同步", + "场景:正在同步(更新进度)", "场景:同步成功", "场景:同步失败", "场景:设备电量过低", @@ -43,12 +44,44 @@ class TestToastVC: BaseListVC { }.startRotate() simulateSync() } else if row == 1 { + Toast.push("progress") { (t) in + t.update { (vm) in + vm.scene = .loading + vm.title = "正在同步" + vm.message = "请稍等片刻" + } + t.startRotate() + t.update(progress: 0) + let s = DispatchSemaphore(value: 1) + DispatchQueue.global().async { + for i in 0 ... 5 { + s.wait() + DispatchQueue.main.async { + Toast.find("progress", last: { (t) in + t.update(progress: CGFloat(i)/5) + print("\(CGFloat(i)/5)") + if i == 5 { + t.update { (vm) in + vm.scene = .success + vm.title = "同步成功" + vm.message = "xxx" + } + } + }) + DispatchQueue.main.asyncAfter(deadline: .now()+1) { + s.signal() + } + } + } + } + } + } else if row == 2 { let t = Toast.push(scene: .success, title: "同步成功", message: "点击查看详情") t.didTapped { [weak self, weak t] in self?.presentEmptyVC(title: "详情") t?.pop() } - } else if row == 2 { + } else if row == 3 { Toast.push(scene: .error, title: "同步失败", message: "请稍后重试。点击查看详情") { (vc) in vc.update { (vm) in vm.duration = 0 @@ -58,10 +91,10 @@ class TestToastVC: BaseListVC { vc?.pop() } } - } else if row == 3 { + } else if row == 4 { Toast.push(scene: .warning, title: "设备电量过低", message: "请及时对设备进行充电,以免影响使用。") - } else if row == 4 { + } else if row == 5 { Toast.push(scene: .default, title: "传入指定图标测试", message: "这是消息内容") { (vc) in vc.update { (vm) in if #available(iOS 13.0, *) { @@ -72,14 +105,14 @@ class TestToastVC: BaseListVC { } } } - } else if row == 5 { + } else if row == 6 { Toast.push(scene: .default, title: "禁止手势移除", message: "这条消息无法通过向上滑动移出屏幕。5秒后自动消失,每次拖拽都会刷新倒计时。") { (vc) in vc.isRemovable = false vc.update { (vm) in vm.duration = 5 } } - } else if row == 6 { + } else if row == 7 { Toast.push(scene: .message, title: "好友邀请", message: "你收到一条好友邀请,点击查看详情。", duration: 10) { (vc) in vc.identifier = "xxx" vc.didTapped { [weak vc] in @@ -97,7 +130,7 @@ class TestToastVC: BaseListVC { } } } - } else if row == 7 { + } else if row == 8 { if let t = Toast.find("aaa").last { t.pulse() t.update() { (vm) in @@ -112,7 +145,7 @@ class TestToastVC: BaseListVC { } } } - } else if row == 8 { + } else if row == 9 { Toast.push("aaa") { (t) in t.update { (vm) in vm.scene = .success @@ -121,7 +154,7 @@ class TestToastVC: BaseListVC { } t.pulse() } - } else if row == 9 { + } else if row == 10 { Toast.push() { (a) in a.update { (vm) in vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" @@ -129,7 +162,7 @@ class TestToastVC: BaseListVC { } } - } else if row == 10 { + } else if row == 11 { Toast.push() { (a) in a.update { (vm) in vm.title = "正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过正在同步看到了你撒地方快乐撒的肌肤轮廓啊就是;来的跨省的人格人格离开那地方离开过" @@ -137,7 +170,7 @@ class TestToastVC: BaseListVC { } } - } else if row == 11 { + } else if row == 12 { Toast.push() { (a) in a.update { (vm) in vm.scene = .warning @@ -145,7 +178,7 @@ class TestToastVC: BaseListVC { } } - } else if row == 12 { + } else if row == 13 { Toast.push() { (a) in a.update { (vm) in vm.scene = .warning @@ -153,7 +186,7 @@ class TestToastVC: BaseListVC { } } - } else if row == 13 { + } else if row == 14 { Toast.push(scene: .privacy, title: "正在授权", message: "请稍等片刻") { (t) in t.identifier = "loading" diff --git a/Example-Xcode11/Example-Xcode11.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example-Xcode11/Example-Xcode11.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 7e9a833..ec9dc04 100644 --- a/Example-Xcode11/Example-Xcode11.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example-Xcode11/Example-Xcode11.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,7 +6,7 @@ "repositoryURL": "https://github.com/xaoxuu/Inspire", "state": { "branch": "master", - "revision": "cad0c64e6995a06ee3bf3ed7c632ad27c1b8ffb1", + "revision": "43b6a9b7ebcd9f628590eac56cd88a85380dee21", "version": null } }, @@ -15,7 +15,7 @@ "repositoryURL": "https://github.com/xaoxuu/ProHUD", "state": { "branch": "master", - "revision": "d32d6f2dbec8d9464ead83be619d5c21fdb2a464", + "revision": "58d752efc0ad1a2a49a46bc4106e318afe7a9f25", "version": null } }, diff --git a/Source/Alert/AlertConfig.swift b/Source/Alert/AlertConfig.swift index fc507f1..9d04aff 100644 --- a/Source/Alert/AlertConfig.swift +++ b/Source/Alert/AlertConfig.swift @@ -129,6 +129,7 @@ fileprivate var privUpdateImage: (ProHUD.Alert) -> Void = { vc.imageView.layer.removeAllAnimations() vc.animateLayer = nil vc.animation = nil + vc.progressView?.removeFromSuperview() } }() diff --git a/Source/HUDController.swift b/Source/HUDController.swift index b6a0609..fdea8b8 100644 --- a/Source/HUDController.swift +++ b/Source/HUDController.swift @@ -19,9 +19,11 @@ public class HUDController: UIViewController { internal var didDisappearCallback: (() -> Void)? /// 执行动画的图层 - var animateLayer: CALayer? + internal var animateLayer: CALayer? internal var animation: CAAnimation? + internal var progressView: ProHUD.ProgressView? + /// 按钮事件 internal var buttonEvents = [UIButton:() -> Void]() @@ -96,7 +98,28 @@ internal extension HUDController { public protocol LoadingAnimationView: HUDController { var imageView: UIImageView { get } } - +public extension LoadingAnimationView { + + /// 更新进度(如果需要显示进度,需要先调用一次 updateProgress(0) 来初始化) + /// - Parameter progress: 进度(0~1) + func update(progress: CGFloat) { + if let spv = imageView.superview { + if progressView == nil { + let v = ProHUD.ProgressView() + spv.addSubview(v) + v.snp.makeConstraints { (mk) in + mk.center.equalTo(imageView) + mk.width.height.equalTo(28) + } + progressView = v + } + if let v = progressView { + v.updateProgress(progress: progress) + } + } + + } +} /// 旋转动画 public protocol LoadingRotateAnimation: LoadingAnimationView {} public extension LoadingRotateAnimation { diff --git a/Source/HUDView.swift b/Source/HUDView.swift index 9c686e3..e9f488e 100644 --- a/Source/HUDView.swift +++ b/Source/HUDView.swift @@ -38,6 +38,52 @@ public extension ProHUD { case counterclockwise = -1 } + + /// 进度指示器 + class ProgressView: UIView { + + var progressLayer = CAShapeLayer() + + override init(frame: CGRect) { + // 容器宽度 + let maxSize = CGFloat(28) + super.init(frame: .init(x: 0, y: 0, width: maxSize, height: maxSize)) + layer.cornerRadius = maxSize / 2 + layer.masksToBounds = true + // 进度圆半径 + let radius = maxSize / 2 - 4 + backgroundColor = .white + + let path = UIBezierPath(arcCenter: CGPoint(x: 14, y: 14), radius: radius/2, startAngle: -CGFloat.pi*0.5, endAngle: CGFloat.pi * 1.5, clockwise: true) + + progressLayer.fillColor = UIColor.clear.cgColor + progressLayer.path = path.cgPath + + progressLayer.strokeColor = tintColor.cgColor + progressLayer.lineWidth = radius + progressLayer.strokeStart = 0 + progressLayer.strokeEnd = 0 + layer.addSublayer(progressLayer) + + } + + required init(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func updateProgress(progress: CGFloat) { + if progress <= 1 { + // 初始化 + if progressLayer.superlayer == nil { + progressLayer.strokeEnd = 0 + layer.addSublayer(progressLayer) + } + progressLayer.strokeEnd = progress + } + } + + } + } // MARK: - internal diff --git a/Source/Toast/ToastConfig.swift b/Source/Toast/ToastConfig.swift index b882fba..57f8088 100644 --- a/Source/Toast/ToastConfig.swift +++ b/Source/Toast/ToastConfig.swift @@ -116,6 +116,8 @@ fileprivate var privReloadData: (ProHUD.Toast) -> Void = { // 设置持续时间 vc.vm.updateDuration() + vc.progressView?.removeFromSuperview() + } }()