CornerDesignable.swift 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. //
  2. // Created by Jake Lin on 12/1/15.
  3. // Copyright © 2015 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. public protocol CornerDesignable: class {
  7. /**
  8. `border-radius`
  9. */
  10. var cornerRadius: CGFloat { get set }
  11. /**
  12. corner side: Top Left, Top Right, Bottom Left or Bottom Right, if not specified, all corner sides will display,
  13. */
  14. var cornerSides: CornerSides { get set }
  15. }
  16. // MARK: - UIView
  17. public extension CornerDesignable where Self: UIView {
  18. func configureCornerRadius() {
  19. configureCornerRadius(in: self)
  20. }
  21. }
  22. // MARK: - UICollectionViewCell
  23. public extension CornerDesignable where Self: UICollectionViewCell {
  24. func configureCornerRadius() {
  25. if !cornerRadius.isNaN && cornerRadius > 0 {
  26. // Remove any previous corner mask, i.e. coming from UIView type implementation
  27. if layer.mask?.name == "cornerSideLayer" {
  28. layer.mask?.removeFromSuperlayer()
  29. }
  30. layer.cornerRadius = 0.0
  31. applyCorner(in: contentView)
  32. contentView.layer.masksToBounds = true
  33. } else {
  34. contentView.layer.masksToBounds = false
  35. }
  36. }
  37. }
  38. // MARK: - Common
  39. extension CornerDesignable {
  40. func configureCornerRadius(in view: UIView) {
  41. guard !cornerRadius.isNaN && cornerRadius > 0 else {
  42. return
  43. }
  44. applyCorner(in: view)
  45. }
  46. private func applyCorner(in view: UIView) {
  47. if cornerSides == .allSides {
  48. view.layer.cornerRadius = cornerRadius
  49. } else {
  50. view.layer.cornerRadius = 0.0
  51. // if a layer mask is specified, remove it
  52. view.layer.mask?.removeFromSuperlayer()
  53. view.layer.mask = cornerSidesLayer(inRect: view.bounds)
  54. }
  55. }
  56. private func cornerSidesLayer(inRect bounds: CGRect) -> CAShapeLayer {
  57. let cornerSideLayer = CAShapeLayer()
  58. cornerSideLayer.name = "cornerSideLayer"
  59. cornerSideLayer.frame = CGRect(origin: .zero, size: bounds.size)
  60. let cornerRadii = CGSize(width: cornerRadius, height: cornerRadius)
  61. let roundingCorners: UIRectCorner = cornerSides.rectCorner
  62. cornerSideLayer.path = UIBezierPath(roundedRect: bounds,
  63. byRoundingCorners: roundingCorners,
  64. cornerRadii: cornerRadii).cgPath
  65. return cornerSideLayer
  66. }
  67. }