Files
2024-09-19 05:09:10 +03:00

325 lines
8.8 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// DesignTest.swift
// FigmaConvertXib
//
// Created by Рустам Мотыгуллин on 28.07.2020.
// Copyright © 2020 mrusta. All rights reserved.
//
import UIKit
@IBDesignable
class DesignFillView_: UIView {
@IBInspectable var cornerRadius: CGFloat = 0.0
//MARK: Blur
@IBInspectable var blur: CGFloat = 0.0
//MARK: Image
@IBInspectable var image: UIImage?
@IBInspectable var imageMode: Int = 1 /// Scale to fill / Aspect fit / fill
//MARK: Fill
@IBInspectable var fillColor: UIColor?
//MARK: Border
@IBInspectable var brColor: UIColor = .clear
@IBInspectable var brWidth: CGFloat = 0.0
@IBInspectable var brDash: Int = 0
@IBInspectable var shColor: UIColor = .clear
@IBInspectable var shRadius: CGFloat = 0.0
@IBInspectable var shOffset: CGSize = .zero
//MARK: - Draw
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let bezier = figurePath(bounds) else { return }
addFill(bezier: bezier)
addImage(bezier: bezier)
addBorder()
addShadow()
addBlur()
}
//MARK: - Figure Type
private func figurePath(_ rect: CGRect) -> UIBezierPath? {
return rectangle(rect: rect, radius: cornerRadius)
}
private func addImage(bezier: UIBezierPath) {
guard let image = image else { return }
guard let context = UIGraphicsGetCurrentContext() else { return }
var f: CGRect = CGRect(x: 0, y: -bounds.height, width: bounds.width, height: bounds.height)
if imageMode == 1 || imageMode == 2 {
var w: CGFloat = 0
var h: CGFloat = 0
let percent = bounds.height / image.size.height
w = image.size.width * percent
h = bounds.height
if (imageMode == 1) && (w > bounds.width) ||
(imageMode == 2) && (bounds.width > w) {
let percent = bounds.width / image.size.width
h = image.size.height * percent
w = bounds.width
}
let x = (bounds.width / 2) - (w / 2)
let y = (-h + (((bounds.height / 2) - (h / 2)) * (-1)))
f = CGRect(x: x, y: y, width: w, height: h)
}
context.saveGState()
bezier.addClip()
context.scaleBy(x: 1, y: -1)
context.draw(image.cgImage!, in: f, byTiling: false)
context.restoreGState()
}
//MARK: - Fill
private func addFill(bezier: UIBezierPath) {
guard let fillColor = fillColor else { return }
guard let context = UIGraphicsGetCurrentContext() else { return }
bezier.close()
context.saveGState()
fillColor.setFill()
bezier.fill()
context.restoreGState()
}
//MARK: - Shadow
private func addShadow() {
if shRadius < 0 { shRadius = 0 }
layer.shadowOffset = shOffset
layer.shadowOpacity = 1.0
layer.shadowRadius = shRadius
layer.shadowColor = shColor.cgColor
}
// MARK: - Border / Stroke
private func addBorder() {
if brWidth < 0 { brWidth = 0 }
guard let context = UIGraphicsGetCurrentContext() else { return }
// brColor.setStroke()
guard let bezier = figurePath(bounds) else { return }
context.saveGState()
if brDash > 0 {
UIColor.clear.setFill()
bezier.fill()
brColor.setStroke()
bezier.lineWidth = brWidth * 2
let dashPattern : [CGFloat] = [ CGFloat(brDash), CGFloat(brDash)]
bezier.setLineDash(dashPattern, count: 2, phase: 0)
bezier.stroke()
} else {
brColor.setStroke()
bezier.lineWidth = brWidth * 2
bezier.stroke()
}
bezier.stroke()
bezier.stroke()
context.restoreGState()
context.restoreGState()
}
// MARK: - Blur
private func addBlur() {
guard blur > 0 else { return }
guard let image = screenShotContext() else { return }
self.addblur(screen: image, blur: blur)
}
// MARK: Screen Shot Context
private func screenShotContext() -> UIImage? {
guard let context = UIGraphicsGetCurrentContext() else { return nil }
guard let cgimage: CGImage = context.makeImage() else { return nil }
let image = UIImage(cgImage: cgimage)
return image
}
// MARK: Clear Context
private func clearContext() {
let f = CGRect(x: 0, y: 0,
width: frame.width * 2,
height: frame.height * 2)
let context = UIGraphicsGetCurrentContext()
context?.clear(f)
}
private func addblur(screen: UIImage, blur: CGFloat) {
clearContext()
func blurImage(image: UIImage) -> UIImage? {
guard let ciscreen: CIImage = CIImage(image: screen) else { return nil }
guard let filter: CIFilter = CIFilter(name: "CIGaussianBlur") else { return nil }
filter.setDefaults()
filter.setValue(ciscreen, forKey: kCIInputImageKey)
filter.setValue(blur, forKey: kCIInputRadiusKey)
let bl2 = ((blur * 3) * -1)
let bl4 = (blur * 6)
let contextFrame = CGRect(
x: bl2,
y: bl2,
width: bl4 + image.size.width,
height: bl4 + image.size.height
)
// let bl2 = ((blur * 2) * -1)
// let bl4 = (blur * 4)
// let contextFrame2 = CGRect(x: bl2,
// y: bl2,
// width: bl4 + (frame.width * 2),
// height: bl4 + (frame.height * 2))
let ciContext = CIContext(options: nil)
guard let ci: CIImage = filter.value(forKey: kCIOutputImageKey) as? CIImage else { return nil }
guard let cImg = ciContext.createCGImage(ci, from: contextFrame) else { return nil }
let finalImage = UIImage(cgImage: cImg)
return finalImage
}
let p2: CGFloat = 1
let p4: CGFloat = p2 * 2
let bl2 = ((blur * p2) * -1)
let bl4 = (blur * p4)
let x: CGFloat = 0
let ofW = (x * 1) * -1
let ofH = (x * 1) * -1
let ofW2 = (x * 2)
let ofH2 = (x * 2)
let contextFrame = CGRect(x: bl2 + ofW,
y: bl2 + ofH,
width: bl4 + ofW2 + frame.width,
height: bl4 + ofH2 + frame.height)
let blurImageView = UIImageView(frame: contextFrame)
blurImageView.image = blurImage(image: screen)
blurImageView.contentMode = .scaleAspectFill
addSubview(blurImageView)
}
//MARK: - Rectangle Bezier
func rectangle(rect: CGRect, radius: CGFloat) -> UIBezierPath {
let r = self.cornerRadius(radius)
let w = rect.width
let h = rect.height
let path = UIBezierPath()
path.move(to: CGPoint(x: r, y: 0.0))
path.addLine(to: CGPoint(x: w - r, y: 0.0))
path.addArc(withCenter: CGPoint(x: w - r, y: r),
radius: r,
startAngle: 3.0 * .pi / 2.0,
endAngle: 2 * .pi,
clockwise: true)
path.addLine(to: CGPoint(x: w, y: h - r))
path.addArc(withCenter: CGPoint(x: w - r, y: h - r),
radius: r,
startAngle: 0.0,
endAngle: .pi / 2.0,
clockwise: true)
path.addLine(to: CGPoint(x: r, y: h))
path.addArc(withCenter: CGPoint(x: r, y: h - r),
radius: r,
startAngle: .pi / 2.0,
endAngle: .pi,
clockwise: true)
path.addLine(to: CGPoint(x: 0.0, y: r))
path.addArc(withCenter: CGPoint(x: r, y: r),
radius: r,
startAngle: .pi,
endAngle: 3.0 * .pi / 2.0,
clockwise: true)
path.close()
return path
}
}