CXSideButton.swift 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //
  2. // CXAlignmentButton.swift
  3. // TitleImageEdgeinsetsButton
  4. //
  5. // Created by chunxi on 2019/1/10.
  6. // Copyright © 2019 chunxi. All rights reserved.
  7. //
  8. import UIKit
  9. /// 图片和标题处于相对方向且都贴在最近的一条边上
  10. ///
  11. /// - left: 图片靠左侧边
  12. /// - right: 图片靠右侧边
  13. /// - top: 图片靠上侧边
  14. /// - bottom: 图片靠下侧边
  15. public enum ImageSideAlignment {
  16. case left(CGFloat, titleRight: CGFloat)
  17. case right(CGFloat, titleLeft: CGFloat)
  18. case top(CGFloat, titleBottom: CGFloat)
  19. case bottom(CGFloat,titleTop: CGFloat)
  20. }
  21. public class CXSideButton: UIButton {
  22. public var imageSideAlignment: ImageSideAlignment?
  23. override public func layoutSubviews() {
  24. super.layoutSubviews()
  25. if let sideAlignment = imageSideAlignment {
  26. layoutImageSideAlignment(sideAlignment)
  27. }
  28. }
  29. private func layoutImageSideAlignment(_ alignment: ImageSideAlignment) {
  30. guard contentHorizontalAlignment == .center, contentVerticalAlignment == .center else {
  31. fatalError("*** content horizon and vertical must be center")
  32. }
  33. let content = super.contentRect(forBounds: bounds)
  34. let titleSize = super.titleRect(forContentRect: content).size
  35. let imageSize = super.imageRect(forContentRect: content).size
  36. let imageAndTitleWidth = titleSize.width + imageSize.width
  37. switch alignment {
  38. case .left(let imageLeft, let titleRight):
  39. let offset = (bounds.width - imageAndTitleWidth)/2
  40. imageEdgeInsets.updateLeftAndRight(left: -offset + imageLeft)
  41. titleEdgeInsets.updateLeftAndRight(left: offset - titleRight)
  42. case .right(let imageRight, let titleLeft):
  43. let offset = (bounds.width - imageAndTitleWidth)/2
  44. imageEdgeInsets.updateLeftAndRight(left: offset + titleSize.width - imageRight)
  45. titleEdgeInsets.updateLeftAndRight(left: -offset - imageSize.width + titleLeft)
  46. case .top(let imageTop, let titleBottom):
  47. let allWidth = imageSize.width + titleSize.width
  48. let imageOffsetX = allWidth/2 - imageSize.width/2
  49. let titleOffsetX = allWidth/2 - titleSize.width/2
  50. imageEdgeInsets.updateLeftAndRight(left: imageOffsetX)
  51. titleEdgeInsets.updateLeftAndRight(left: -titleOffsetX)
  52. imageEdgeInsets.updateTopAndBottom(top: -content.height/2 + imageSize.height/2 + imageTop)
  53. titleEdgeInsets.updateTopAndBottom(top: content.height/2 - titleSize.height/2 - titleBottom)
  54. case .bottom(let imageBottom, let titleTop):
  55. let allWidth = imageSize.width + titleSize.width
  56. let imageOffsetX = allWidth/2 - imageSize.width/2
  57. let titleOffsetX = allWidth/2 - titleSize.width/2
  58. imageEdgeInsets.updateLeftAndRight(left: imageOffsetX)
  59. titleEdgeInsets.updateLeftAndRight(left: -titleOffsetX)
  60. imageEdgeInsets.updateTopAndBottom(top: content.height/2 - imageSize.height/2 - imageBottom)
  61. titleEdgeInsets.updateTopAndBottom(top: -content.height/2 + titleSize.height/2 + titleTop)
  62. }
  63. }
  64. }