348 lines
11 KiB
Swift
348 lines
11 KiB
Swift
//
|
||
// UIView+extension.swift
|
||
// Pubquiz
|
||
//
|
||
// Created by crow on 2018/6/4.
|
||
// Copyright © 2018年 xhy. All rights reserved.
|
||
//
|
||
|
||
import Foundation
|
||
import UIKit
|
||
|
||
public extension UIView {
|
||
|
||
/// 设置边框和圆角
|
||
/// - Parameters:
|
||
/// - radius: 圆角大学
|
||
/// - color: 边框颜色,默认clear
|
||
/// - borderWidth: 边框线条宽度,默认0.5
|
||
func setCornerRadius(_ radius: CGFloat,
|
||
color: UIColor = .clear,
|
||
borderWidth: CGFloat = 0.5) {
|
||
layer.masksToBounds = true
|
||
layer.cornerRadius = radius
|
||
layer.borderColor = color.cgColor
|
||
layer.borderWidth = borderWidth
|
||
}
|
||
|
||
/// 自定义边角圆角,UIView确定frame后在设置
|
||
/// - Parameters:
|
||
/// - corners: [.topLeft, .topRight, .bottomLeft, .bottomRight]
|
||
/// - size: 圆角大小
|
||
func setCornerRadius(_ rect: CGRect = .zero,
|
||
corners: UIRectCorner,
|
||
withCornerRadii size: CGSize) {
|
||
// 圆角位置
|
||
let roundedRect = rect == .zero ? bounds : rect
|
||
let maskPath = UIBezierPath(roundedRect: roundedRect,
|
||
byRoundingCorners: corners,
|
||
cornerRadii: size)
|
||
// 圆角大小
|
||
let maskLayer = CAShapeLayer()
|
||
maskLayer.frame = roundedRect
|
||
maskLayer.path = maskPath.cgPath
|
||
layer.mask = maskLayer
|
||
}
|
||
|
||
/// 设置阴影
|
||
func setShadow(offset: CGSize, opacity: Float, radius: CGFloat, color: UIColor) {
|
||
self.layer.shadowColor = color.cgColor
|
||
self.layer.shadowOpacity = opacity
|
||
self.layer.shadowRadius = radius
|
||
self.layer.shadowOffset = offset
|
||
}
|
||
|
||
/// 设置默认黑色阴影
|
||
func addCommonShadow() {
|
||
setShadow(offset: .zero,
|
||
opacity: 0.1,
|
||
radius: 3,
|
||
color: UIColor.black.withAlphaComponent(0.2))
|
||
}
|
||
|
||
/// 设置视图外边距
|
||
/// - Parameters:
|
||
/// - superView: 父视图
|
||
/// - insets: UIEdgeInsets
|
||
@objc
|
||
func addAndConstraintTo(superView: UIView,
|
||
insets: UIEdgeInsets = .zero) {
|
||
self.translatesAutoresizingMaskIntoConstraints = false
|
||
superView.addSubview(self)
|
||
self.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: insets.left).isActive = true
|
||
self.topAnchor.constraint(equalTo: superView.topAnchor, constant: insets.top).isActive = true
|
||
self.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: insets.right).isActive = true
|
||
self.bottomAnchor.constraint(equalTo: superView.bottomAnchor, constant: insets.bottom).isActive = true
|
||
superView.layoutIfNeeded()
|
||
}
|
||
|
||
static func removeExtraLineForTable(_ tableView: UITableView) {
|
||
let view = UIView()
|
||
tableView.tableFooterView = view
|
||
}
|
||
|
||
/// 设置渐变色
|
||
/// - Parameters:
|
||
/// - frame: frame
|
||
/// - startPoint: 开始点
|
||
/// - endPoint: 结束点
|
||
/// - colors: 颜色
|
||
/// - locations: 位置
|
||
func setGradientLayer(frame: CGRect,
|
||
startPoint: CGPoint,
|
||
endPoint: CGPoint,
|
||
colors: [UIColor],
|
||
locations: [CGFloat]) {
|
||
if let sublayers = self.layer.sublayers {
|
||
for layer in sublayers {
|
||
if layer.name == "Defalut_GradientLayer" {
|
||
layer.removeFromSuperlayer()
|
||
break
|
||
}
|
||
}
|
||
}
|
||
let gradientLayer = CAGradientLayer()
|
||
gradientLayer.name = "Defalut_GradientLayer"
|
||
gradientLayer.frame = frame
|
||
gradientLayer.startPoint = startPoint
|
||
gradientLayer.endPoint = endPoint
|
||
gradientLayer.colors = colors.compactMap { $0.cgColor }
|
||
gradientLayer.locations = locations.compactMap { NSNumber(value: $0) }
|
||
// layer.addSublayer(gradientLayer)
|
||
if let firstSublayer = layer.sublayers?.first {
|
||
layer.insertSublayer(gradientLayer, below: firstSublayer)
|
||
} else {
|
||
layer.addSublayer(gradientLayer)
|
||
}
|
||
}
|
||
}
|
||
|
||
public extension UIView {
|
||
|
||
/// 添加缩放动画
|
||
/// - Parameters:
|
||
/// - duration: 动画时间
|
||
/// - usingSpringWithDamping: TimeInterval
|
||
/// - initialSpringVelocity: CGFloat
|
||
func affineTransformScale(duration: TimeInterval,
|
||
usingSpringWithDamping: TimeInterval,
|
||
initialSpringVelocity: CGFloat) {
|
||
self.layer.setAffineTransform(CGAffineTransform(scaleX: 0.1, y: 0.1))
|
||
|
||
UIView.animate(withDuration: duration, delay: 0.01, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options:UIView.AnimationOptions.overrideInheritedOptions, animations: { () -> Void in
|
||
self.layer.setAffineTransform(CGAffineTransform(scaleX: 1, y: 1))
|
||
}) { finished in
|
||
UIView.animate(withDuration: 0.08, animations:{ ()-> Void in
|
||
self.layer.setAffineTransform(.identity)
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - IBDesignable
|
||
@IBDesignable extension UIView {
|
||
@IBInspectable public var borderColor:UIColor? {
|
||
set {
|
||
layer.borderColor = newValue!.cgColor
|
||
}
|
||
get {
|
||
if let color = layer.borderColor {
|
||
return UIColor(cgColor:color)
|
||
}
|
||
else {
|
||
return nil
|
||
}
|
||
}
|
||
}
|
||
@IBInspectable public var borderWidth:CGFloat {
|
||
set {
|
||
layer.borderWidth = newValue
|
||
}
|
||
get {
|
||
return layer.borderWidth
|
||
}
|
||
}
|
||
@IBInspectable public var cornerRadius:CGFloat {
|
||
set {
|
||
layer.cornerRadius = newValue
|
||
clipsToBounds = newValue > 0
|
||
}
|
||
get {
|
||
return layer.cornerRadius
|
||
}
|
||
}
|
||
@IBInspectable public var shadowOffset: CGSize {
|
||
set {
|
||
layer.shadowOffset = newValue
|
||
}
|
||
get {
|
||
return layer.shadowOffset
|
||
}
|
||
}
|
||
@IBInspectable public var shadowOpacity: Float {
|
||
set {
|
||
layer.shadowOpacity = newValue
|
||
}
|
||
get {
|
||
return layer.shadowOpacity
|
||
}
|
||
}
|
||
@IBInspectable public var shadowRadius: CGFloat {
|
||
set {
|
||
layer.shadowRadius = newValue
|
||
}
|
||
get {
|
||
return layer.shadowRadius
|
||
}
|
||
}
|
||
@IBInspectable public var shadowColor: UIColor? {
|
||
set {
|
||
layer.shadowColor = newValue?.cgColor
|
||
}
|
||
get {
|
||
if let color = layer.shadowColor {
|
||
return UIColor(cgColor:color)
|
||
}
|
||
else {
|
||
return nil
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - Frame
|
||
public extension DLWrapper where Base: UIView {
|
||
|
||
var height: CGFloat {
|
||
set {
|
||
var newframe = base.frame
|
||
newframe.size.height = newValue
|
||
base.frame = newframe
|
||
}
|
||
|
||
get { base.frame.size.height }
|
||
}
|
||
|
||
var width: CGFloat {
|
||
set {
|
||
var newframe = base.frame
|
||
newframe.size.width = newValue
|
||
base.frame = newframe
|
||
}
|
||
|
||
get { base.frame.size.width }
|
||
}
|
||
|
||
var x: CGFloat {
|
||
set {
|
||
var newframe = base.frame
|
||
newframe.origin.x = newValue
|
||
base.frame = newframe
|
||
}
|
||
|
||
get { base.frame.origin.x }
|
||
}
|
||
|
||
var y: CGFloat {
|
||
set {
|
||
var newframe = base.frame
|
||
newframe.origin.y = newValue
|
||
base.frame = newframe
|
||
}
|
||
|
||
get { base.frame.origin.y }
|
||
}
|
||
|
||
var size: CGSize {
|
||
set {
|
||
var newframe = base.frame
|
||
newframe.size = newValue
|
||
base.frame = newframe
|
||
}
|
||
|
||
get { base.frame.size }
|
||
}
|
||
|
||
var origin: CGPoint {
|
||
set {
|
||
var newframe = base.frame
|
||
newframe.origin = newValue
|
||
base.frame = newframe
|
||
}
|
||
|
||
get { base.frame.origin }
|
||
}
|
||
}
|
||
|
||
extension UIView {
|
||
|
||
func findSubView(with tag: Int) -> UIView? {
|
||
subviews.first(where: { $0.tag == tag })
|
||
}
|
||
}
|
||
|
||
// MARK: - 生成二维码图片
|
||
extension UIView {
|
||
func generateQRCodeImage(_ content: String, size: CGSize) -> UIImage? {
|
||
// 创建滤镜
|
||
guard let filter = CIFilter(name: "CIQRCodeGenerator") else {return nil}
|
||
// 还原滤镜的默认属性
|
||
filter.setDefaults()
|
||
// 设置需要生成的二维码数据
|
||
let contentData = content.data(using: String.Encoding.utf8)
|
||
filter.setValue(contentData, forKey: "inputMessage")
|
||
// 从滤镜中取出生成的图片
|
||
guard let ciImage = filter.outputImage else { return nil }
|
||
|
||
let context = CIContext(options: nil)
|
||
let bitmapImage = context.createCGImage(ciImage, from: ciImage.extent)
|
||
|
||
let colorSpace = CGColorSpaceCreateDeviceGray()
|
||
let bitmapContext = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.none.rawValue)
|
||
|
||
//draw image
|
||
let scale = min(size.width / ciImage.extent.width, size.height / ciImage.extent.height)
|
||
bitmapContext!.interpolationQuality = CGInterpolationQuality.none
|
||
bitmapContext?.scaleBy(x: scale, y: scale)
|
||
bitmapContext?.draw(bitmapImage!, in: ciImage.extent)
|
||
|
||
//保存bitmap到图片
|
||
guard let scaledImage = bitmapContext?.makeImage() else { return nil }
|
||
|
||
return UIImage(cgImage: scaledImage)
|
||
}
|
||
}
|
||
|
||
// MARK: - 截图
|
||
extension UIView {
|
||
func takeScreenshot() -> UIImage? {
|
||
let renderer = UIGraphicsImageRenderer(bounds: bounds)
|
||
return renderer.image { context in
|
||
layer.render(in: context.cgContext)
|
||
}
|
||
}
|
||
}
|
||
|
||
extension UIView {
|
||
func stringPrefix(index: Int, text: String) -> String {
|
||
if text.count <= index {
|
||
return text
|
||
} else {
|
||
let index = text.index(text.startIndex, offsetBy: index)
|
||
let str = text.prefix(upTo: index)
|
||
return String(str)
|
||
}
|
||
}
|
||
}
|
||
|
||
// MARK: - 时间戳
|
||
extension UIView {
|
||
func getDateInterval2String(date: String) -> String {
|
||
let date = Date(timeIntervalSince1970: TimeInterval(date.double))
|
||
let dateFormatter = DateFormatter()
|
||
dateFormatter.dateFormat = "yyyy.MM.dd HH:mm:ss"
|
||
let dateString = dateFormatter.string(from: date)
|
||
return dateString
|
||
}
|
||
}
|