MaterialShowcase+Calculations.swift 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. //
  2. // MaterialShowcase+Calculations.swift
  3. // MaterialShowcase
  4. //
  5. // Created by Andrei Tulai on 2017-11-16.
  6. // Copyright © 2017 Aromajoin. All rights reserved.
  7. //
  8. import Foundation
  9. import UIKit
  10. extension MaterialShowcase {
  11. func isInGutter(center: CGPoint) -> Bool {
  12. return center.y < offsetThreshold || containerView.frame.height - center.y < offsetThreshold
  13. }
  14. func getOuterCircleCenterPoint(for target: UIView) -> CGPoint {
  15. if isInGutter(center: target.center) {
  16. return target.center
  17. }
  18. let targetRadius = max(target.frame.width, target.frame.height) / 2 + TARGET_PADDING
  19. let totalTextHeight = instructionView.frame.height
  20. let onTop = getTargetPosition(target: targetView, container: containerView) == .below
  21. let left = min(instructionView.frame.minX, target.frame.minX - targetRadius)
  22. let right = max(instructionView.frame.maxX, target.frame.maxX + targetRadius)
  23. let titleHeight = instructionView.primaryLabel.frame.height
  24. let centerY = onTop ? target.center.y - TARGET_HOLDER_RADIUS - TARGET_PADDING - totalTextHeight + titleHeight
  25. : target.center.y + TARGET_HOLDER_RADIUS + TARGET_PADDING + titleHeight
  26. return CGPoint(x: (left + right) / 2, y: centerY)
  27. }
  28. func getOuterCircleRadius(center: CGPoint, textBounds: CGRect, targetBounds: CGRect) -> CGFloat {
  29. let targetCenterX = targetBounds.midX
  30. let targetCenterY = targetBounds.midY
  31. let expandedRadius = 1.1 * TARGET_HOLDER_RADIUS
  32. var expandedBounds = CGRect(x: targetCenterX, y: targetCenterY, width: 0, height: 0)
  33. expandedBounds = expandedBounds.insetBy(dx: -expandedRadius, dy: -expandedRadius);
  34. let textRadius = maxDistance(from: center, to: textBounds)
  35. let targetRadius = maxDistance(from: center, to: expandedBounds)
  36. return max(textRadius, targetRadius) + 40
  37. }
  38. func maxDistance(from point: CGPoint, to rect: CGRect) -> CGFloat {
  39. let tl = distance(point, CGPoint(x: rect.minX, y: rect.minY))
  40. let tr = distance(point, CGPoint(x: rect.maxX, y: rect.minY))
  41. let bl = distance(point, CGPoint(x: rect.minX, y: rect.maxY))
  42. let br = distance(point, CGPoint(x: rect.maxX, y: rect.maxY))
  43. return max(tl, max(tr, max(bl, br)))
  44. }
  45. func distance(_ a: CGPoint, _ b: CGPoint) -> CGFloat {
  46. let xDist = a.x - b.x
  47. let yDist = a.y - b.y
  48. return CGFloat(sqrt((xDist * xDist) + (yDist * yDist)))
  49. }
  50. }