Commit 0b841956 authored by David黄金龙's avatar David黄金龙

文件移动

parent 277f5d93
//
// BsBaseViewController.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/21.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
//import Kingfisher
class YHBaseViewController: UIViewController {
lazy var noDataView:YHNoDataTipView = {
let temp = YHNoDataTipView()
temp.frame = view.bounds
temp.isHidden = true
let tap = UITapGestureRecognizer(target: self, action: #selector(tapNodataViewEvent(tap:)))
temp.addGestureRecognizer(tap)
return temp
}()
override func viewDidLoad() {
super.viewDidLoad()
self.bs_setupLeftButton()
//0
setupNavigationAttributed()
//1、
view.addSubview(noDataView)
view.backgroundColor = .white
}
deinit {
#if DEBUG
print(#function)
#endif
}
}
// MARK: - 私有操作方法
extension YHBaseViewController {
@objc func tapNodataViewEvent(tap: UITapGestureRecognizer) -> Void {
print("do nothing~~~ 子类根据具体情况来实现\(#function)")
}
func openFullScreenBackGes(_ openFlag : Bool) {
if self.navigationController is YHNavigationController {
self.navigationItem.hidesBackButton = !openFlag
}
}
///设置导航条属性
func setupNavigationAttributed(_ color: UIColor? = nil) {
if let color = color {
self.navigationController?.navigationBar.setBackgroundImage(UIImage.from(color: color), for: .default) //设置导航栏背景色
self.navigationController?.navigationBar.barTintColor = color
} else {
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) //设置导航栏背景透明色
self.navigationController?.navigationBar.barTintColor = nil
}
self.navigationController?.navigationBar.shadowImage = UIImage() //隐藏下划线
}
}
//
// CustomNavigationController.swift
// DYZB
//
// Created by 1 on 16/10/14.
// Copyright © 2016年 小码哥. All rights reserved.
//
import UIKit
public protocol BsNavigationControllerDelegate : NSObject {
func canBack() -> Bool
}
class YHNavigationController: UINavigationController {
weak var myDelegate : BsNavigationControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.interactivePopGestureRecognizer?.delegate = self
}
// override func viewWillLayoutSubviews() {
// super.viewWillLayoutSubviews()
// if #available(iOS 14.0, *){
// self.navigationBar.topItem?.backButtonDisplayMode = .minimal
// }
// }
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
// 隐藏要push的控制器的tabbar
if animated == true {
viewController.hidesBottomBarWhenPushed = true
}
super.pushViewController(viewController, animated: animated)
}
}
// MARK: - UIGestureRecognizerDelegate, UINavigationBarDelegate
extension YHNavigationController : UIGestureRecognizerDelegate,UINavigationBarDelegate {
//这个方法是在手势将要激活前调用:返回YES允许右滑手势的激活,返回NO不允许右滑手势的激活
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
print(#function)
if let returnValue = myDelegate?.canBack(){
return returnValue
} else {
#if DEBUG
print(#function)
print("myDelegate == nil 或者其他")
#endif
}
return true
}
public func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
if let returnValue = myDelegate?.canBack(){
return returnValue
}
return true
}
}
//
// BsTabBarViewController.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/12/4.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
import ESTabBarController_swift
class YHTabBarViewController: ESTabBarController {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBar.shadowImage = UIImage()
self.tabBar.backgroundImage = UIImage()
// NotificationCenter.default.addObserver(self, selector: #selector(hideTabBar), name: BsConstant.BsNotification.tabBarHideNotification, object: nil)
//
// NotificationCenter.default.addObserver(self, selector: #selector(showTabBar), name: BsConstant.BsNotification.tabBarShowNotification, object: nil)
}
}
extension YHTabBarViewController {
@objc func hideTabBar() -> Void {
self.tabBar.isHidden = true
}
@objc func showTabBar() -> Void {
self.tabBar.isHidden = false
}
}
This diff is collapsed.
//
// BaseModel.swift
// DouYuUI
//
// Created by davidhuang on 2022/8/15.
// Copyright © 2022 davidhuang. All rights reserved.
//
import UIKit
import HandyJSON
// MARK: - JSon解析模型的基类
class BsBaseModel: HandyJSON {
var data : Any?
var errorCode : Int = -1
var errorMessage : String = ""
var success : Bool = false
// MARK: - 使用 HandyJSON 进行解析
required init() {}
}
//
// ExampleBasicContentView.swift
// ESTabBarControllerExample
//
// Created by lihao on 2017/2/9.
// Copyright © 2018年 Egg Swift. All rights reserved.
//
import UIKit
import ESTabBarController_swift
class YHBasicContentView: ESTabBarItemContentView {
override init(frame: CGRect) {
super.init(frame: frame)
textColor = UIColor.init(white: 175.0 / 255.0, alpha: 1.0)
highlightTextColor = .commonColor100
iconColor = UIColor.init(white: 175.0 / 255.0, alpha: 1.0)
highlightIconColor = .commonColor100
titleLabel.font = UIFont.PFSCR(ofSize: 10)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// ExampleBouncesContentView.swift
// ESTabBarControllerExample
//
// Created by lihao on 2017/2/9.
// Copyright © 2018年 Egg Swift. All rights reserved.
//
import UIKit
class YHBouncesContentView: YHBasicContentView {
public var duration = 0.3
override init(frame: CGRect) {
super.init(frame: frame)
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func selectAnimation(animated: Bool, completion: (() -> ())?) {
self.bounceAnimation()
completion?()
}
override func reselectAnimation(animated: Bool, completion: (() -> ())?) {
self.bounceAnimation()
completion?()
}
func bounceAnimation() {
let impliesAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
impliesAnimation.values = [1.0 ,1.4, 0.9, 1.15, 0.95, 1.02, 1.0]
impliesAnimation.duration = duration * 2
impliesAnimation.calculationMode = CAAnimationCalculationMode.cubic
imageView.layer.add(impliesAnimation, forKey: nil)
}
}
//
// YHNoDataTipView.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/25.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
class YHNoDataTipView: UIView {
public var reloadBlock: (()->())?
private var imageStr: String = "no-order-bkg-icon"
private var title: String = "暂无数据"
private lazy var imageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "no-order-bkg-icon"))
return imageView
}()
private lazy var titleLabel: UILabel = {
let label = UILabel(text: "暂无数据", font: UIFont.PFSCR(ofSize: 14), color: UIColor.commonColor45)
return label
}()
private lazy var descLabel: UILabel = {
let label = UILabel(text: "", font: UIFont.PFSCR(ofSize: 12), color: UIColor.commonColor45)
return label
}()
private lazy var reloadBtn: UIButton = {
let btn = UIButton.bs_button(title: "重新加载", font: UIFont.PFSCM(ofSize: 12), normalColor: UIColor.commonColor100)
btn.layer.cornerRadius = 6
btn.layer.masksToBounds = true
btn.layer.borderWidth = 1
btn.layer.borderColor = UIColor.commonColor10.cgColor
btn.addTarget(self, action: #selector(onReloadData), for: .touchUpInside)
return btn
}()
override init(frame: CGRect) {
super.init(frame: frame)
initView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setup(image: String? = nil, title: String) {
if let image = image {
imageView.image = UIImage(named: image)
self.imageStr = image
}
titleLabel.text = title
self.title = title
}
override var isHidden: Bool {
didSet {
if isHidden == false {
if YHNetworkStatusManager.shared.isNetWorkOK == true {
imageView.image = UIImage(named: self.imageStr)
titleLabel.text = title
descLabel.isHidden = true
reloadBtn.isHidden = true
} else {
imageView.image = UIImage(named: "no_data_network_icon")
titleLabel.text = "网络好像断开了哦"
descLabel.isHidden = false
reloadBtn.isHidden = false
}
}
}
}
}
// MARK: - 提供快速创建的类方法
extension YHNoDataTipView {
private func initView() {
self.addSubview(imageView)
self.addSubview(titleLabel)
self.addSubview(descLabel)
self.addSubview(reloadBtn)
let imageViewTop = 132 / (UIDevice.kScreenW - UIDevice.bs_navigationFullHeight())
imageView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(imageViewTop)
make.centerX.equalToSuperview()
make.width.height.equalTo(165)
}
titleLabel.snp.makeConstraints { make in
make.top.equalTo(imageView.snp.bottom)
make.centerX.equalToSuperview()
}
descLabel.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom).offset(4)
make.centerX.equalToSuperview()
}
reloadBtn.snp.makeConstraints { make in
make.top.equalTo(descLabel.snp.bottom).offset(16)
make.centerX.equalToSuperview()
make.width.equalTo(80)
make.height.equalTo(28)
}
descLabel.isHidden = true
reloadBtn.isHidden = true
}
// class func noDataTipView() -> YHNoDataTipView {
// return YHNoDataTipView()
// //return Bundle.main.loadNibNamed("YHNoDataTipView", owner: nil, options: nil)?.first as! YHNoDataTipView
// }
override func layoutSubviews() {
super.layoutSubviews()
let imageViewTop = (132 + UIDevice.bs_navigationFullHeight()) / UIDevice.kScreenH * self.frame.size.height
imageView.snp.updateConstraints { make in
make.top.equalToSuperview().offset(imageViewTop)
}
}
@objc private func onReloadData() {
reloadBlock?()
}
}
//
// AppDelegate + UIAppearance.swift
// SleepDoctor
//
// Created by DAVIDiOS1 on 2020/12/24.
// Copyright © 2020 sumian. All rights reserved.
//
import UIKit
// MARK: - 设置导航栏样式
extension AppDelegate{
func customAppearance() {
setNavigationBarAppearanceWhenContainedInInstancesOf(containers: [YHNavigationController.self])
setNavigationBarAppearanceWhenContainedInInstancesOf(containers: [YHBaseViewController.self])
}
func setNavigationBarAppearanceWhenContainedInInstancesOf(containers: [UIAppearanceContainer.Type]){
let navigationBarAppearance = UINavigationBar.appearance(whenContainedInInstancesOf: containers)
navigationBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.commonColor100,NSAttributedString.Key.font:UIFont.PFSCM(ofSize: 16)]
navigationBarAppearance.barTintColor = UIColor.yellow
navigationBarAppearance.tintColor = UIColor.commonColor100
navigationBarAppearance.backIndicatorImage = UIImage(named: "back_icon")
navigationBarAppearance.backIndicatorTransitionMaskImage = UIImage(named: "back_icon")
navigationBarAppearance.setBackgroundImage(UIImage.from(color: UIColor.clear),for: .default)
navigationBarAppearance.isOpaque = true
navigationBarAppearance.shadowImage = nil
//隐藏返回文字
if #available(iOS 13, *) {
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset( horizontal: -UIDevice.kScreenW, vertical: 0), for: .default)
}
let barItemAppearance = UIBarButtonItem.appearance(whenContainedInInstancesOf: containers)
barItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.clear,NSAttributedString.Key.font:UIFont.systemFont(ofSize: 14)], for: UIControl.State.normal)
barItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.clear,NSAttributedString.Key.font:UIFont.systemFont(ofSize: 14)], for: UIControl.State.highlighted)
}
}
// MARK: - Pay 支付
extension AppDelegate {
func payCallback(url: URL) {
// //支付宝支付
// if url.host == "safepay" {
// AlipaySDK.defaultService().processOrder(withPaymentResult: url, standbyCallback: { resultDic in
// let status = resultDic?["resultStatus"] as? String ?? ""
// var success: Bool = false
// if status == "9000" {
// success = true
// print("支付宝: 支付成功")
// } else {
// success = false
// print("支付宝: 支付失败")
// }
// NotificationCenter.default.post(name: BsConstant.BsNotification.payResultNotification, object: success)
// })
// }
}
}
//
// BsCacheTool.swift
// BaiSiSMApp
//
// Created by DAVID on 2023/1/4.
// Copyright © 2023 www.sumian.com. All rights reserved.
//
import Foundation
open class BsCacheTool: NSObject {
/// 计算缓存大小
public static var cacheSize: String{
get{
// 路径
let basePath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
let fileManager = FileManager.default
// 遍历出所有缓存文件加起来的大小
func caculateCache() -> CGFloat{
var total: CGFloat = 0
if fileManager.fileExists(atPath: basePath!){
let childrenPath = fileManager.subpaths(atPath: basePath!)
if childrenPath != nil{
for path in childrenPath!{
if path != "iconName.png" && path != "Collect.json" {
let childPath = basePath!.appending("/").appending(path)
do{
let attr:NSDictionary = try fileManager.attributesOfItem(atPath: childPath) as NSDictionary
if let fileSize = attr["NSFileSize"] as? CGFloat {
total += fileSize
}
}catch _{
}
}
}
}
}
// 缓存文件大小
return total
}
// 调用函数
let totalCache = caculateCache()
return NSString(format: "%.2fM", totalCache / 1024.0 / 1024.0 ) as String
}
}
/// 清除缓存
///
/// - returns: 是否清理成功
public class func clearCache() -> Bool {
var result = true
// 取出cache文件夹目录 缓存文件都在这个目录下
let cachePath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first
// 取出文件夹下所有文件数组
let fileArr = FileManager.default.subpaths(atPath: cachePath!)
// 遍历删除
for file in fileArr! {
if file != "iconName.png" && file != "Collect.json" {
// 拼接文件路径
let path = cachePath?.appending("/\(file)")
if FileManager.default.fileExists(atPath: path!) {
// 循环删除
do {
try FileManager.default.removeItem(atPath: path!)
} catch {
// 删除失败
result = false
}
}
}
}
return result
}
}
//
// BsGestureTableView.swift
// GDKit
//
// Created by GDKit on 01/11/2022.
// Copyright (c) 2022 GDKit. All rights reserved.
//
import UIKit
open class BsGestureTableView: UITableView {
}
// MARK: - UIGestureRecognizerDelegate
extension BsGestureTableView: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
open override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
open class BsGestureScrollView: UIScrollView {
}
// MARK: - UIGestureRecognizerDelegate
extension BsGestureScrollView: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
open override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
open class BsGestureCollectionView: UICollectionView {
}
// MARK: - UIGestureRecognizerDelegate
extension BsGestureCollectionView: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
open override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
//
// BsOverlayView.swift
// BaiSiSMApp
//
// Created by DAVID on 2022/11/22.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
class BsOverlayView: UIView {
// MARK: - 属性
public var overlayView:UIControl! //遮罩层view
private var keyWindow : UIWindow?
// MARK: - 生命周期函数
override init(frame: CGRect) {
super.init(frame: frame)
setupOverlayView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupOverlayView() {
// 1 获取window
if (keyWindow == nil) {
self.keyWindow = UIApplication.shared.bsKeyWindow()
}
// 2.遮罩view
overlayView = UIControl.init(frame: UIScreen.main.bounds)
overlayView?.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5)
overlayView?.addTarget(self, action: #selector(hide), for: .touchUpInside)
overlayView?.alpha = 0
}
// MARK: - ACTIONS
//显示
public func show() {
keyWindow?.addSubview(overlayView!)
keyWindow?.addSubview(self)
UIView.animate(withDuration: 0.25, animations: {
self.overlayView?.alpha = 1.0
var frame = self.frame
frame.origin.y = UIScreen.main.bounds.size.height - self.bounds.size.height
self.frame = frame
}) { (isFinished) in
//
}
}
//隐藏
@objc public func hide() {
UIView.animate(withDuration: 0.25, animations: {
self.overlayView?.alpha = 0
var frame = self.frame
frame.origin.y = UIScreen.main.bounds.size.height
self.frame = frame
}) { (isFinished) in
self.overlayView?.removeFromSuperview()
self.removeFromSuperview()
}
}
// MARK: - 私有方法
// MARK: - 事件响应包括手势和按钮等
// MARK: - UITableViewDataSource 和 UITableViewDelegate
}
//
// Date-Extension.swift
// DouYuUI
//
// Created by davidhuang on 2022/8/11.
// Copyright © 2022 davidhuang. All rights reserved.
//
import UIKit
extension Date {
static func getCurrentDate() -> String {
let now = Int(Date.timeIntervalSinceReferenceDate)
return "\(now)"
}
init(_ dateString: String, dateFormat: String = "yyyy-MM-dd") {
let df = DateFormatter()
df.dateFormat = dateFormat
let date = df.date(from: dateString)!
self.init(timeInterval: 0, since: date)
}
}
//
// NSAttributedString+Extension.swift
// BaiSiSMApp
//
// Created by DAVID on 2022/12/6.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension NSAttributedString {
//添加富文本
public class func bs_create(string str: String, font: UIFont? = nil, color textColor: UIColor? = nil, url: String? = nil, lineSpacing: CGFloat? = nil) -> NSAttributedString {
var attributes: [NSAttributedString.Key: Any] = [:]
if let font = font {
attributes[.font] = font
}
if let textColor = textColor {
attributes[.foregroundColor] = textColor
}
if let url = url {
//添加链接文本
attributes[.link] = url
}
if let lineSpacing = lineSpacing {
//格式调整
let style = NSMutableParagraphStyle()
/**调行间距*/
style.lineSpacing = lineSpacing
style.alignment = .left
attributes[.paragraphStyle] = style
}
let attributedString = NSAttributedString(string: str, attributes: attributes)
return attributedString
}
//添加图片
public class func gd_create(image: UIImage) -> NSAttributedString {
let textAttachment = NSTextAttachment()
textAttachment.image = image
let attrStringWithImage = NSAttributedString(attachment: textAttachment)
return attrStringWithImage
}
}
extension NSAttributedString {
/// 富文本转html字符串
public class func attriToStr(attri: NSAttributedString) -> String {
let tempDic: [NSAttributedString.DocumentAttributeKey : Any] =
[NSAttributedString.DocumentAttributeKey.documentType:
NSAttributedString.DocumentType.html,
NSAttributedString.DocumentAttributeKey.characterEncoding:
String.Encoding.utf8.rawValue]
do {
let htmlData = try attri.data(from: NSRange(location: 0, length: attri.length-1), documentAttributes: tempDic)
return String(data: htmlData, encoding: String.Encoding.utf8) ?? ""
} catch {
return ""
}
}
/// 字符串转富文本
public class func strToAttri(htmlStr: String) -> NSAttributedString {
guard let data = htmlStr.data(using: String.Encoding.unicode) else {
return NSAttributedString()
}
do {
let attri = try NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)
return attri
} catch {
return NSAttributedString()
}
}
}
extension NSMutableAttributedString {
//添加图片和点击事件
public class func bs_create(image: UIImage) -> NSMutableAttributedString {
let textAttachment = NSTextAttachment()
textAttachment.image = image
let attrStringWithImage = NSMutableAttributedString(attachment: textAttachment)
attrStringWithImage.addAttributes([.link: "checkbox://"], range: NSMakeRange(0, attrStringWithImage.length))
return attrStringWithImage
}
public func setStyle(lineSpacing: CGFloat) {
//格式调整
let style = NSMutableParagraphStyle()
/**调行间距*/
style.lineSpacing = lineSpacing
style.alignment = .left
self.addAttributes([NSAttributedString.Key.paragraphStyle : style], range: NSRange(location: 0, length: self.string.count))
}
}
//
// String-Extension.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/12.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension String {
// MARK: - 拨打电话
func makePhone() {
let phone = "telprompt://" + self
if UIApplication.shared.canOpenURL(URL(string: phone)!) == true {
UIApplication.shared.open(URL(string: phone)!, options: [:], completionHandler: nil)
}
}
// MARK: - 判断是否为手机号码
func isMobile() -> Bool {
let reg = "^1[3456789]\\d{9}$"
let regextestmobile = NSPredicate(format: "SELF MATCHES %@",reg)
return regextestmobile.evaluate(with: self);
}
// MARK: - 判断密码是否合法
//密码至少包含一个数字,一个字母,一个特殊字符
func isPwdLegal() -> Bool {
let reg = "^(?=.*)(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[-~!@#$%^&*:;,.=?$\\x22]).{8,20}$"
let regextestmobile = NSPredicate(format: "SELF MATCHES %@",reg)
return regextestmobile.evaluate(with: self);
}
// MARK: - 是否包含字符
func isIncludeChinese() -> Bool {
for char in self {
if ("\u{4E00}" <= char && char <= "\u{9FA5}") {
return true
}
}
return false
}
func phoneNumberForUI() -> String {
let phone = self.replacingOccurrences(of: " ", with: "")
if phone.count == 11 {
let st1 = phone.slicing(from: 0, length: 3)
let st2 = phone.slicing(from:7,length: 4)
return st1! + "****" + st2!
}
return self
}
var unicodeDescription: String {
return self.stringByReplaceUnicode
}
var stringByReplaceUnicode: String {
let jsonDict = try? JSONSerialization.jsonObject(
with: self.data(using: String.Encoding.utf8, allowLossyConversion: true)!,
options: JSONSerialization.ReadingOptions.mutableLeaves)
let jsonData = try? JSONSerialization.data(withJSONObject: jsonDict as Any, options: .prettyPrinted)
let string_r = String(data: jsonData!, encoding: String.Encoding.utf8)
return string_r ?? self
}
//时间戳转Date
func stringConvertDate(dateFormat:String="yyyy-MM-dd HH:mm:ss") -> Date {
let timeZone = TimeZone.init(identifier: "UTC") //这是重点
let dateFormatter = DateFormatter.init()
dateFormatter.timeZone = timeZone
dateFormatter.dateFormat = dateFormat
let date = dateFormatter.date(from: self)
return date!
}
//时间戳转Date
func convertDate(dateFormat:String="yyyy-MM-dd HH:mm:ss") -> Date {
let dateFormatter = DateFormatter.init()
dateFormatter.dateFormat = dateFormat
let date = dateFormatter.date(from: self) ?? Date()
return date
}
//时间戳转 DateString
func timeStampToString()->String {
guard let timeStamp = self.cgFloat() else {
return "--"
}
//时间戳为毫秒级要 / 1000, 秒就不用除1000,参数带没带000
let timeSta:TimeInterval = TimeInterval(timeStamp)
let date = NSDate(timeIntervalSince1970: timeSta)
let dateformatter = DateFormatter()
dateformatter.dateFormat="yyyy-MM-dd HH:mm:ss"
return dateformatter.string(from: date as Date)
}
}
// MARK: - 计算文字的宽高
extension String {
/// 计算文字的宽高
///
/// - Parameters:
/// - font: 字体大小
/// - lineSpacing: 行高
/// - constraintRect: 大小范围
/// - Returns: 宽高
public func bs_sizeWithConstrained(_ font: UIFont,
lineSpacing: CGFloat? = nil,
constraintRect: CGSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)) -> CGSize {
var attributes: [NSAttributedString.Key : Any] = [NSAttributedString.Key.font: font]
if let lineSpacing = lineSpacing {
//格式调整
let style = NSMutableParagraphStyle()
/**调行间距*/
style.lineSpacing = lineSpacing
style.alignment = .left
attributes[.paragraphStyle] = style
}
let boundingBox = self.boundingRect(
with: constraintRect,
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes: attributes,
context: nil)
return boundingBox.size
}
}
// MARK: - 正则获取http
extension String {
//获取http链接字符串的参数
public var urlParameters: [String: String] {
guard let url = URL(string: self) else {
return [:]
}
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems else { return [:] }
return queryItems.reduce(into: [String: String]()) { (result, item) in
result[item.name] = item.value
}
}
///获取http链接字符串的range
public func getHttpRangeOfString() -> [NSTextCheckingResult]? {
let regulaStr = "((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"
do {
let regex = try NSRegularExpression(pattern: regulaStr, options: .caseInsensitive)
let arrayOfAllMatches = regex.matches(in: self, options: NSRegularExpression.MatchingOptions.init(rawValue: 0), range: NSMakeRange(0, self.count))
return arrayOfAllMatches
} catch {
return nil
}
}
}
/// 打印
///
/// - Parameters:
/// - message: 打印内容
/// - file: 所在文件
/// - method: 所在方法
/// - line: 所在行
public func printLog<T>(_ message: T, file: String = #file, method: String = #function, line: Int = #line) {
print("\((file as NSString).lastPathComponent)[\(line)],\(method):\(message)")
}
//
// UIApplication-Extension.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/31.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension UIApplication {
func bsKeyWindow() -> UIWindow? {
var originalKeyWindow: UIWindow?
#if swift(>=5.1)
if #available(iOS 13, *) {
originalKeyWindow = UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.first(where: { $0.isKeyWindow })
} else {
originalKeyWindow = UIApplication.shared.keyWindow
}
#else
originalKeyWindow = UIApplication.shared.keyWindow
#endif
return originalKeyWindow
}
}
//
// UIButton-Extension.swift
// BaiSiSMApp
//
// Created by DAVID on 2023/1/11.
// Copyright © 2023 www.sumian.com. All rights reserved.
//
import UIKit
extension UIButton {
/// 图片在右位置
/// - Parameter spacing: 间距
func iconInRight(with spacing: CGFloat) {
let img_w = self.imageView?.frame.size.width ?? 0
let title_w = self.titleLabel?.frame.size.width ?? 0
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: -(img_w+spacing / 2.0), bottom: 0, right: (img_w+spacing / 2.0))
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: (title_w+spacing / 2.0), bottom: 0, right: -(title_w+spacing / 2.0))
}
/// 图片在左位置
/// - Parameter spacing: 间距
func iconInLeft(spacing: CGFloat) {
self.titleEdgeInsets = UIEdgeInsets(top: 0, left: spacing / 2.0, bottom: 0, right: -spacing / 2.0)
self.imageEdgeInsets = UIEdgeInsets(top: 0, left: -spacing / 2.0, bottom: 0, right: spacing / 2.0)
}
/// 图片在上面
/// - Parameter spacing: 间距
func iconInTop(spacing: CGFloat) {
let img_W = self.imageView?.frame.size.width ?? 0
let img_H = self.imageView?.frame.size.height ?? 0
let tit_W = self.titleLabel?.frame.size.width ?? 0
let tit_H = self.titleLabel?.frame.size.height ?? 0
self.titleEdgeInsets = UIEdgeInsets(top: (tit_H / 2 + spacing / 2), left: -(img_W / 2), bottom: -(tit_H / 2 + spacing / 2), right: (img_W / 2))
self.imageEdgeInsets = UIEdgeInsets(top: -(img_H / 2 + spacing / 2), left: (tit_W / 2), bottom: (img_H / 2 + spacing / 2), right: -(tit_W / 2))
}
/// 图片在 下面
/// - Parameter spacing: 间距
func iconInBottom(spacing: CGFloat) {
let img_W = self.imageView?.frame.size.width ?? 0
let img_H = self.imageView?.frame.size.height ?? 0
let tit_W = self.titleLabel?.frame.size.width ?? 0
let tit_H = self.titleLabel?.frame.size.height ?? 0
self.titleEdgeInsets = UIEdgeInsets(top: -(tit_H / 2 + spacing / 2), left: -(img_W / 2), bottom: (tit_H / 2 + spacing / 2), right: (img_W / 2))
self.imageEdgeInsets = UIEdgeInsets(top: (img_H / 2 + spacing / 2), left: (tit_W / 2), bottom: -(img_H / 2 + spacing / 2), right: -(tit_W / 2))
}
}
// MARK: - Create 初始化
extension UIButton {
public class func bs_button(
title:String? = nil,
selectTitle:String? = nil,
font:UIFont? = nil,
normalColor: UIColor? = nil,
selectColor: UIColor? = nil,
bgNormalColor: UIColor? = nil,
bgSelectColor: UIColor? = nil,
lightNormalColor: UIColor? = nil,
lightSelectColor: UIColor? = nil,
bgLightNormalColor: UIColor? = nil,
bgLightSelectColor: UIColor? = nil) -> UIButton {
let btn = UIButton(type: .custom)
btn.titleLabel?.font = font
btn.setTitle(title, for: .normal)
btn.setTitle(selectTitle, for: .selected)
btn.setTitle(title, for: [.highlighted,.normal])
btn.setTitle(selectTitle, for: [.highlighted,.selected])
btn.setTitleColor(normalColor, for: .normal)
btn.setTitleColor(selectColor, for: .selected)
btn.setTitleColor(lightNormalColor, for: [.highlighted,.normal])
btn.setTitleColor(lightSelectColor, for: [.highlighted,.selected])
btn.setBackgroundImage(bgNormalColor?.imageWithColor(), for: .normal)
btn.setBackgroundImage(bgSelectColor?.imageWithColor(), for: .selected)
btn.setBackgroundImage(bgLightNormalColor?.imageWithColor(), for: [.highlighted,.normal])
if bgLightNormalColor == nil {
btn.setBackgroundImage(bgNormalColor?.withAlphaComponent(0.9).imageWithColor(), for: [.highlighted,.normal])
}
btn.setBackgroundImage(bgLightSelectColor?.imageWithColor(), for: [.highlighted,.selected])
if bgLightSelectColor == nil {
btn.setBackgroundImage(bgSelectColor?.withAlphaComponent(0.9).imageWithColor(), for: [.highlighted,.selected])
}
return btn
}
}
//
// UIColor-Extension.swift
// DouYuUI
//
// Created by davidhuang on 2022/8/9.
// Copyright © 2022 davidhuang. All rights reserved.
//
import UIKit
import SwifterSwift
extension UIColor {
// MARK: - 当前 app 主颜色
static let mainColor : UIColor = UIColor(hexString: "#46E0BB")!
static let commonColor100 : UIColor = UIColor(hexString: "#333333",transparency: 1.0)!
static let commonColor90 : UIColor = UIColor(hexString: "#333333",transparency: 0.9)!
static let commonColor65 : UIColor = UIColor(hexString: "#333333",transparency: 0.65)!
static let commonColor45 : UIColor = UIColor(hexString: "#333333",transparency: 0.45)!
static let commonColor25 : UIColor = UIColor(hexString: "#333333",transparency: 0.25)!
static let commonColor15 : UIColor = UIColor(hexString: "#333333",transparency: 0.15)!
static let commonColor10 : UIColor = UIColor(hexString: "#333333",transparency: 0.10)!
static let commonColor6 : UIColor = UIColor(hexString: "#333333",transparency: 0.06)!
static let commonColor4 : UIColor = UIColor(hexString: "#333333",transparency: 0.04)!
static let commonColor3 : UIColor = UIColor(hexString: "#333333",transparency: 0.03)!
static let backgroundColor : UIColor = UIColor(hexString: "#F2F7F6",transparency: 1.0)!
static let mainTextColor : UIColor = UIColor(hexString: "#00D19F")!
static let selectBgColor : UIColor = UIColor(hexString: "#D9FCF7")!
//黑色 50透明
static let black50Persent : UIColor = UIColor.black.withAlphaComponent(0.5)
public convenience init(r : CGFloat, g : CGFloat, b : CGFloat) {
self.init(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1.0)
}
public func imageWithColor(width: Double = 1.0, height: Double = 1.0) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: width, height: height)
UIGraphicsBeginImageContext(rect.size)
let ctx = UIGraphicsGetCurrentContext()
ctx!.setFillColor(self.cgColor)
ctx!.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
//
// UIDevice-Extension.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/11.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension UIDevice {
// MARK: - 屏幕size
static let kScreenSize : CGRect = UIScreen.main.bounds
// MARK: - 屏幕宽度
static let kScreenW : CGFloat = UIScreen.main.bounds.width
// MARK: - 屏幕高度
static let kScreenH : CGFloat = UIScreen.main.bounds.height
// MARK: - iOS系统版本号
static let kSystemVersion : String = UIDevice.current.systemVersion
// MARK: - 顶部安全区高度
static func bs_safeDistanceTop() -> CGFloat {
if #available(iOS 13.0, *) {
let scene = UIApplication.shared.connectedScenes.first
guard let windowScene = scene as? UIWindowScene else { return 0 }
guard let window = windowScene.windows.first else { return 0 }
return window.safeAreaInsets.top
}
// else if #available(iOS 11.0, *) {
// guard let window = UIApplication.shared.windows.first else { return 0 }
// return window.safeAreaInsets.top
// }
return 0;
}
// MARK: - 底部安全区高度
static func bs_safeDistanceBottom() -> CGFloat {
if #available(iOS 13.0, *) {
let scene = UIApplication.shared.connectedScenes.first
guard let windowScene = scene as? UIWindowScene else { return 0 }
guard let window = windowScene.windows.first else { return 0 }
return window.safeAreaInsets.bottom
}
// else if #available(iOS 11.0, *) {
// guard let window = UIApplication.shared.windows.first else { return 0 }
// return window.safeAreaInsets.bottom
// }
return 0;
}
// MARK: - 顶部状态栏高度(包括安全区)
static func bs_statusBarHeight() -> CGFloat {
var statusBarHeight: CGFloat = 0
if #available(iOS 13.0, *) {
let scene = UIApplication.shared.connectedScenes.first
guard let windowScene = scene as? UIWindowScene else { return 0 }
guard let statusBarManager = windowScene.statusBarManager else { return 0 }
statusBarHeight = statusBarManager.statusBarFrame.height
}
// else {
// statusBarHeight = UIApplication.shared.statusBarFrame.height
// }
return statusBarHeight
}
// MARK: - 导航栏高度
static func bs_navigationBarHeight() -> CGFloat {
return 44.0
}
// MARK: - 状态栏+导航栏的高度
static func bs_navigationFullHeight() -> CGFloat {
return UIDevice.bs_statusBarHeight() + UIDevice.bs_navigationBarHeight()
}
// MARK: - 底部导航栏高度
static func bs_tabBarHeight() -> CGFloat {
return 49.0
}
// MARK: - 底部导航栏高度(包括安全区)
static func bs_tabBarFullHeight() -> CGFloat {
return UIDevice.bs_tabBarHeight() + UIDevice.bs_safeDistanceBottom()
}
// MARK: - 版本号
static func appVersion() -> String {
let infoDictionary = Bundle.main.infoDictionary
if let infoDictionary = infoDictionary {
let appVersion = infoDictionary["CFBundleShortVersionString"]
return appVersion as! String
}
return " "
}
// MARK: - 内部编译版本号
static func appBuild() -> String {
let infoDictionary = Bundle.main.infoDictionary
if let infoDictionary = infoDictionary {
let appBuild = infoDictionary["CFBundleVersion"]
return appBuild as! String
}
return " "
}
}
//
// UIFont-Extension.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/16.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension UIFont {
// MARK: - 苹果字体
static func PFSCR(ofSize size : CGFloat = 15) -> UIFont {
return UIFont(name: "PingFangSC-Regular", size: size)!
}
static func PFSCM(ofSize size : CGFloat = 15) -> UIFont {
return UIFont(name: "PingFangSC-Medium", size: size)!
}
// static func PFSCB(ofSize size : CGFloat = 15) -> UIFont {
// return UIFont(name: "PingFangSC-Bold", size: size)!
// }
}
//
// UIImage-Extension.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/11/3.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension UIImage {
static func defaultHeadImage() -> UIImage? {
return UIImage(named: "default-head-image")
}
static func from(color: UIColor,
rect: CGRect = CGRect(origin: CGPoint.zero ,size: CGSize(width: 4, height: 4))) -> UIImage {
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img!
}
// 修复图片旋转
func fixOrientation() -> UIImage {
if self.imageOrientation == .up {
return self
}
var transform = CGAffineTransform.identity
switch self.imageOrientation {
case .down, .downMirrored:
transform = transform.translatedBy(x: self.size.width, y: self.size.height)
transform = transform.rotated(by: .pi)
break
case .left, .leftMirrored:
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.rotated(by: .pi / 2)
break
case .right, .rightMirrored:
transform = transform.translatedBy(x: 0, y: self.size.height)
transform = transform.rotated(by: -.pi / 2)
break
default:
break
}
switch self.imageOrientation {
case .upMirrored, .downMirrored:
transform = transform.translatedBy(x: self.size.width, y: 0)
transform = transform.scaledBy(x: -1, y: 1)
break
case .leftMirrored, .rightMirrored:
transform = transform.translatedBy(x: self.size.height, y: 0);
transform = transform.scaledBy(x: -1, y: 1)
break
default:
break
}
let ctx = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: self.cgImage!.bitmapInfo.rawValue)
ctx?.concatenate(transform)
switch self.imageOrientation {
case .left, .leftMirrored, .right, .rightMirrored:
ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.height), height: CGFloat(size.width)))
break
default:
ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.width), height: CGFloat(size.height)))
break
}
let cgimg: CGImage = (ctx?.makeImage())!
let img = UIImage(cgImage: cgimg)
return img
}
}
// MARK: - 图片大小编辑
extension UIImage {
//等比例放大(图片居中,增加边缘透明范围)
func bs_scaled(toHeight: CGFloat, opaque: Bool = false) -> UIImage? {
let scale = toHeight / size.height
let newWidth = size.width * scale
UIGraphicsBeginImageContextWithOptions(CGSize(width: newWidth, height: toHeight), opaque, self.scale)
draw(in: CGRect(x: (newWidth - size.width)/2, y: (toHeight - size.height)/2, width: size.width, height: size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
func withBackground(color: UIColor, opaque: Bool = true) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
guard let ctx = UIGraphicsGetCurrentContext(), let image = cgImage else { return self }
defer { UIGraphicsEndImageContext() }
let rect = CGRect(origin: .zero, size: size)
ctx.setFillColor(color.cgColor)
ctx.fill(rect)
ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height))
ctx.draw(image, in: rect)
return UIGraphicsGetImageFromCurrentImageContext() ?? self
}
//等比例放大(图片居中,增加边缘透明范围)
func bs_scaled(toWidth: CGFloat, opaque: Bool = false) -> UIImage? {
let scale = toWidth / size.width
let newHeight = size.height * scale
UIGraphicsBeginImageContextWithOptions(CGSize(width: toWidth, height: newHeight), opaque, self.scale)
draw(in: CGRect(x: (toWidth - size.width)/2, y: (newHeight - size.height)/2, width: size.width, height: size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
/// 放大画布大小(图片自定义,增加边缘透明范围)
/// - Parameters:
/// - toSize: 需要的画布大小
/// - rect: 图片在画布的位置
/// - opaque: 不透明/黑色背景
/// - Returns: 图片
func bs_canvas(toSize: CGSize, rect: CGRect, opaque: Bool = false) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(CGSize(width: toSize.width, height: toSize.height), opaque, self.scale)
draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
//
// UILable-Extension.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/11/16.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension UILabel {
public class func createBsTagLabel() -> UILabel {
let temp = UILabel()
temp.textColor = UIColor(hexString: "#333333", transparency: 0.45)
temp.textAlignment = .center
temp.font = UIFont.PFSCM(ofSize: 10)
temp.backgroundColor = UIColor(hexString: "#333333", transparency: 0.04)
temp.layer.cornerRadius = 2
temp.clipsToBounds = true
return temp
}
public class func label(text: String, font: UIFont, color: UIColor, numberOfLines: Int = 0, alignment: NSTextAlignment = .left) -> UILabel {
let label = UILabel()
label.text = text
label.font = font
label.textColor = color
label.numberOfLines = numberOfLines
label.textAlignment = alignment
return label
}
convenience init(text: String, font: UIFont, color: UIColor, numberOfLines: Int = 0, alignment: NSTextAlignment = .left) {
self.init()
self.text = text
self.font = font
self.textColor = color
self.numberOfLines = numberOfLines
self.textAlignment = alignment
}
var requiredWidth: CGFloat {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: CGFloat.greatestFiniteMagnitude, height: frame.height))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text
label.attributedText = attributedText
label.sizeToFit()
return label.frame.width
}
}
//
// UIView-Extension.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/16.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
extension UIView {
// MARK: - 旋转
func rotate( begin : Bool = true) {
if begin == true {
let rotation : CABasicAnimation = CABasicAnimation(keyPath:"transform.rotation.z")
rotation.toValue = NSNumber(value: Double.pi * 2)
rotation.duration = 3
rotation.isCumulative = true
rotation.repeatCount = Float.greatestFiniteMagnitude
rotation.fillMode = CAMediaTimingFillMode(rawValue: "forwards")
layer.add(rotation, forKey:"rotationAnimation")
} else {
layer.removeAllAnimations()
}
}
// MARK: - 获取当前UIview 所在的 UIViewController
func getFirstViewController()->UIViewController?{
for view in sequence(first: self.superview, next: {$0?.superview}){
if let responder = view?.next{
if responder.isKind(of: UIViewController.self){
return responder as? UIViewController
}
}
}
return nil
}
// MARK: - UIView 晃动效果
public func shake2(direction:ShakeDirection = .horizontal,times: Int = 5,
interval:TimeInterval = 0.1, delta : CGFloat = 5,completion:(() -> Void)?=nil){
if times == 0 {
self.layer.setAffineTransform(CGAffineTransform.identity)
} else {
UIView.animate(withDuration: interval) {
switch direction {
case .horizontal:
self.layer.setAffineTransform(CGAffineTransform(translationX: delta, y: 0))
break
case .vertical:
self.layer.setAffineTransform(CGAffineTransform(translationX: 0, y: delta))
break
}
} completion: { (finished) in
self.shake2(direction: direction, times: times - 1 , interval: interval, delta: delta * -1, completion: completion)
}
}
}
}
// MARK: - 阴影设置
extension UIView {
@objc public enum ShadowType: Int {
case all = 0 ///四周
case top = 1 ///上方
case left = 2///左边
case right = 3///右边
case bottom = 4///下方
}
///默认设置:黑色阴影, 阴影所占视图的比例
// func shadow(_ type: ShadowType, percent: Float) {
// shadow(type: type, color: .black, opactiy: 0.4, //shadowSize: 4)
//}
///默认设置:黑色阴影
@objc func shadow(_ type: ShadowType) {
shadow(type: type, color: .black, opactiy: 0.1, shadowSize: 4)
}
///阴影设置
@objc public func shadow(type: ShadowType, color: UIColor, opactiy: Float, shadowSize: CGFloat) -> Void {
layer.masksToBounds = false;//必须要等于NO否则会把阴影切割隐藏掉
layer.shadowColor = color.cgColor;// 阴影颜色
layer.shadowOpacity = opactiy;// 阴影透明度,默认0
layer.shadowOffset = .zero;//shadowOffset阴影偏移,默认(0, -3),这个跟shadowRadius配合使用
layer.shadowRadius = 3 //阴影半径,默认3
var shadowRect: CGRect?
switch type {
case .all:
shadowRect = CGRect.init(x: -shadowSize, y: -shadowSize, width: bounds.size.width + 2 * shadowSize, height: bounds.size.height + 2 * shadowSize)
case .top:
shadowRect = CGRect.init(x: -shadowSize, y: -shadowSize, width: bounds.size.width + 2 * shadowSize, height: 2 * shadowSize)
case .bottom:
shadowRect = CGRect.init(x: -shadowSize, y: bounds.size.height - shadowSize, width: bounds.size.width + 2 * shadowSize, height: 2 * shadowSize)
case .left:
shadowRect = CGRect.init(x: -shadowSize, y: -shadowSize, width: 2 * shadowSize, height: bounds.size.height + 2 * shadowSize)
case .right:
shadowRect = CGRect.init(x: bounds.size.width - shadowSize, y: -shadowSize, width: 2 * shadowSize, height: bounds.size.height + 2 * shadowSize)
}
layer.shadowPath = UIBezierPath.init(rect: shadowRect!).cgPath
}
///阴影 0.5
@objc public func bs_shadow(color: UIColor = UIColor(red: 0.87, green: 0.87, blue: 0.87, alpha: 0.7), offset: CGSize = CGSize(width: 0, height: 1.5), opacity: Float = 1, radius: CGFloat = 3.5) {
self.layer.shadowColor = color.cgColor
self.layer.shadowOffset = offset
self.layer.shadowOpacity = opacity
self.layer.shadowRadius = radius
}
///内阴影
@objc public func bs_innerShadow() {
self.layer.shadowColor = UIColor(red: 0.87, green: 0.87, blue: 0.87, alpha: 0.5).cgColor
self.layer.shadowOffset = CGSize(width: 0, height: 0)
self.layer.shadowOpacity = 1
self.layer.shadowRadius = 3
}
}
// MARK: - 圆角设置
extension UIView {
public func setCorners(corners: UIRectCorner, radius: CGFloat) -> Void {
self.setCorners(corners: corners, radius: radius, rect: self.bounds)
}
public func setCorners(corners: UIRectCorner, radius: CGFloat, rect: CGRect) -> Void {
let path = UIBezierPath.init(roundedRect: rect, byRoundingCorners: corners , cornerRadii: CGSize.init(width: radius, height: radius))
let layer = CAShapeLayer.init()
layer.frame = self.bounds
layer.path = path.cgPath
self.layer.mask = layer
}
///渐变颜色(frame需要有值)
@objc public func bs_gradient(_ type: ShadowType = .left, colors: [UIColor], locations: [NSNumber]? = nil) {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.bounds
//设置颜色
var cgColors: [CGColor] = []
for color in colors {
cgColors.append(color.cgColor)
}
gradientLayer.colors = cgColors
//设置占比
if locations == nil {
let num = 1.0/(Double(colors.count)-1.0)
var locations: [NSNumber] = []
for i in 0..<colors.count {
locations.append(NSNumber(value: num*Double(i)))
}
gradientLayer.locations = locations
} else {
gradientLayer.locations = locations
}
//设置位置
switch type {
case .all:
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.5)
case .top:
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1)
break
case .left:
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
break
case .right:
gradientLayer.startPoint = CGPoint(x: 1, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0, y: 0.5)
break
case .bottom:
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0)
break
}
self.layer.addSublayer(gradientLayer)
}
/// 绘制虚线
/// - Parameters:
/// - lineLength: 长度
/// - lineSpacing: 间隔长度
/// - lineColor: 颜色
public func bs_drawDashLine(lineLength: Int, lineSpacing: Int, lineColor: UIColor) {
let shapeLayer = CAShapeLayer()
shapeLayer.bounds = self.bounds
shapeLayer.anchorPoint = CGPoint(x: 0, y: 0)
shapeLayer.strokeColor = lineColor.cgColor
shapeLayer.lineWidth = 1 //描边路径时使用的线宽。默认为1。
shapeLayer.lineJoin = CAShapeLayerLineJoin.round
shapeLayer.lineDashPattern = [NSNumber(value: lineLength),NSNumber(value: lineSpacing)]
let path = CGMutablePath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: self.bounds.size.width, y: 0))
shapeLayer.path = path
self.layer.addSublayer(shapeLayer)
}
}
// MARK: - Frame
extension UIView {
//let cOrigin: CGPoint //!< 位置
//let cSize: CGSize //!< 大小
open var height: CGFloat {
get {
return self.frame.height
}
set {
var frame = self.frame
frame.size.height = newValue
self.frame = frame
}
} //!< 高度
open var width: CGFloat {
get {
return self.frame.width
}
set {
var frame = self.frame
frame.size.width = newValue
self.frame = frame
}
} //!< 宽度
open var top: CGFloat {
get {
return self.frame.minY
}
set {
var frame = self.frame
frame.origin.y = newValue
self.frame = frame
}
} //!< 上
open var left: CGFloat {
get {
return self.frame.minX
}
set {
var frame = self.frame
frame.origin.x = newValue
self.frame = frame
}
} //!< 左
open var bottom: CGFloat {
get {
return self.frame.maxY
}
set {
var frame = self.frame
frame.origin.y = newValue - self.frame.height
self.frame = frame
}
} //!< 下
open var right: CGFloat {
get {
return self.frame.maxX
}
set {
var frame = self.frame;
frame.origin.x = newValue - self.frame.width
self.frame = frame
}
} //!< 右
}
//
// BSjsonUtil.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/11/18.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
import HandyJSON
class BSJsonUtil: NSObject {
/**
* Json转对象
*/
static func jsonToModel(_ jsonStr:String,_ modelType:HandyJSON.Type) ->BsBaseModel {
if jsonStr == "" || jsonStr.count == 0 {
#if DEBUG
print("jsonoModel:字符串为空")
#endif
return BsBaseModel()
}
return modelType.deserialize(from: jsonStr) as! BsBaseModel
}
/**
* Json转数组对象
*/
static func jsonArrayToModel(_ jsonArrayStr:String, _ modelType:HandyJSON.Type) ->[BsBaseModel] {
if jsonArrayStr == "" || jsonArrayStr.count == 0 {
#if DEBUG
print("jsonToModelArray:字符串为空")
#endif
return []
}
var modelArray:[BsBaseModel] = []
let data = jsonArrayStr.data(using: String.Encoding.utf8)
let peoplesArray = try! JSONSerialization.jsonObject(with:data!, options: JSONSerialization.ReadingOptions()) as? [AnyObject]
for people in peoplesArray! {
modelArray.append(dictionaryToModel(people as! [String : Any], modelType))
}
return modelArray
}
/**
* 字典转对象
*/
static func dictionaryToModel(_ dictionStr:[String:Any],_ modelType:HandyJSON.Type) -> BsBaseModel {
if dictionStr.count == 0 {
#if DEBUG
print("dictionaryToModel:字符串为空")
#endif
return BsBaseModel()
}
return modelType.deserialize(from: dictionStr) as! BsBaseModel
}
/**
* 对象转JSON
*/
static func modelToJson(_ model:BsBaseModel?) -> String {
if model == nil {
#if DEBUG
print("modelToJson:model为空")
#endif
return ""
}
return (model?.toJSONString())!
}
/**
* 对象转字典
*/
static func modelToDictionary(_ model:BsBaseModel?) -> [String:Any] {
if model == nil {
#if DEBUG
print("modelToJson:model为空")
#endif
return [:]
}
return (model?.toJSON())!
}
//数组转json
static func arrayToJson(_ array:NSArray) -> String {
if (!JSONSerialization.isValidJSONObject(array)) {
print("无法解析出JSONString")
return ""
}
let data : NSData! = try? JSONSerialization.data(withJSONObject: array, options: []) as NSData
let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
return JSONString! as String
}
/**
* 字典转JSON
*/
static func dictionaryToJson(_ dictionary:NSDictionary) -> String {
if (!JSONSerialization.isValidJSONObject(dictionary)) {
print("无法解析出JSONString")
return ""
}
let data : NSData! = try? JSONSerialization.data(withJSONObject: dictionary, options: []) as NSData
let JSONString = NSString(data:data as Data,encoding: String.Encoding.utf8.rawValue)
return JSONString! as String
}
}
//
// BsConstant.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/19.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
// MARK: - 工程中的 常量定义
class BsConstant {
// MARK: - 个人信息基本类型
enum UserBaseInfoType : Int {
case unknow //未知
case sex//性别
case birthday//生日
case height//身高
case weight//体重
case education //学历
case profession //职务
case work_domain//从事行业
case income//收入
func title() -> String {
switch self {
case .sex:
return "性别"
case .birthday:
return "生日"
case .height:
return "身高"
case .weight:
return "体重"
case .education:
return "学历"
case .profession:
return "职务"
case .work_domain:
return "从事行业"
case .income:
return "收入"
default:
return "--"
}
}
func titleForSelectView() -> String {
switch self {
case .sex:
return "性别"
case .birthday:
return "生日"
case .height:
return "身高(单位:cm)"
case .weight:
return "体重(单位:kg)"
case .education:
return "学历"
case .profession:
return "职务"
case .work_domain:
return "从事行业"
case .income:
return "收入(单位:k)"
default:
return "--"
}
}
/*
var id : String = ""//用户ID
var user_type : String = ""//用户类型 1:普通用户2.明星用户3.管理员
var sex : String = ""//性别 0其他, 1:男, 2女
var real_name : String = "" //真实姓名
var nick_name : String = "" //昵称
var avatar : String = ""//头像
var birthday : String = ""//生日
var status : String = ""//用户状态1:正常,0:已注销
var height : String = ""//身高
var weight : String = ""//体重
var user_name : String = ""//用户名
var phone : String = ""//手机号码
var marital_status : String = ""//婚姻情况
var profession : String = ""//职业ID
var profession_name : String = ""//职业名称
var education : String = ""//文化程度ID
var education_name : String = ""//文化程度名称
var work_domain : String = ""//行业领域ID
var work_domain_name : String = ""//行业领域名称
*/
func key() -> String {
switch self {
case .sex:
return "sex"
case .birthday:
return "birthday"
case .height:
return "height"
case .weight:
return "weight"
case .education:
return "education"
case .profession:
return "profession"
case .work_domain:
return "work_domain"
case .income:
return "monthly_income"
default:
return ""
}
}
}
// MARK: - URL 相关
struct URL {
// MARK: - 帮助与反馈
static let userQAUrl = YHBaseUrlManager.shared.h5URL() + "landing/index.html#/pages/my/index"
// MARK: - 优眠用户注销条款
static let userUnregisterURL = "https://www.baidu.com"
// MARK: - 隐私政策
static let privacyURL = YHBaseUrlManager.shared.h5URL() + "landing/index.html#/subpages/personal/pages/protocol/index?classify=privacy"
// MARK: - 用户协议
static let userProtocalURL = YHBaseUrlManager.shared.h5URL() + "landing/index.html#/subpages/personal/pages/protocol/index?classify=agreement"
// MARK: - 付费咨询服务协议
static let payProtocalURL = "https://www.baidu.com"
// MARK: - 官网地址
static let officialWebsite = "https://www.sumian.com"
// MARK: - 量表入口
static let liangBiaoEntryWebsite = YHBaseUrlManager.shared.h5URL() + "landing/index.html#/pages/medicineCenter/index"
// MARK: - 通用链接,可以在 Safari 等 web 环境打开 APP,目前主要是提供给微信APP调用
static let universal_link = "https://sdapi.sumian.com/sleepdoctor/"
static let wx_universal_link = universal_link + "wx-sign-in/"
//#if DEBUG
// // MARK: - 医学中心
// static let medical_center_url = "http://10.168.3.41:10086/h5/#/pages/medicineCenter/index"
//#else
// MARK: - 医学中心
static let medical_center_url = YHBaseUrlManager.shared.h5URL() + "landing/index.html#/pages/medicineCenter/index"
//#endif
// MARK: - 助眠专辑详情
//static let music_detail_url = BsBaseUrlManager.shared.h5URL() + "landing/index.html#/subpages/platform/pages/musicdetail/index?immerse=1"
// MARK: - 文章列表
//static let article_list_url = BsBaseUrlManager.shared.h5URL() + "landing/index.html#/subpages/platform/pages/articlelist/index?immerse=1"
// MARK: - 文章详情
static let article_detail_url = YHBaseUrlManager.shared.h5URL() + "landing/index.html#/subpages/platform/pages/articledetail/index?immerse=1"
// MARK: - 科普视频列表
//static let video_list_url = BsBaseUrlManager.shared.h5URL() + "landing/index.html#/subpages/platform/pages/videolist/index?immerse=1"
}
// MARK: - 阿里云 手机号一键登录 秘钥信息
static let kAliOnePressPhoneLoginKey = "pjYDHIVE1Q4qu7QJNI8MaxfvqJQvn5j+Az8xHRlnctj+kUAGf2Hin6ONsTFu1yjCwWPvhmw5NlhFo5DuP1SabykuX1Dz/xl4aDDLQQ5oijBNqRtwmwFAHl/exvfLk6zndWdv3Hi+DUL6gRwAj2UWj1rNXAMP2YSlisC0NSrFFFpiKyHAd2dM2OpIiGh9lkGeihU5iOjv/IycVMW6l2Sx9QqcrKiAX44aPMp0/uS5+y0xYwy/CjV6bvpacHNstxtVFd2Vgi7p454="
// MARK: - 登录信息
static let KLoginedInfoKey = "KLoginedInfoKey"
// MARK: - 上次登录成功后的 手机号码
static let KLastLoginedSuccessPhoneKey = "KLastLoginedSuccessPhoneKey"
// MARK: - 登录用户 详情信息
static let kDetailInfo = "kDetailInfo"
}
extension BsConstant {
// MARK: - 友盟相关
struct Wechat {
static let appKey = "wx57b2a7469d15ff8f"
static let AppSecret = "e0a351290c66c05f85c54a31b213c1aa"
}
struct UM {
static let appKey = "5a77b807a40fa30f0300008b"
}
// MARK: - 支付宝
struct Alipay {
static let scheme = "com.usleep.health.alipay"
}
// MARK: - 通知相关 名称
class BsNotification {
public static let didCancelTaskNotification = Notification.Name(rawValue: "org.alamofire.notification.name.request.didCancelTask")
//用户详细信息更改成功
public static let didUpdateUserDetailInfoSuccessNotifiction = Notification.Name(rawValue: "com.usleep.health.updateUserDetailInfo.success")
//登录成功
public static let didLoginSuccessNotifiction = Notification.Name(rawValue: "com.usleep.health.login.success")
//退出成功
public static let didLoginoutSuccessNotifiction = Notification.Name(rawValue: "com.usleep.health.loginout.success")
//token 过期
public static let tokenInvalidateNotifiction = Notification.Name(rawValue: "com.usleep.health.token.invalidate")
//用户注册 在完成登录、修改密码后需要 填写标签
public static let needSelectTagsNotification = Notification.Name(rawValue: "com.usleep.health.selecte.tags")
//跳转安睡主页
public static let goAnSleepNotification = Notification.Name(rawValue: "com.usleep.health.go.An.sleep")
//跳转填写量表列表界面
public static let goFillScaleNotification = Notification.Name(rawValue: "com.usleep.health.go.Fill.Scale")
//支付结果回调
public static let payResultNotification = Notification.Name(rawValue: "com.usleep.health.pay.result")
//隐藏tabBar
public static let tabBarHideNotification = Notification.Name(rawValue: "com.usleep.health.tabBar.hide")
//显示tabBar
public static let tabBarShowNotification = Notification.Name(rawValue: "com.usleep.health.tabBar.show")
//安睡主页切换Tab
public static let sleepPageChangeTabNotification = Notification.Name(rawValue: "com.usleep.health.sleepPage.changeTab")
}
}
//
// BsHUD.swift
// PKHUD Demo
//
// Created by ahao on 2018/3/20.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
import PKHUD
public enum BsHUDType {
case success(message: String?)
case error(message: String?)
case warning(message: String?)
case progress(message: String?)
case image(image: UIImage?, message: String?)
case rotatingImage(image: UIImage?, message: String?)
}
class BsHUD {
// MARK: Properties
public static var dimsBackground: Bool {
get { return PKHUD.sharedHUD.dimsBackground }
set { PKHUD.sharedHUD.dimsBackground = newValue }
}
public static var allowsInteraction: Bool {
get { return PKHUD.sharedHUD.userInteractionOnUnderlyingViewsEnabled }
set { PKHUD.sharedHUD.userInteractionOnUnderlyingViewsEnabled = newValue }
}
public static var isVisible: Bool { return PKHUD.sharedHUD.isVisible }
// MARK: Public methods, PKHUD based
public static func show(_ content: BsHUDType, onView view: UIView? = nil) {
PKHUD.sharedHUD.contentView = contentView(content)
PKHUD.sharedHUD.show(onView: view)
}
public static func hide(_ completion: ((Bool) -> Void)? = nil) {
PKHUD.sharedHUD.hide(animated: false, completion: completion)
}
public static func hide(animated: Bool, completion: ((Bool) -> Void)? = nil) {
PKHUD.sharedHUD.hide(animated: animated, completion: completion)
}
public static func hide(afterDelay delay: TimeInterval, completion: ((Bool) -> Void)? = nil) {
PKHUD.sharedHUD.hide(afterDelay: delay, completion: completion)
}
public static func hideFlashMessage() {
let keyWindow = UIApplication.shared.windows.first {$0.isKeyWindow}
if keyWindow != nil {
while(keyWindow!.viewWithTag(BsHUD.flashMessageTag) != nil){
keyWindow!.viewWithTag(BsHUD.flashMessageTag)?.removeFromSuperview()
}
}
}
// MARK: Public methods, HUD based
public static func flash(_ content: BsHUDType, onView view: UIView? = nil) {
BsHUD.flash(content, onView: view, delay: 1, completion: nil)
}
public static func flash(_ content: BsHUDType, onView view: UIView? = nil, delay: TimeInterval, completion: ((Bool) -> Void)? = nil) {
BsHUD.show(content, onView: view)
BsHUD.hide(afterDelay: delay, completion: completion)
}
// MARK: Private methods
static func contentView(_ content: BsHUDType) -> UIView {
let todoView: UIView
switch content {
case let .progress(message):
todoView = BsHUDProgressView(title: message)
case let .success(message):
todoView = BsHUDSuccessView(title: message)
case let .error(message):
todoView = BsHUDErrorView(title: message)
case let .warning(message):
todoView = BsHUDWariningView(title: message)
case let .rotatingImage(image, message):
todoView = BsHUDSquareBaseView(image: image, title: message)
case let .image(image, message):
todoView = BsHUDSquareBaseView(image: image, title: message)
}
return todoView
}
}
extension BsHUD{
static func setup(){
PKHUD.sharedHUD.effect = nil
// PKHUD.sharedHUD.gracePeriod = 0.5
}
}
extension BsHUD{
static let flashMessageTag = 61535
static func flash(message: String,
dismissAfter: TimeInterval = 1.5,
duration:TimeInterval = 0.5,
isRemoveBefore: Bool = true,
insets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 120, right: 20),
contentInsets: UIEdgeInsets = UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10),
containerWindow: UIWindow? = nil,
walk:((UILabel)->Void)? = nil){
if isRemoveBefore{
hideFlashMessage()
}
if message.isEmpty{
return
}
let containerView = UIView()
containerView.backgroundColor = UIColor.black.withAlphaComponent(0.7)
containerView.layer.cornerRadius = 4
containerView.alpha = 0
containerView.tag = flashMessageTag
let label = UILabel()
label.text = message
label.numberOfLines = 5
label.textColor = UIColor.white
label.font = UIFont.systemFont(ofSize: 14)
containerView.addSubview(label)
walk?(label)
let keyW = UIApplication.shared.windows.first {$0.isKeyWindow}
if let keyWindow = (containerWindow ?? keyW){
let labelWidth = keyWindow.bounds.width-insets.left-insets.right-contentInsets.left-contentInsets.right
label.frame = CGRect(x: contentInsets.left,
y: contentInsets.top,
width: labelWidth,
height: 30)
label.sizeToFit()
let containerViewSize = CGSize(width: label.frame.width+contentInsets.left+contentInsets.right,
height: label.frame.height+contentInsets.top+contentInsets.bottom)
containerView.frame = CGRect(x: (keyWindow.bounds.width-containerViewSize.width)/2.0,
y: (keyWindow.bounds.height-containerViewSize.height)/2.0,
width: containerViewSize.width,
height: containerViewSize.height)
keyWindow.addSubview(containerView)
UIView.animate(withDuration: duration, animations: {
containerView.alpha = 1
}, completion: { (_) in
UIView.animate(withDuration: duration, delay: dismissAfter, options: [], animations: {
containerView.alpha = 0
}, completion: { (_) in
containerView.removeFromSuperview()
})
})
}
}
}
//
// BsHUDContainerView.swift
// PKHUD Demo
//
// Created by ahao on 2018/3/20.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
class BsHUDContainerView: UIView {
static let defaultFrame = CGRect(origin: CGPoint.zero, size: CGSize(width: 156.0, height: 156.0))
private let offSet: CGFloat
var contentView: UIView
init(contentView:UIView,offSet: CGFloat = 0) {
self.contentView = contentView
self.offSet = offSet
super.init(frame: BsHUDContainerView.adjustFrame(contentViewFrame: contentView.frame, offSet: offSet))
addSubview(contentView)
}
func adjustFrame() -> CGRect{
return BsHUDContainerView.adjustFrame(contentViewFrame: contentView.frame, offSet: offSet)
}
class func adjustFrame(contentViewFrame: CGRect, offSet: CGFloat) -> CGRect{
let height = contentViewFrame.height + abs(offSet) * 2
let adjustSize = CGSize(width: contentViewFrame.width, height: height)
return CGRect(origin: CGPoint.zero, size: adjustSize)
}
override func layoutSubviews() {
super.layoutSubviews()
let contentSize = contentView.frame.size
contentView.frame = CGRect(origin: CGPoint.zero, size: contentSize)
contentView.center = CGPoint(x: bounds.width/2.0, y: bounds.height/2.0 + offSet)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// BsHUDErrorView.swift
// PKHUD Demo
//
// Created by ahao on 2018/3/20.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
import PKHUD
class BsHUDErrorView: BsHUDSquareBaseView {
public init(title: String? = nil) {
super.init(image: UIImage(named: "float_icon_error"), title: title)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
//
// BsHUDProgressView.swift
// PKHUD Demo
//
// Created by ahao on 2018/4/19.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
import PKHUD
class BsHUDProgressView: BsHUDSquareBaseView,PKHUDAnimating {
public init(title: String? = nil) {
super.init(image:UIImage(named:"float_icon_loading"), title: title)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public func startAnimation() {
imageView.layer.add(PKHUDAnimation.discreteRotation, forKey: "progressAnimation")
}
public func stopAnimation() {
imageView.layer.removeAnimation(forKey: "progressAnimation")
}
}
//
// BsHUDRotatingImageView.swift
// PKHUD Demo
//
// Created by ahao on 2018/4/19.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
import PKHUD
class BsHUDRotatingImageView: BsHUDSquareBaseView,PKHUDAnimating {
public func startAnimation() {
imageView.layer.add(PKHUDAnimation.discreteRotation, forKey: "progressAnimation")
}
public func stopAnimation() {
}
}
//
// BsHUDSquareBaseView.swift
// PKHUD Demo
//
// Created by ahao on 2018/4/19.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
import PKHUD
class BsHUDSquareBaseView: UIView {
static let defaultSquareBaseViewFrame = CGRect(origin: CGPoint.zero, size: CGSize(width: 120, height: 120))
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init(image: UIImage? = nil, title: String? = nil) {
super.init(frame: BsHUDSquareBaseView.defaultSquareBaseViewFrame)
backgroundColor = UIColor.black
imageView.image = image
titleLabel.text = title
titleLabel.sizeToFit()
addSubview(containerView)
containerView.addSubview(imageView)
containerView.addSubview(titleLabel)
}
let imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
imageView.contentMode = .scaleAspectFit
return imageView
}()
let titleLabel: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 14.0)
label.textColor = UIColor.white
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = 0.25
return label
}()
let containerView: UIView = {
let temp = UIView()
return temp
}()
open override func layoutSubviews() {
super.layoutSubviews()
let viewWidth = bounds.size.width
let viewHeight = bounds.size.height
let labelHeight = titleLabel.bounds.height
let imageViewHeight: CGFloat = max(imageView.image?.size.height ?? 28, 30)
let padding: CGFloat = labelHeight > 0 ? 8 : 0
let containerWidth = viewWidth - 5 - 5
let containerHeight = imageViewHeight + padding + labelHeight
containerView.frame.size = CGSize(width: containerWidth, height: containerHeight)
containerView.center = CGPoint(x: viewWidth/2.0, y: viewHeight/2.0)
imageView.frame = CGRect(origin: CGPoint.zero,
size: CGSize(width: containerWidth, height: imageViewHeight))
titleLabel.frame = CGRect(origin: CGPoint(x: 0, y: imageView.frame.maxY + padding),
size: CGSize(width: viewWidth-8, height: titleLabel.frame.height))
}
}
//
// BsHUDSuccessView.swift
// PKHUD Demo
//
// Created by ahao on 2018/3/20.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
import PKHUD
class BsHUDSuccessView: BsHUDSquareBaseView {
public init(title: String? = nil) {
super.init(image: UIImage(named:"float_icon_success"), title: title)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
//
// BsHUDWariningView.swift
// PKHUD Demo
//
// Created by ahao on 2018/4/19.
// Copyright © 2018年 NSExceptional. All rights reserved.
//
import UIKit
class BsHUDWariningView: BsHUDSquareBaseView {
public init(title: String? = nil) {
super.init(image: UIImage(named:"float_icon_caveat"), title: title)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
//
// BsKVOHelper.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/10/19.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
///解决重复添加;解决重复移除;解决未添加却移除
open class BsKVOHelper {
class Container: Equatable {
static func == (lhs: BsKVOHelper.Container, rhs: BsKVOHelper.Container) -> Bool {
guard let lObserver = lhs.observer,
let lObject = lhs.object,
let rObserver = rhs.observer,
let rObject = rhs.object else {
return false
}
if lObserver == rObserver, lObject == rObject{
return lhs.keyPath == rhs.keyPath
}
return false
}
var observer: Int?
var object: Int?
var keyPath: String
init(observer: Int?, object: Int?, keyPath: String) {
self.observer = observer
self.object = object
self.keyPath = keyPath
}
func clear(){
observer = nil
object = nil
}
}
private var containers: [Container] = []
public init(){
}
open func add(observer: NSObject,toObject object: NSObject,forKeyPath keyPath: String, options: NSKeyValueObservingOptions = [], context: UnsafeMutableRawPointer?){
let aContainer = Container(observer: observer.hashValue, object: object.hashValue, keyPath: keyPath)
if containers.contains(where: { (thisContainer) -> Bool in
return aContainer == thisContainer
}){
return
}
containers.append(aContainer)
object.addObserver(observer,forKeyPath: keyPath, options: options, context: context)
}
open func remove(observer: NSObject,atObject object: NSObject,forKeyPath keyPath: String){
let aContainer = Container(observer: observer.hashValue, object: object.hashValue, keyPath: keyPath)
if let first = containers.first(where: { (thisContainer) -> Bool in
return aContainer == thisContainer
}){
object.removeObserver(observer, forKeyPath: keyPath)
first.clear()
}
}
}
//
// BsMapManager.swift
// BaiSiSMApp
//
// Created by DAVID on 2022/12/15.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
import MapKit
class BsMapManager {
// MARK: - 属性
static let sharedInstance = BsMapManager()
public let hasQqMap: Bool = UIApplication.shared.canOpenURL(URL(string: "qqmap://")!)
public let hasIosaMap: Bool = UIApplication.shared.canOpenURL(URL(string: "iosamap://")!)
public let hasBaiduMap: Bool = UIApplication.shared.canOpenURL(URL(string: "baidumap://")!)
// 当前位置或起始位置
var currentLocation: CLLocationCoordinate2D!
var currentAddress: String = ""
// 目标位置
var targetLocation: CLLocationCoordinate2D!
var targetAddress: String = ""
// MARK: - 导航位置初始化
func initNavi(currentLoc: CLLocationCoordinate2D! = nil, currentAdd: String = "", targetLoc: CLLocationCoordinate2D!, targetAdd: String) {
if currentLoc != nil {
currentLocation = currentLoc
}
currentAddress = currentAdd
if targetLoc != nil {
targetLocation = targetLoc
}
targetAddress = targetAdd
}
// MARK: - Apple地图导航
func naviWithAppleMap() {
if targetLocation == nil {
return
}
// 起始位置
let fromLocation = MKMapItem.forCurrentLocation()
fromLocation.name = "我的位置"
// 目标位置
let toCoor = CLLocationCoordinate2D(latitude: targetLocation!.latitude, longitude: targetLocation!.longitude)
let toLocation = MKMapItem(placemark: MKPlacemark(coordinate: toCoor, addressDictionary: [:]))
toLocation.name = targetAddress
// 打开地图
MKMapItem.openMaps(with: [fromLocation, toLocation],
launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsShowsTrafficKey: NSNumber(true)])
}
// MARK: - 百度地图导航
func naviWithBaiduMap() {
if targetLocation == nil {
return
}
/// 请求格式:
/// baidumap://map/direction?origin=34.264642646862,108.95108518068&destination=40.007623,116.360582&coord_type=bd09ll&mode=driving&src=ios.baidu.openAPIdemo
var urlString: String = "baidumap://map/direction?"
// 起始位置
let origin: String = "我的位置"
urlString = urlString + "origin=\(origin)"
// 目标位置
let destination: String = "\(targetLocation!.latitude),\(targetLocation!.longitude)"
let name: String = targetAddress
urlString = urlString + "&destination=name:\(name)|latlng:\(destination)"
/// 可选的坐标系统:
/// bd09ll(百度经纬度坐标)
/// bd09mc(百度墨卡托坐标)
/// gcj02(经国测局加密的坐标)
/// wgs84(gps获取的原始坐标)
urlString = urlString + "&coord_type=gcj02&mode=driving&src=ios.ftsafe.FTSmartSudentCard"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
if #available(iOS 10.0, *) {
UIApplication.shared.open(URL(string: urlString)!, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(URL(string: urlString)!)
}
}
// MARK: - 腾讯地图导航
func naviWithQqMap() {
if targetLocation == nil {
return
}
/// 请求格式:
/// qqmap://map/routeplan?type=drive&from=清华&fromcoord=39.994745,116.247282&to=怡和世家&tocoord=39.867192,116.493187&referer=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
/// 这里可能需要开发者key,即referer
var urlString: String = "qqmap://map/routeplan?type=drive"
let origin: String = "我的位置"
urlString = urlString + "&from=\(origin)&fromcoord=CurrentLocation"
let destination: String = "\(targetLocation!.latitude),\(targetLocation!.longitude)"
let name: String = targetAddress
urlString = urlString + "&to=\(name)&tocoord=\(destination)"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
if #available(iOS 10.0, *) {
UIApplication.shared.open(URL(string: urlString)!, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(URL(string: urlString)!)
}
}
// MARK: - 高德地图导航
func naviWithAMap() {
if targetLocation == nil {
return
}
/// 请求格式:
/// iosamap://path?sourceApplication=applicationName&sid=&slat=39.92848272&slon=116.39560823&sname=A&did=&dlat=39.98848272&dlon=116.47560823&dname=B&dev=0&t=0
var urlString: String = "iosamap://path?sourceApplication=FTSmartSudentCard"
let name: String = targetAddress
urlString = urlString + "&dlat=\(targetLocation!.latitude)&dlon=\(targetLocation!.longitude)&dname=\(name)&dev=0&t=0"
urlString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
if #available(iOS 10.0, *) {
UIApplication.shared.open(URL(string: urlString)!, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(URL(string: urlString)!)
}
}
}
//
// BsPageContentView.swift
// GDKit
//
// Created by GDKit on 01/11/2022.
// Copyright (c) 2022 GDKit. All rights reserved.
//
import UIKit
@objc public protocol BsPageContentViewDelegate : AnyObject {
func pageContentView(_ contentView : BsPageContentView, progress : CGFloat, sourceIndex : Int, targetIndex : Int)
}
private let ContentCellID = "BsContentCellID"
open class BsPageContentView: UIView {
// MARK: - 定义属性
fileprivate var childVcs : [UIViewController]
fileprivate weak var parentVC : UIViewController?
fileprivate var startOffsetX : CGFloat = 0
fileprivate var isForbidScrollDelegate : Bool = false
@objc public weak var delegate : BsPageContentViewDelegate?
public var isScrollEnabled: Bool? {
didSet {
if let isScrollEnabled = isScrollEnabled {
collectionView.isScrollEnabled = isScrollEnabled
}
}
}
@objc public func banScrollEnabled() {
collectionView.isScrollEnabled = false
}
fileprivate func getLayout() -> UICollectionViewFlowLayout {
let layout = UICollectionViewFlowLayout()
layout.itemSize = self.bounds.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .horizontal
return layout
}
// MARK: - 懒加载属性
fileprivate lazy var collectionView : UICollectionView = {[weak self] in
// 1.创建layout
let layout = self?.getLayout() ?? UICollectionViewFlowLayout()
// 2.创建UICollectionView
let collectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
collectionView.backgroundColor = .clear//groupTableViewBackground
collectionView.showsHorizontalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.bounces = false
collectionView.dataSource = self
collectionView.delegate = self
collectionView.scrollsToTop = false
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: ContentCellID)
return collectionView
}()
// MARK: - 自定义构造函数
@objc public init(frame: CGRect, childVcs : [UIViewController], parentViewController : UIViewController?) {
self.childVcs = childVcs
self.parentVC = parentViewController
super.init(frame: frame)
// 设置UI
setupUI()
}
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// MARK: - 设置UI界面
extension BsPageContentView {
fileprivate func setupUI() {
// 1.将所有的子控制器添加父控制器中
for childVc in childVcs {
parentVC?.addChild(childVc)
}
// 2.添加UICollectionView,用于在Cell中存放控制器的View
addSubview(collectionView)
collectionView.frame = bounds
}
public func refreshRect() {
collectionView.frame = bounds
collectionView.collectionViewLayout = self.getLayout()
}
}
// MARK: - 遵守UICollectionViewDataSource
extension BsPageContentView : UICollectionViewDataSource {
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return childVcs.count
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// 1.创建Cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ContentCellID, for: indexPath)
// 2.给Cell设置内容
for view in cell.contentView.subviews {
view.removeFromSuperview()
}
let childVc = childVcs[(indexPath as NSIndexPath).item]
childVc.view.frame = cell.contentView.bounds
cell.contentView.addSubview(childVc.view)
return cell
}
}
// MARK: - 遵守UICollectionViewDelegate
extension BsPageContentView : UICollectionViewDelegate {
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
isForbidScrollDelegate = false
startOffsetX = scrollView.contentOffset.x
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
// 0.判断是否是点击事件
if isForbidScrollDelegate { return }
// 1.定义获取需要的数据
var progress : CGFloat = 0
var sourceIndex : Int = 0
var targetIndex : Int = 0
// 2.判断是左滑还是右滑
let currentOffsetX = scrollView.contentOffset.x
let scrollViewW = scrollView.bounds.width
if currentOffsetX > startOffsetX { // 左滑
// 1.计算progress
progress = currentOffsetX / scrollViewW - floor(currentOffsetX / scrollViewW)
// 2.计算sourceIndex
sourceIndex = Int(currentOffsetX / scrollViewW)
// 3.计算targetIndex
targetIndex = sourceIndex + 1
if targetIndex >= childVcs.count {
targetIndex = childVcs.count - 1
}
// 4.如果完全划过去
if currentOffsetX - startOffsetX == scrollViewW {
progress = 1
targetIndex = sourceIndex
}
} else { // 右滑
// 1.计算progress
progress = 1 - (currentOffsetX / scrollViewW - floor(currentOffsetX / scrollViewW))
// 2.计算targetIndex
targetIndex = Int(currentOffsetX / scrollViewW)
// 3.计算sourceIndex
sourceIndex = targetIndex + 1
if sourceIndex >= childVcs.count {
sourceIndex = childVcs.count - 1
}
}
// 3.将progress/sourceIndex/targetIndex传递给titleView
delegate?.pageContentView(self, progress: progress, sourceIndex: sourceIndex, targetIndex: targetIndex)
}
}
// MARK: - 对外暴露的方法
extension BsPageContentView {
@objc public func setCurrentIndex(_ currentIndex : Int) {
// 1.记录需要进制执行代理方法
isForbidScrollDelegate = true
// 2.滚动正确的位置
let offsetX = CGFloat(currentIndex) * collectionView.frame.width
collectionView.setContentOffset(CGPoint(x: offsetX, y: 0), animated: false)
}
}
//
// BsPresentView.swift
// BaiSiSMApp
//
// Created by DAVID on 2022/12/15.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
/// view.tag = 98 由下往上推出
/// view.tag = 99 由frame起点缩放
open class BsPresentView: UIView {
var animated: Bool = true
///由下往上推出
@objc public func bs_showView(_ view: UIView, isTapEnabled: Bool = true) {
self.animated = true
bs_showView(view, isTapEnabled: isTapEnabled, animated: true)
}
///由下往上推出
@objc public func bs_showView(_ view: UIView, isTapEnabled: Bool = true, animated: Bool) {
// self.keyWindow = [[[UIApplication sharedApplication] delegate] window];
// self.keyVC = self.keyWindow.rootViewController;
// self.frame = self.keyWindow.bounds;
view.tag = 98
self.animated = animated
self.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
self.backgroundColor = UIColor.black.withAlphaComponent(0.4)
UIApplication.shared.keyWindow?.addSubview(self)
let topView = UIView(frame: self.frame)
self.addSubview(topView)
topView.height = self.height - view.height
if isTapEnabled == true {
let tap = UITapGestureRecognizer(target: self, action: #selector(bs_closeView))
topView.addGestureRecognizer(tap)
}
self.addSubview(view)
view.top = self.height
if (animated == true) {
UIView.animate(withDuration: 0.25) {
view.top = self.height - view.height
}
}else{
view.top = self.height - view.height
}
}
///由frame为起点缩放
@objc public func bs_showView(_ view: UIView, frame: CGRect) {
view.tag = 99
self.animated = true
//view.frame = CGRect(x: frame.origin.x, y: frame.origin.y, width: 0, height: 0)
self.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
//self.backgroundColor = UIColor.black.withAlphaComponent(0.4)
UIApplication.shared.keyWindow?.addSubview(self)
let backView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
self.addSubview(backView)
let tap = UITapGestureRecognizer(target: self, action: #selector(bs_closeView))
backView.addGestureRecognizer(tap)
backView.isUserInteractionEnabled = false
self.addSubview(view)
view.frame = frame
if (animated == true) {
var offsetX = frame.size.width / 2
if frame.origin.x < (UIScreen.main.bounds.size.width - frame.size.width)/2 {
offsetX = -frame.size.width / 2
}
let offsetY = -frame.size.height / 2
view.transform = __CGAffineTransformMake(0.01, 0, 0, 0.01, offsetX, offsetY)
//view.layer.anchorPoint = CGPoint(x: 0, y: 0) //锚点
UIView.animate(withDuration: 0.3) {
view.alpha = 1.0
view.transform = __CGAffineTransformMake(1.05, 0, 0, 1.0, 0, 0)
} completion: { success in
UIView.animate(withDuration: 0.1) {
view.transform = __CGAffineTransformMake(1, 0, 0, 1, 0, 0)
} completion: { success in
// 恢复原位
view.transform = CGAffineTransform.identity
backView.isUserInteractionEnabled = true
}
}
}else{
view.frame = frame
}
}
// override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// self.bs_closeView()
// }
@objc public func bs_closeView() {
guard let view = self.subviews.last, self.subviews.count == 2 else {
self.removeFromSuperview()
return
}
if (animated == true) {
if view.tag == 99 {
let frame = view.frame
// 动画由大变小
view.transform = __CGAffineTransformMake(1, 0, 0, 1, 0, 0)
UIView.animate(withDuration: 0.2) {
var offsetX = frame.size.width / 2
if frame.origin.x < (UIScreen.main.bounds.size.width - frame.size.width)/2 {
offsetX = -frame.size.width / 2
}
let offsetY = -frame.size.height / 2
view.transform = __CGAffineTransformMake(0.01, 0, 0, 0.01, offsetX, offsetY)
} completion: { success in
view.transform = CGAffineTransform.identity
view.alpha = 0.0
self.removeFromSuperview()
}
} else {
UIView.animate(withDuration: 0.25, animations: {
view.top = self.height
}) { (finished) in
self.removeFromSuperview()
}
}
}else{
view.top = self.height
self.removeFromSuperview()
}
}
public class func bs_closeView() {
for view in UIApplication.shared.keyWindow?.subviews ?? [] {
if let view = view as? BsPresentView {
view.bs_closeView()
break
}
}
}
}
extension UIView {
@objc public func bs_closeViewToPresentView() {
if let presentView = self.superview as? BsPresentView {
presentView.bs_closeView()
}
}
}
//
// BskWebViewPreloadManager.swift
// BaiSiSMApp
//
// Created by davidhuang on 2022/11/22.
// Copyright © 2022 www.davidhuang.com. All rights reserved.
//
import UIKit
import WebKit
class BsWebViewPreloadManager : NSObject {
private var dicPreloadedViews : [String : AnyObject] = [:]
static let share = BsWebViewPreloadManager()
override init() {
super.init()
addPreloadingView()
}
// /**
// 根据URL 预初始化若干WebView
// */
// - (void)addPreloadingView:(NSArray *)urls {
// for (NSString *url in urls) {
// if (![self.urls containsObject:url]) {
// [self.urls addObject: url];
// ReuseWebView *webView = [self createWebView];
// [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
// [self.preloadedViews addEntriesFromDictionary:@{url:webView}];
// }
// }
// }
}
// MARK: - 私有方法 methods
extension BsWebViewPreloadManager {
private func getWebview(urlString : String) -> WKWebView {
if let wk = dicPreloadedViews[urlString] {
return wk as! WKWebView
}
return createWebView(urlString: urlString)
}
private func createWebView(urlString : String) -> WKWebView {
let jScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jScript, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
let userContentController = WKUserContentController()
userContentController.addUserScript(userScript)
let cfg = WKWebViewConfiguration()
cfg.allowsInlineMediaPlayback = true
cfg.mediaTypesRequiringUserActionForPlayback = []
cfg.userContentController = userContentController
let wv = WKWebView(frame: UIScreen.main.bounds,configuration: cfg)
if let nsURL = URL(string: urlString){
let request = URLRequest(url: nsURL)
wv.load(request)
return wv
}
return WKWebView()
}
#if DEBUG
func onlyCreateWebView() -> WKWebView {
let jScript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);"
let userScript = WKUserScript(source: jScript, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
let userContentController = WKUserContentController()
userContentController.addUserScript(userScript)
let cfg = WKWebViewConfiguration()
cfg.allowsInlineMediaPlayback = true
cfg.mediaTypesRequiringUserActionForPlayback = []
cfg.userContentController = userContentController
let wv = WKWebView(frame: UIScreen.main.bounds,configuration: cfg)
return wv
}
#endif
}
// MARK: - public methods
extension BsWebViewPreloadManager {
func addPreloadingView() {
let arrUrl = [
BsConstant.URL.medical_center_url]
for item in arrUrl {
let wv = createWebView(urlString: item)
dicPreloadedViews[item] = wv
}
}
func getWebView(urlString : String) -> WKWebView {
let urls = dicPreloadedViews.keys
if urls.contains(urlString) == false {
return getWebview(urlString: urlString)
} else {
let wk = createWebView(urlString: urlString)
dicPreloadedViews[urlString] = wk
return wk
}
}
}
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment