| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- //
- // UIView+Extension.swift
- // QuickSearchLocation
- //
- // Created by mac on 2024/4/10.
- //
- import Foundation
- import UIKit
- import Toast_Swift
- // MARK: - 屏幕尺寸常用的常量
- public extension UIView {
-
- // MARK: 1.1、是否是缺口屏幕(刘海屏)或者灵动岛的屏幕
- // 是否是缺口屏幕(刘海屏)或者灵动岛的屏幕
- var qsl_isIPhoneNotch: Bool {
- if #available(iOS 11.0, *) {
- if let window = UIApplication.keyWindow {
- return window.safeAreaInsets.bottom > 0
- } else {
- return false
- }
- } else {
- return UIApplication.shared.statusBarFrame.height > 20
- }
- }
- // MARK: 2.1、屏幕的宽
- /// 屏幕的宽
- var qsl_kScreenW: CGFloat { return UIScreen.main.bounds.width }
- // MARK: 2.2、屏幕的高
- /// 屏幕的高
- var qsl_kScreenH: CGFloat { return UIScreen.main.bounds.height }
- // MARK: 2.3、获取statusBar的高度
- /// 获取statusBar的高度
- var qsl_kStatusBarFrameH: CGFloat {
- if #available(iOS 13.0, *) {
- let window: UIWindow? = UIApplication.shared.windows.first
- let statusBarHeight = (window?.windowScene?.statusBarManager?.statusBarFrame.height) ?? 0
- return statusBarHeight
- } else {
- // 防止界面没有出来获取为0的情况
- return UIApplication.shared.statusBarFrame.height > 0 ? UIApplication.shared.statusBarFrame.height : 44
- }
- }
- // MARK: 2.4、获取导航栏的高度
- /// 获取导航栏的高度
- var qsl_kNavFrameH: CGFloat { return 44 + qsl_kStatusBarFrameH }
-
- // MARK: 2.5、屏幕底部Tabbar高度
- /// 屏幕底部Tabbar高度
- var qsl_kTabbarFrameH: CGFloat { return qsl_isIPhoneNotch ? 83 : 49 }
- // MARK: 2.6、屏幕底部刘海高度
- /// 屏幕底部刘海高度
- var qsl_kTabbarBottom: CGFloat { return qsl_isIPhoneNotch ? 34 : 0 }
- // MARK: 2.7、屏幕比例
- /// 屏幕比例
- var qsl_kPixel: CGFloat { return 1.0 / UIScreen.main.scale }
-
- var qsl_kScale: CGFloat { return qsl_kScreenW / CGFloat(375.0) }
-
- }
- // MARK: - UIView 有关 Frame 的扩展
- public extension UIView {
- // MARK: 3.1、x 的位置
- /// x 的位置
- var qsl_x: CGFloat {
- get {
- return frame.origin.x
- }
- set(newValue) {
- var tempFrame: CGRect = frame
- tempFrame.origin.x = newValue
- frame = tempFrame
- }
- }
- // MARK: 3.2、y 的位置
- /// y 的位置
- var qsl_y: CGFloat {
- get {
- return frame.origin.y
- }
- set(newValue) {
- var tempFrame: CGRect = frame
- tempFrame.origin.y = newValue
- frame = tempFrame
- }
- }
-
- // MARK: 3.3、height: 视图的高度
- /// height: 视图的高度
- var qsl_height: CGFloat {
- get {
- return frame.size.height
- }
- set(newValue) {
- var tempFrame: CGRect = frame
- tempFrame.size.height = newValue
- frame = tempFrame
- }
- }
-
- // MARK: 3.4、width: 视图的宽度
- /// width: 视图的宽度
- var qsl_width: CGFloat {
- get {
- return frame.size.width
- }
- set(newValue) {
- var tempFrame: CGRect = frame
- tempFrame.size.width = newValue
- frame = tempFrame
- }
- }
-
- // MARK: 3.5、size: 视图的zize
- /// size: 视图的zize
- var qsl_size: CGSize {
- get {
- return frame.size
- }
- set(newValue) {
- var tempFrame: CGRect = frame
- tempFrame.size = newValue
- frame = tempFrame
- }
- }
-
- // MARK: 3.6、centerX: 视图的X中间位置
- /// centerX: 视图的X中间位置
- var qsl_centerX: CGFloat {
- get {
- return center.x
- }
- set(newValue) {
- var tempCenter: CGPoint = center
- tempCenter.x = newValue
- center = tempCenter
- }
- }
-
- // MARK: 3.7、centerY: 视图的Y中间位置
- /// centerY: 视图Y的中间位置
- var qsl_centerY: CGFloat {
- get {
- return center.y
- }
- set(newValue) {
- var tempCenter: CGPoint = center
- tempCenter.y = newValue
- center = tempCenter
- }
- }
-
- // MARK: 3.9、top 上端横坐标(y)
- /// top 上端横坐标(y)
- var qsl_top: CGFloat {
- get {
- return frame.origin.y
- }
- set(newValue) {
- var tempFrame: CGRect = frame
- tempFrame.origin.y = newValue
- frame = tempFrame
- }
- }
-
- // MARK: 3.10、left 左端横坐标(x)
- /// left 左端横坐标(x)
- var qsl_left: CGFloat {
- get {
- return frame.origin.x
- }
- set(newValue) {
- var tempFrame: CGRect = frame
- tempFrame.origin.x = newValue
- frame = tempFrame
- }
- }
-
- // MARK: 3.11、bottom 底端纵坐标 (y + height)
- /// bottom 底端纵坐标 (y + height)
- var qsl_bottom: CGFloat {
- get {
- return frame.origin.y + frame.size.height
- }
- set(newValue) {
- frame.origin.y = newValue - frame.size.height
- }
- }
-
- // MARK: 3.12、right 底端纵坐标 (x + width)
- /// right 底端纵坐标 (x + width)
- var qsl_right: CGFloat {
- get {
- return frame.origin.x + frame.size.width
- }
- set(newValue) {
- frame.origin.x = newValue - frame.size.width
- }
- }
-
- // MARK: 3.13、origin 点
- /// origin 点
- var qsl_origin: CGPoint {
- get {
- return frame.origin
- }
- set(newValue) {
- var tempOrigin: CGPoint = frame.origin
- tempOrigin = newValue
- frame.origin = tempOrigin
- }
- }
- }
- // MARK: - 关于UIView的 圆角、阴影、边框、虚线 的设置
- public extension UIView {
-
- // MARK: 5.1、添加圆角
- /// 添加圆角
- /// - Parameters:
- /// - radius: 圆角的大小
- func addRadius(radius:CGFloat) {
-
- self.layer.cornerRadius = radius
- self.clipsToBounds = true
- }
-
- // MARK: 5.1、添加圆角
- /// 添加圆角
- /// - Parameters:
- /// - conrners: 具体哪个圆角
- /// - radius: 圆角的大小
- func addCorner(conrners: UIRectCorner , radius: CGFloat) {
- let maskPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: conrners, cornerRadii: CGSize(width: radius, height: radius))
- let maskLayer = CAShapeLayer()
- maskLayer.frame = self.bounds
- maskLayer.path = maskPath.cgPath
- self.layer.mask = maskLayer
- }
-
- // MARK: 5.2、添加圆角和边框
- /// 添加圆角和边框
- /// - Parameters:
- /// - conrners: 具体哪个圆角
- /// - radius: 圆角的大小
- /// - borderWidth: 边框的宽度
- /// - borderColor: 边框的颜色
- func addCorner(conrners: UIRectCorner , radius: CGFloat, borderWidth: CGFloat, borderColor: UIColor) {
- let maskPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: conrners, cornerRadii: CGSize(width: radius, height: radius))
- let maskLayer = CAShapeLayer()
- maskLayer.frame = self.bounds
- maskLayer.path = maskPath.cgPath
- self.layer.mask = maskLayer
-
- // Add border
- let borderLayer = CAShapeLayer()
- borderLayer.path = maskLayer.path
- borderLayer.fillColor = UIColor.clear.cgColor
- borderLayer.strokeColor = borderColor.cgColor
- borderLayer.lineWidth = borderWidth
- borderLayer.frame = self.bounds
- self.layer.addSublayer(borderLayer)
- }
-
- // MARK: 5.3、给继承于view的类添加阴影
- /// 给继承于view的类添加阴影
- /// - Parameters:
- /// - shadowColor: 阴影的颜色
- /// - shadowOffset: 阴影的偏移度:CGSizeMake(X[正的右偏移,负的左偏移], Y[正的下偏移,负的上偏移])
- /// - shadowOpacity: 阴影的透明度
- /// - shadowRadius: 阴影半径,默认 3
- func addShadow(shadowColor: UIColor, shadowOffset: CGSize, shadowOpacity: Float, shadowRadius: CGFloat = 3) {
- // 设置阴影颜色
- layer.shadowColor = shadowColor.cgColor
- // 设置透明度
- layer.shadowOpacity = shadowOpacity
- // 设置阴影半径
- layer.shadowRadius = shadowRadius
- // 设置阴影偏移量
- layer.shadowOffset = shadowOffset
- }
-
- // MARK: 5.4、添加阴影和圆角并存
- /// 添加阴影和圆角并存
- ///
- /// - Parameter superview: 父视图
- /// - Parameter conrners: 具体哪个圆角
- /// - Parameter radius: 圆角大小
- /// - Parameter shadowColor: 阴影的颜色
- /// - Parameter shadowOffset: 阴影的偏移度:CGSizeMake(X[正的右偏移,负的左偏移], Y[正的下偏移,负的上偏移])
- /// - Parameter shadowOpacity: 阴影的透明度
- /// - Parameter shadowRadius: 阴影半径,默认 3
- ///
- /// - Note1: 如果在异步布局(如:SnapKit布局)中使用,要在布局后先调用 layoutIfNeeded,再使用该方法
- /// - Note2: 如果在添加阴影的视图被移除,底部插入的父视图的layer是不会被移除的⚠️
- func addCornerAndShadow(superview: UIView, conrners: UIRectCorner , radius: CGFloat = 3, shadowColor: UIColor, shadowOffset: CGSize, shadowOpacity: Float, shadowRadius: CGFloat = 3) {
-
- let maskPath = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: conrners, cornerRadii: CGSize(width: radius, height: radius))
- let maskLayer = CAShapeLayer()
- maskLayer.frame = self.bounds
- maskLayer.path = maskPath.cgPath
- self.layer.mask = maskLayer
-
- let subLayer = CALayer()
- let fixframe = self.frame
- subLayer.frame = fixframe
- subLayer.cornerRadius = radius
- subLayer.backgroundColor = shadowColor.cgColor
- subLayer.masksToBounds = false
- // shadowColor阴影颜色
- subLayer.shadowColor = shadowColor.cgColor
- // shadowOffset阴影偏移,x向右偏移3,y向下偏移2,默认(0, -3),这个跟shadowRadius配合使用
- subLayer.shadowOffset = shadowOffset
- // 阴影透明度,默认0
- subLayer.shadowOpacity = shadowOpacity
- // 阴影半径,默认3
- subLayer.shadowRadius = shadowRadius
- subLayer.shadowPath = maskPath.cgPath
- superview.layer.insertSublayer(subLayer, below: self.layer)
- }
-
- // MARK: 5.5、通过贝塞尔曲线View添加阴影和圆角
- /// 通过贝塞尔曲线View添加阴影和圆角
- ///
- /// - Parameter conrners: 具体哪个圆角(暂时只支持:allCorners)
- /// - Parameter radius: 圆角大小
- /// - Parameter shadowColor: 阴影的颜色
- /// - Parameter shadowOffset: 阴影的偏移度:CGSizeMake(X[正的右偏移,负的左偏移], Y[正的下偏移,负的上偏移])
- /// - Parameter shadowOpacity: 阴影的透明度
- /// - Parameter shadowRadius: 阴影半径,默认 3
- ///
- /// - Note: 提示:如果在异步布局(如:SnapKit布局)中使用,要在布局后先调用 layoutIfNeeded,再使用该方法或者在override func layoutSublayers(of layer: CALayer) {} 里面调用,也要使用 layoutIfNeeded
- func addViewCornerAndShadow(conrners: UIRectCorner , radius: CGFloat = 3, shadowColor: UIColor, shadowOffset: CGSize, shadowOpacity: Float, shadowRadius: CGFloat = 3) {
- // 切圆角
- layer.shadowColor = shadowColor.cgColor
- layer.shadowOffset = shadowOffset
- layer.shadowOpacity = shadowOpacity
- layer.shadowRadius = shadowRadius
- layer.cornerRadius = radius
-
- // 路径阴影
- let path = UIBezierPath.init(roundedRect: bounds, byRoundingCorners: conrners, cornerRadii: CGSize.init(width: radius, height: radius))
- layer.shadowPath = path.cgPath
- }
-
- // MARK: 5.6、添加边框
- /// 添加边框
- /// - Parameters:
- /// - width: 边框宽度
- /// - color: 边框颜色
- func addBorder(borderWidth: CGFloat, borderColor: UIColor) {
- layer.borderWidth = borderWidth
- layer.borderColor = borderColor.cgColor
- layer.masksToBounds = true
- }
-
- // MARK: 5.7、毛玻璃效果
- /// 毛玻璃效果
- /// - Parameters:
- /// - alpha: 可设置模糊的程度(0-1),越大模糊程度越大
- /// - size: 毛玻璃的size
- /// - style: 模糊效果
- func effectViewWithAlpha(alpha: CGFloat = 1.0, size: CGSize? = nil, style: UIBlurEffect.Style = .light) {
- // 模糊视图的大小
- var visualEffectViewSize = CGSize(width: 0, height: 0)
- if let weakSize = size {
- visualEffectViewSize = weakSize
- } else {
- visualEffectViewSize = self.qsl_size
- }
- let visualEffectView = UIVisualEffectView.visualEffectView(size: visualEffectViewSize, alpha: alpha, style: style, isAddVibrancy: false)
- self.addSubview(visualEffectView)
- }
-
- // 设置渐变颜色
- func gradientBackgroundColor(color1: UIColor, color2: UIColor, width: CGFloat, height: CGFloat, direction: ImageGradientDirection) {
-
- if let image = UIImage.gradient([color1, color2], size: CGSize(width: width, height: height), locations: [0, 1], direction: direction) {
- self.backgroundColor = UIColor(patternImage: image)
- }
- }
- }
- extension UIView {
-
- func addFourCornerAndBorder(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat, borderWidth: CGFloat, borderColor: UIColor){
- let cornerRadii = UIView.CornerRadii.init(topLeft: topLeft, topRight: topRight, bottomLeft: bottomLeft, bottomRight: bottomRight)
- let path = createPathWithRoundedRect(bounds: self.bounds, cornerRadii:cornerRadii)
- let shapLayer = CAShapeLayer()
- shapLayer.frame = self.bounds
- shapLayer.path = path
- self.layer.mask = shapLayer
-
- // Add border
- let borderLayer = CAShapeLayer()
- borderLayer.path = shapLayer.path
- borderLayer.fillColor = UIColor.clear.cgColor
- borderLayer.strokeColor = borderColor.cgColor
- borderLayer.lineWidth = borderWidth
- borderLayer.frame = self.bounds
- self.layer.insertSublayer(borderLayer, at: 0)
- }
-
- //添加4个不同大小的圆角
- func addFourCorner(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat){
- let cornerRadii = UIView.CornerRadii.init(topLeft: topLeft, topRight: topRight, bottomLeft: bottomLeft, bottomRight: bottomRight)
- let path = createPathWithRoundedRect(bounds: self.bounds, cornerRadii:cornerRadii)
- let shapLayer = CAShapeLayer()
- shapLayer.frame = self.bounds
- shapLayer.path = path
- self.layer.mask = shapLayer
- }
-
- //各圆角大小
- struct CornerRadii {
- var topLeft :CGFloat = 0
- var topRight :CGFloat = 0
- var bottomLeft :CGFloat = 0
- var bottomRight :CGFloat = 0
- }
-
- //切圆角函数绘制线条
- func createPathWithRoundedRect (bounds:CGRect,cornerRadii:CornerRadii) -> CGPath {
- let minX = bounds.minX
- let minY = bounds.minY
- let maxX = bounds.maxX
- let maxY = bounds.maxY
-
- //获取四个圆心
- let topLeftCenterX = minX + cornerRadii.topLeft
- let topLeftCenterY = minY + cornerRadii.topLeft
-
- let topRightCenterX = maxX - cornerRadii.topRight
- let topRightCenterY = minY + cornerRadii.topRight
-
- let bottomLeftCenterX = minX + cornerRadii.bottomLeft
- let bottomLeftCenterY = maxY - cornerRadii.bottomLeft
-
- let bottomRightCenterX = maxX - cornerRadii.bottomRight
- let bottomRightCenterY = maxY - cornerRadii.bottomRight
-
- //虽然顺时针参数是YES,在iOS中的UIView中,这里实际是逆时针
- let path :CGMutablePath = CGMutablePath();
- //顶 左
- path.addArc(center: CGPoint(x: topLeftCenterX, y: topLeftCenterY), radius: cornerRadii.topLeft, startAngle: CGFloat.pi, endAngle: CGFloat.pi * 3 / 2, clockwise: false)
- //顶右
- path.addArc(center: CGPoint(x: topRightCenterX, y: topRightCenterY), radius: cornerRadii.topRight, startAngle: CGFloat.pi * 3 / 2, endAngle: 0, clockwise: false)
- //底右
- path.addArc(center: CGPoint(x: bottomRightCenterX, y: bottomRightCenterY), radius: cornerRadii.bottomRight, startAngle: 0, endAngle: CGFloat.pi / 2, clockwise: false)
- //底左
- path.addArc(center: CGPoint(x: bottomLeftCenterX, y: bottomLeftCenterY), radius: cornerRadii.bottomLeft, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi, clockwise: false)
- path.closeSubpath();
- return path;
- }
-
- }
- // MARK: - UIView的一些其他方法
- public extension UIView {
-
- // MARK: - 键盘收起来
- /// 键盘收起来
- func keyboardEndEditing() {
- self.endEditing(true)
- }
-
- // MARK: 将 View 转换成图片
- /// 将 View 转换成图片
- /// - Returns: 图片
- func toImage() -> UIImage {
- return UIGraphicsImageRenderer(size: self.frame.size).image { context in
- self.layer.render(in: context.cgContext)
- }
- }
- }
- // MARK: - Toast吐司🍞
- extension UIView {
-
- // MARK: 普通消息
- func toast(text: String) {
-
- var style = ToastStyle()
- style.messageFont = .textF(14)
- style.backgroundColor = UIColor.hexStringColor(hexString: "#000000", alpha: 0.85)
- style.cornerRadius = 8
- style.verticalPadding = 14
- style.horizontalPadding = 44
- self.makeToast(text, duration: 1.5, position: .center, style: style)
- }
- }
|