| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685 |
- //
- // Popover.swift
- // Popover
- //
- // Created by corin8823 on 8/16/15.
- // Copyright (c) 2015 corin8823. All rights reserved.
- //
- import Foundation
- import UIKit
- public enum PopoverOption {
- case arrowSize(CGSize)
- case animationIn(TimeInterval)
- case animationOut(TimeInterval)
- case cornerRadius(CGFloat)
- case sideEdge(CGFloat)
- case blackOverlayColor(UIColor)
- case overlayBlur(UIBlurEffect.Style)
- case type(PopoverType)
- case color(UIColor)
- case dismissOnBlackOverlayTap(Bool)
- case showBlackOverlay(Bool)
- case springDamping(CGFloat)
- case initialSpringVelocity(CGFloat)
- case sideOffset(CGFloat)
- case borderColor(UIColor)
- }
- @objc public enum PopoverType: Int {
- case up
- case down
- case left
- case right
- case auto
- }
- @objcMembers
- open class Popover: UIView {
- // custom property
- open var arrowSize: CGSize = CGSize(width: 16.0, height: 10.0)
- open var animationIn: TimeInterval = 0.6
- open var animationOut: TimeInterval = 0.3
- open var cornerRadius: CGFloat = 6.0
- open var sideEdge: CGFloat = 20.0
- open var popoverType: PopoverType = .down
- open var blackOverlayColor: UIColor = UIColor(white: 0.0, alpha: 0.2)
- open var overlayBlur: UIBlurEffect?
- open var popoverColor: UIColor = UIColor.white
- open var dismissOnBlackOverlayTap: Bool = true
- open var showBlackOverlay: Bool = true
- open var highlightFromView: Bool = false
- open var highlightCornerRadius: CGFloat = 0
- open var springDamping: CGFloat = 0.7
- open var initialSpringVelocity: CGFloat = 3
- open var sideOffset: CGFloat = 6.0
- open var borderColor: UIColor?
- // custom closure
- open var willShowHandler: (() -> ())?
- open var willDismissHandler: (() -> ())?
- open var didShowHandler: (() -> ())?
- open var didDismissHandler: (() -> ())?
- public fileprivate(set) var blackOverlay: UIControl = UIControl()
- fileprivate var containerView: UIView!
- fileprivate var contentView: UIView!
- fileprivate var contentViewFrame: CGRect!
- fileprivate var arrowShowPoint: CGPoint!
- public init() {
- super.init(frame: .zero)
- self.backgroundColor = .clear
- self.accessibilityViewIsModal = true
- }
- public init(showHandler: (() -> ())?, dismissHandler: (() -> ())?) {
- super.init(frame: .zero)
- self.backgroundColor = .clear
- self.didShowHandler = showHandler
- self.didDismissHandler = dismissHandler
- self.accessibilityViewIsModal = true
- }
- public init(options: [PopoverOption]?, showHandler: (() -> ())? = nil, dismissHandler: (() -> ())? = nil) {
- super.init(frame: .zero)
- self.backgroundColor = .clear
- self.setOptions(options)
- self.didShowHandler = showHandler
- self.didDismissHandler = dismissHandler
- self.accessibilityViewIsModal = true
- }
- required public init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override open func layoutSubviews() {
- super.layoutSubviews()
- self.contentView.frame = self.bounds
- }
- open func showAsDialog(_ contentView: UIView) {
- guard let rootView = UIApplication.shared.keyWindow else {
- return
- }
- self.showAsDialog(contentView, inView: rootView)
- }
- open func showAsDialog(_ contentView: UIView, inView: UIView) {
- self.arrowSize = .zero
- let point = CGPoint(x: inView.center.x,
- y: inView.center.y - contentView.frame.height / 2)
- self.show(contentView, point: point, inView: inView)
- }
- open func show(_ contentView: UIView, fromView: UIView) {
- guard let rootView = UIApplication.shared.keyWindow else {
- return
- }
- self.show(contentView, fromView: fromView, inView: rootView)
- }
- open func show(_ contentView: UIView, fromView: UIView, inView: UIView) {
- let point: CGPoint
-
- //TODO: add left/right auto
- if self.popoverType == .auto {
- if let point = fromView.superview?.convert(fromView.frame.origin, to: nil),
- point.y + fromView.frame.height + self.arrowSize.height + contentView.frame.height > inView.frame.height {
- self.popoverType = .up
- } else {
- self.popoverType = .down
- }
- }
-
- switch self.popoverType {
- case .up:
- point = inView.convert(
- CGPoint(
- x: fromView.frame.origin.x + (fromView.frame.size.width / 2),
- y: fromView.frame.origin.y
- ), from: fromView.superview)
- case .down, .auto:
- point = inView.convert(
- CGPoint(
- x: fromView.frame.origin.x + (fromView.frame.size.width / 2),
- y: fromView.frame.origin.y + fromView.frame.size.height
- ), from: fromView.superview)
- case .left:
- point = inView.convert(
- CGPoint(x: fromView.frame.origin.x - sideOffset,
- y: fromView.frame.origin.y + 0.5 * fromView.frame.height
- ), from: fromView.superview)
- case .right:
- point = inView.convert(
- CGPoint(x: fromView.frame.origin.x + fromView.frame.size.width + sideOffset,
- y: fromView.frame.origin.y + 0.5 * fromView.frame.height
- ), from: fromView.superview)
- }
- if self.highlightFromView {
- self.createHighlightLayer(fromView: fromView, inView: inView)
- }
- self.show(contentView, point: point, inView: inView)
- }
- open func show(_ contentView: UIView, point: CGPoint) {
- guard let rootView = UIApplication.shared.keyWindow else {
- return
- }
- self.show(contentView, point: point, inView: rootView)
- }
- open func show(_ contentView: UIView, point: CGPoint, inView: UIView) {
- if self.dismissOnBlackOverlayTap || self.showBlackOverlay {
- self.blackOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
- self.blackOverlay.frame = inView.bounds
- inView.addSubview(self.blackOverlay)
- if showBlackOverlay {
- if let overlayBlur = self.overlayBlur {
- let effectView = UIVisualEffectView(effect: overlayBlur)
- effectView.frame = self.blackOverlay.bounds
- effectView.isUserInteractionEnabled = false
- self.blackOverlay.addSubview(effectView)
- } else {
- if !self.highlightFromView {
- self.blackOverlay.backgroundColor = self.blackOverlayColor
- }
- self.blackOverlay.alpha = 0
- }
- }
- if self.dismissOnBlackOverlayTap {
- self.blackOverlay.addTarget(self, action: #selector(Popover.dismiss), for: .touchUpInside)
- }
- }
-
- self.containerView = inView
- self.contentView = contentView
- self.contentView.backgroundColor = UIColor.clear
- self.contentView.layer.cornerRadius = self.cornerRadius
- self.contentView.layer.masksToBounds = true
- self.arrowShowPoint = point
- self.show()
- }
- open override func accessibilityPerformEscape() -> Bool {
- self.dismiss()
- return true
- }
- @objc open func dismiss() {
- if self.superview != nil {
- self.willDismissHandler?()
- UIView.animate(withDuration: self.animationOut, delay: 0,
- options: UIView.AnimationOptions(),
- animations: {
- self.transform = CGAffineTransform(scaleX: 0.0001, y: 0.0001)
- self.blackOverlay.alpha = 0
- }){ _ in
- self.contentView.removeFromSuperview()
- self.blackOverlay.removeFromSuperview()
- self.removeFromSuperview()
- self.transform = CGAffineTransform.identity
- self.didDismissHandler?()
- }
- }
- }
- override open func draw(_ rect: CGRect) {
- super.draw(rect)
- let arrow = UIBezierPath()
- let color = self.popoverColor
- let arrowPoint = self.containerView.convert(self.arrowShowPoint, to: self)
- switch self.popoverType {
- case .up:
- arrow.move(to: CGPoint(x: arrowPoint.x, y: self.bounds.height))
- arrow.addLine(
- to: CGPoint(
- x: arrowPoint.x - self.arrowSize.width * 0.5,
- y: self.isCornerLeftArrow ? self.arrowSize.height : self.bounds.height - self.arrowSize.height
- )
- )
- arrow.addLine(to: CGPoint(x: self.cornerRadius, y: self.bounds.height - self.arrowSize.height))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.cornerRadius,
- y: self.bounds.height - self.arrowSize.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(90),
- endAngle: self.radians(180),
- clockwise: true)
- arrow.addLine(to: CGPoint(x: 0, y: self.cornerRadius))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.cornerRadius,
- y: self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(180),
- endAngle: self.radians(270),
- clockwise: true)
- arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: 0))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.bounds.width - self.cornerRadius,
- y: self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(270),
- endAngle: self.radians(0),
- clockwise: true)
- arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height - self.arrowSize.height - self.cornerRadius))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.bounds.width - self.cornerRadius,
- y: self.bounds.height - self.arrowSize.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(0),
- endAngle: self.radians(90),
- clockwise: true)
- arrow.addLine(
- to: CGPoint(
- x: arrowPoint.x + self.arrowSize.width * 0.5,
- y: self.isCornerRightArrow ? self.arrowSize.height : self.bounds.height - self.arrowSize.height
- )
- )
- case .down, .auto:
- arrow.move(to: CGPoint(x: arrowPoint.x, y: 0))
-
- if self.isCloseToCornerRightArrow && !self.isCornerRightArrow {
- if !isBehindCornerRightArrow {
- arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height))
- arrow.addArc(
- withCenter: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height + self.cornerRadius),
- radius: self.cornerRadius,
- startAngle: self.radians(270.0),
- endAngle: self.radians(0),
- clockwise: true)
- } else {
- arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.arrowSize.height + self.cornerRadius))
- arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.arrowSize.height))
- }
- } else {
- arrow.addLine(
- to: CGPoint(
- x: self.isBehindCornerLeftArrow ? self.frame.minX - self.arrowSize.width * 0.5 : arrowPoint.x + self.arrowSize.width * 0.5,
- y: self.isCornerRightArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height
- )
- )
- arrow.addLine(to: CGPoint(x: self.bounds.width - self.cornerRadius, y: self.arrowSize.height))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.bounds.width - self.cornerRadius,
- y: self.arrowSize.height + self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(270.0),
- endAngle: self.radians(0),
- clockwise: true)
- }
-
- arrow.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height - self.cornerRadius))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.bounds.width - self.cornerRadius,
- y: self.bounds.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(0),
- endAngle: self.radians(90),
- clockwise: true)
- arrow.addLine(to: CGPoint(x: 0, y: self.bounds.height))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.cornerRadius,
- y: self.bounds.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(90),
- endAngle: self.radians(180),
- clockwise: true)
- arrow.addLine(to: CGPoint(x: 0, y: self.arrowSize.height + self.cornerRadius))
-
- if !isBehindCornerLeftArrow {
- arrow.addArc(
- withCenter: CGPoint(
- x: self.cornerRadius,
- y: self.arrowSize.height + self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(180),
- endAngle: self.radians(270),
- clockwise: true)
- }
- if isBehindCornerRightArrow {
- arrow.addLine(to: CGPoint(
- x: self.bounds.width - self.arrowSize.width * 0.5,
- y: self.isCornerLeftArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height))
- } else if isCloseToCornerLeftArrow && !isCornerLeftArrow {
- () // skipping this line in that case
- } else {
- arrow.addLine(to: CGPoint(x: arrowPoint.x - self.arrowSize.width * 0.5,
- y: self.isCornerLeftArrow ? self.arrowSize.height + self.bounds.height : self.arrowSize.height))
- }
-
- case .left:
- arrow.move(to: CGPoint(x: self.bounds.width, y: self.bounds.height * 0.5))
- arrow.addLine(
- to: CGPoint(
- x: self.bounds.width - self.arrowSize.height,
- y: self.bounds.height * 0.5 + self.arrowSize.width * 0.5
- ))
-
- arrow.addLine(to: CGPoint(x:self.bounds.width - self.arrowSize.height, y: self.bounds.height - self.cornerRadius))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.bounds.width - self.arrowSize.height - self.cornerRadius,
- y: self.bounds.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(0.0),
- endAngle: self.radians(90),
- clockwise: true)
-
- arrow.addLine(to: CGPoint(x: self.cornerRadius, y: self.bounds.height))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.cornerRadius,
- y: self.bounds.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(90),
- endAngle: self.radians(180),
- clockwise: true)
-
- arrow.addLine(to: CGPoint(x: 0, y: self.cornerRadius))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.cornerRadius,
- y: self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(180),
- endAngle: self.radians(270),
- clockwise: true)
-
- arrow.addLine(to: CGPoint(x: self.bounds.width - self.arrowSize.height - self.cornerRadius, y: 0))
- arrow.addArc(
- withCenter: CGPoint(x: self.bounds.width - self.arrowSize.height - self.cornerRadius,
- y: self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(270),
- endAngle: self.radians(0),
- clockwise: true)
-
- arrow.addLine(to: CGPoint(x: self.bounds.width - self.arrowSize.height,
- y: self.bounds.height * 0.5 - self.arrowSize.width * 0.5
- ))
- case .right:
- arrow.move(to: CGPoint(x: arrowPoint.x, y: self.bounds.height * 0.5))
- arrow.addLine(
- to: CGPoint(
- x: arrowPoint.x + self.arrowSize.height,
- y: self.bounds.height * 0.5 + 0.5 * self.arrowSize.width
- ))
-
- arrow.addLine(
- to: CGPoint(
- x: arrowPoint.x + self.arrowSize.height,
- y: self.bounds.height - self.cornerRadius
- ))
- arrow.addArc(
- withCenter: CGPoint(
- x: arrowPoint.x + self.arrowSize.height + self.cornerRadius,
- y: self.bounds.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(180.0),
- endAngle: self.radians(90),
- clockwise: false)
-
- arrow.addLine(to: CGPoint(x: self.bounds.width + arrowPoint.x - self.cornerRadius, y: self.bounds.height))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.bounds.width + arrowPoint.x - self.cornerRadius,
- y: self.bounds.height - self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(90),
- endAngle: self.radians(0),
- clockwise: false)
-
- arrow.addLine(to: CGPoint(x: self.bounds.width + arrowPoint.x, y: self.cornerRadius))
- arrow.addArc(
- withCenter: CGPoint(
- x: self.bounds.width + arrowPoint.x - self.cornerRadius,
- y: self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(0),
- endAngle: self.radians(-90),
- clockwise: false)
-
- arrow.addLine(to: CGPoint(x: arrowPoint.x + self.arrowSize.height - self.cornerRadius, y: 0))
- arrow.addArc(
- withCenter: CGPoint(x: arrowPoint.x + self.arrowSize.height + self.cornerRadius,
- y: self.cornerRadius
- ),
- radius: self.cornerRadius,
- startAngle: self.radians(-90),
- endAngle: self.radians(-180),
- clockwise: false)
-
- arrow.addLine(to: CGPoint(x: arrowPoint.x + self.arrowSize.height,
- y: self.bounds.height * 0.5 - self.arrowSize.width * 0.5))
- }
- color.setFill()
- arrow.fill()
- if let borderColor = borderColor {
- borderColor.setStroke()
- arrow.stroke()
- }
- }
- }
- private extension Popover {
- func setOptions(_ options: [PopoverOption]?){
- if let options = options {
- for option in options {
- switch option {
- case let .arrowSize(value):
- self.arrowSize = value
- case let .animationIn(value):
- self.animationIn = value
- case let .animationOut(value):
- self.animationOut = value
- case let .cornerRadius(value):
- self.cornerRadius = value
- case let .sideEdge(value):
- self.sideEdge = value
- case let .blackOverlayColor(value):
- self.blackOverlayColor = value
- case let .overlayBlur(style):
- self.overlayBlur = UIBlurEffect(style: style)
- case let .type(value):
- self.popoverType = value
- case let .color(value):
- self.popoverColor = value
- case let .dismissOnBlackOverlayTap(value):
- self.dismissOnBlackOverlayTap = value
- case let .showBlackOverlay(value):
- self.showBlackOverlay = value
- case let .springDamping(value):
- self.springDamping = value
- case let .initialSpringVelocity(value):
- self.initialSpringVelocity = value
- case let .sideOffset(value):
- self.sideOffset = value
- case let .borderColor(value):
- self.borderColor = value
- }
- }
- }
- }
- func create() {
- var frame = self.contentView.frame
-
- switch self.popoverType {
- case .up, .down, .auto:
- frame.origin.x = self.arrowShowPoint.x - frame.size.width * 0.5
- case .left, .right:
- frame.origin.y = self.arrowShowPoint.y - frame.size.height * 0.5
- }
- var sideEdge: CGFloat = 0.0
- if frame.size.width < self.containerView.frame.size.width {
- sideEdge = self.sideEdge
- }
- let outerSideEdge = frame.maxX - self.containerView.bounds.size.width
- if outerSideEdge > 0 {
- frame.origin.x -= (outerSideEdge + sideEdge)
- } else {
- if frame.minX < 0 {
- frame.origin.x += abs(frame.minX) + sideEdge
- }
- }
- self.frame = frame
- let arrowPoint = self.containerView.convert(self.arrowShowPoint, to: self)
- var anchorPoint: CGPoint
- switch self.popoverType {
- case .up:
- frame.origin.y = self.arrowShowPoint.y - frame.height - self.arrowSize.height
- anchorPoint = CGPoint(x: arrowPoint.x / frame.size.width, y: 1)
- case .down, .auto:
- frame.origin.y = self.arrowShowPoint.y
- anchorPoint = CGPoint(x: arrowPoint.x / frame.size.width, y: 0)
- case .left:
- frame.origin.x = self.arrowShowPoint.x - frame.size.width - self.arrowSize.height
- anchorPoint = CGPoint(x: 1, y: 0.5)
- case .right:
- frame.origin.x = self.arrowShowPoint.x
- anchorPoint = CGPoint(x: 0, y: 0.5)
- }
- if self.arrowSize == .zero {
- anchorPoint = CGPoint(x: 0.5, y: 0.5)
- }
- let lastAnchor = self.layer.anchorPoint
- self.layer.anchorPoint = anchorPoint
- let x = self.layer.position.x + (anchorPoint.x - lastAnchor.x) * self.layer.bounds.size.width
- let y = self.layer.position.y + (anchorPoint.y - lastAnchor.y) * self.layer.bounds.size.height
- self.layer.position = CGPoint(x: x, y: y)
- switch self.popoverType {
- case .up, .down, .auto:
- frame.size.height += self.arrowSize.height
- case .left, .right:
- frame.size.width += self.arrowSize.height
- }
-
- self.frame = frame
- }
- func createHighlightLayer(fromView: UIView, inView: UIView) {
- let path = UIBezierPath(rect: inView.bounds)
- let highlightRect = inView.convert(fromView.frame, from: fromView.superview)
- let highlightPath = UIBezierPath(roundedRect: highlightRect, cornerRadius: self.highlightCornerRadius)
- path.append(highlightPath)
- path.usesEvenOddFillRule = true
- let fillLayer = CAShapeLayer()
- fillLayer.path = path.cgPath
- fillLayer.fillRule = CAShapeLayerFillRule.evenOdd
- fillLayer.fillColor = self.blackOverlayColor.cgColor
- self.blackOverlay.layer.addSublayer(fillLayer)
- }
- func show() {
- self.setNeedsDisplay()
- switch self.popoverType {
- case .up:
- self.contentView.frame.origin.y = 0.0
- case .down, .auto:
- self.contentView.frame.origin.y = self.arrowSize.height
- case .left, .right:
- self.contentView.frame.origin.x = 0
- }
- self.addSubview(self.contentView)
- self.containerView.addSubview(self)
- self.create()
- self.transform = CGAffineTransform(scaleX: 0.0, y: 0.0)
- self.willShowHandler?()
- UIView.animate(
- withDuration: self.animationIn,
- delay: 0,
- usingSpringWithDamping: self.springDamping,
- initialSpringVelocity: self.initialSpringVelocity,
- options: UIView.AnimationOptions(),
- animations: {
- self.transform = CGAffineTransform.identity
- }){ _ in
- self.didShowHandler?()
- }
- UIView.animate(
- withDuration: self.animationIn / 3,
- delay: 0,
- options: .curveLinear,
- animations: {
- self.blackOverlay.alpha = 1
- }, completion: nil)
- }
- var isCloseToCornerLeftArrow: Bool {
- return self.arrowShowPoint.x < self.frame.origin.x + arrowSize.width/2 + cornerRadius
- }
- var isCloseToCornerRightArrow: Bool {
- return self.arrowShowPoint.x > (self.frame.origin.x + self.bounds.width) - arrowSize.width/2 - cornerRadius
- }
- var isCornerLeftArrow: Bool {
- return self.arrowShowPoint.x == self.frame.origin.x
- }
- var isCornerRightArrow: Bool {
- return self.arrowShowPoint.x == self.frame.origin.x + self.bounds.width
- }
-
- var isBehindCornerLeftArrow: Bool {
- return self.arrowShowPoint.x < self.frame.origin.x
- }
- var isBehindCornerRightArrow: Bool {
- return self.arrowShowPoint.x > self.frame.origin.x + self.bounds.width
- }
- func radians(_ degrees: CGFloat) -> CGFloat {
- return CGFloat.pi * degrees / 180
- }
- }
|