import Foundation import UIKit extension UIView { @IBInspectable var cornerRadius: CGFloat { get { return layer.cornerRadius } set { layer.cornerRadius = newValue } } @IBInspectable var borderWidth: CGFloat { get { return layer.borderWidth } set { layer.borderWidth = newValue } } @IBInspectable var borderColor: UIColor? { get { if let color = layer.borderColor { return UIColor(cgColor: color) } return nil } set { if let color = newValue { layer.borderColor = color.cgColor } else { layer.borderColor = nil } } } @IBInspectable var shadowRadius: CGFloat { get { return layer.shadowRadius } set { layer.shadowRadius = newValue } } @IBInspectable var shadowOpacity: Float { get { return layer.shadowOpacity } set { layer.shadowOpacity = newValue } } @IBInspectable var shadowOffset: CGSize { get { return layer.shadowOffset } set { layer.shadowOffset = newValue } } @IBInspectable var shadowColor: UIColor? { get { if let color = layer.shadowColor { return UIColor(cgColor: color) } return nil } set { if let color = newValue { layer.shadowColor = color.cgColor } else { layer.shadowColor = nil } } } @IBInspectable var bothTopBorderMask:Bool { get{ return self.bothTopBorderMask } set{ if newValue{ if #available(iOS 11.0, *) { self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] } else { // Fallback on earlier versions } } } } @IBInspectable var bothTopLeftBottomRightBorderMask:Bool { get{ return bothTopBorderMask } set{ if newValue{ if #available(iOS 11.0, *) { self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMaxYCorner] } else { // Fallback on earlier versions } } } } func copyView() -> AnyObject{ return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! as AnyObject } func clearConstraints() { for subview in self.subviews { subview.clearConstraints() } self.removeConstraints(self.constraints) } func addDashedLine(color: UIColor = UIColor(red: 207/255.0, green: 207/255.0, blue: 207/255.0, alpha: 0.5)) { let _ = layer.sublayers?.filter({ $0.name == "DashedTopLine" }).map({ $0.removeFromSuperlayer() }) self.backgroundColor = UIColor.clear let cgColor = color.cgColor let shapeLayer: CAShapeLayer = CAShapeLayer() let shapeRect = CGRect(x: 0, y: 0, width: 0, height: 0) shapeLayer.name = "DashedTopLine" shapeLayer.bounds = shapeRect shapeLayer.position = CGPoint(x: 0, y: 0) shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.strokeColor = cgColor shapeLayer.lineWidth = 2 shapeLayer.lineJoin = CAShapeLayerLineJoin.round shapeLayer.lineDashPattern = [2, 2] let path: CGMutablePath = CGMutablePath() path.move(to: CGPoint(x: 0, y: 0)) path.addLine(to: CGPoint(x: self.frame.width, y: 0)) shapeLayer.path = path self.layer.addSublayer(shapeLayer) } } extension UIView { // In order to create computed properties for extensions, we need a key to // store and access the stored property fileprivate struct AssociatedObjectKeys { static var tapGestureRecognizer = "MediaViewerAssociatedObjectKey_mediaViewer" static var longPressGestureRecognizer = "MediaViewerAssociatedObjectKey_mediaViewer2" } fileprivate typealias Action = (() -> Void)? // Set our computed property type to a closure fileprivate var tapGestureRecognizerAction: Action? { set { if let newValue = newValue { // Computed properties get stored as associated objects objc_setAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } } get { let tapGestureRecognizerActionInstance = objc_getAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer) as? Action return tapGestureRecognizerActionInstance } } // This is the meat of the sauce, here we create the tap gesture recognizer and // store the closure the user passed to us in the associated object we declared above public func addTapGestureRecognizer(action: (() -> Void)?) { self.isUserInteractionEnabled = true self.tapGestureRecognizerAction = action let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture)) self.addGestureRecognizer(tapGestureRecognizer) } // Every time the user taps on the UIImageView, this function gets called, // which triggers the closure we stored @objc fileprivate func handleTapGesture(sender: UITapGestureRecognizer) { if let action = self.tapGestureRecognizerAction { action?() } else { print("no action") } } } extension UIView { // Set our computed property type to a closure fileprivate var longPressGestureRecognizerAction: Action? { set { if let newValue = newValue { // Computed properties get stored as associated objects objc_setAssociatedObject(self, &AssociatedObjectKeys.longPressGestureRecognizer, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } } get { let longPressGestureRecognizerActionInstance = objc_getAssociatedObject(self, &AssociatedObjectKeys.longPressGestureRecognizer) as? Action return longPressGestureRecognizerActionInstance } } // This is the meat of the sauce, here we create the tap gesture recognizer and // store the closure the user passed to us in the associated object we declared above public func addLongPressGestureRecognizer(action: (() -> Void)?) { self.isUserInteractionEnabled = true self.longPressGestureRecognizerAction = action let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleTapGesture2)) self.addGestureRecognizer(longPressGestureRecognizer) } // Every time the user taps on the UIImageView, this function gets called, // which triggers the closure we stored @objc fileprivate func handleTapGesture2(sender: UILongPressGestureRecognizer) { if let action = self.longPressGestureRecognizerAction, sender.state == .began{ action?() } else { print("no action") } } } extension UIView{ //Get Parent View Controller from any view func parentViewController() -> UIViewController { var responder: UIResponder? = self while !(responder is UIViewController) { responder = responder?.next if nil == responder { break } } return (responder as? UIViewController)! } }