HDEmptyView.swift 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. //
  2. // HDEmptyView.swift
  3. // HDEmptyViewDemo
  4. //
  5. // Created by liuyi on 2018/5/18.
  6. // Copyright © 2018年 liuyi. All rights reserved.
  7. //
  8. import UIKit
  9. import Foundation
  10. //每个子控件之间的间距
  11. let kSubViewMargin = 20.0
  12. //描述字体
  13. let kTitleLabFont = UIFont.systemFont(ofSize: 16)
  14. //详细描述字体
  15. let kDetailLabFont = UIFont.systemFont(ofSize: 14)
  16. //按钮字体大小
  17. let kActionBtnFont = UIFont.systemFont(ofSize: 14)
  18. //按钮高度
  19. let kActionBtnHeight = 40.0
  20. let kActionBtnWidth = 100.0
  21. //水平方向内边距
  22. let kActionBtnHorizontalMargin = 30.0
  23. //黑色
  24. let kBlackColor = UIColor.init(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
  25. //灰色
  26. let kGrayColor = UIColor.init(red: 0.5, green: 0.5, blue: 0.5, alpha: 1)
  27. public class HDEmptyView: HDEmptyBaseView {
  28. //提醒图片
  29. fileprivate lazy var promptImageView: UIImageView = {
  30. let promptImageView = UIImageView()
  31. promptImageView.contentMode = .scaleAspectFit
  32. return promptImageView
  33. }()
  34. //标题
  35. fileprivate lazy var titleLabel: UILabel = {
  36. let titleL = UILabel()
  37. titleL.textAlignment = .center
  38. return titleL
  39. }()
  40. //详情
  41. fileprivate lazy var detailLabel: UILabel = {
  42. let detailL = UILabel()
  43. detailL.textAlignment = .center
  44. detailL.numberOfLines = 2
  45. return detailL
  46. }()
  47. //
  48. fileprivate lazy var actionButton: UIButton = {
  49. let btn = UIButton()
  50. btn.layer.masksToBounds = true
  51. return btn
  52. }()
  53. fileprivate var contentMaxWidth: CGFloat? //最大宽度
  54. fileprivate var contentWidth: CGFloat? //内容物宽度
  55. fileprivate var contentHeight: CGFloat? //内容物高度
  56. fileprivate var subViweMargin: CGFloat? //间距
  57. //MARK: ----- 显示参数设置 ---
  58. //控件间的间距 default is 20.f
  59. public var subViewMargin: CGFloat = 20 {
  60. didSet {
  61. setupSubviews()
  62. }
  63. }
  64. //内容物-垂直方向偏移 (此属性与contentViewY 互斥,只有一个会有效)
  65. public var contentViewOffset: CGFloat = 0 {
  66. didSet {
  67. self.contentView.ly_centerY += contentViewOffset
  68. }
  69. }
  70. // 内容物-Y坐标 (此属性与contentViewOffset 互斥,只有一个会有效)
  71. public var contentViewY: CGFloat = 0 {
  72. didSet {
  73. self.contentView.ly_top = self.contentViewY
  74. }
  75. }
  76. //图片可设置固定大小 (default=图片实际大小)
  77. public var imageSize: CGSize = CGSize.zero {
  78. didSet {
  79. setupSubviews()
  80. }
  81. }
  82. //标题字体, 大小default is 16.f
  83. public var titleLabFont: UIFont = kTitleLabFont {
  84. didSet {
  85. setupSubviews()
  86. }
  87. }
  88. //标题文字颜色
  89. public var titleLabTextColor: UIColor = kBlackColor {
  90. didSet {
  91. titleLabel.textColor = titleLabTextColor
  92. }
  93. }
  94. //详细描述字体,大小default is 14.f
  95. public var detailLabFont: UIFont = kDetailLabFont {
  96. didSet {
  97. detailLabel.font = detailLabFont
  98. setupSubviews()
  99. }
  100. }
  101. // 详细描述文字颜色
  102. public var detailLabTextColor: UIColor = kGrayColor {
  103. didSet {
  104. detailLabel.textColor = detailLabTextColor
  105. }
  106. }
  107. // 详细描述最大行数, default is 2
  108. public var detailLabMaxLines: NSInteger = 2 {
  109. didSet {
  110. setupSubviews()
  111. }
  112. }
  113. //Button
  114. // 按钮字体, 大小default is 14.f
  115. public var actionBtnFont: UIFont = kActionBtnFont {
  116. didSet {
  117. actionButton.titleLabel?.font = actionBtnFont
  118. setupSubviews()
  119. }
  120. }
  121. // 按钮的高度, default is 40.f
  122. public var actionBtnHeight: CGFloat = CGFloat(kActionBtnHeight) {
  123. didSet {
  124. setupSubviews()
  125. }
  126. }
  127. public var actionBtnWidth: CGFloat = CGFloat(kActionBtnWidth) {
  128. didSet {
  129. setupSubviews()
  130. }
  131. }
  132. //水平方向内边距, default is 30.f
  133. public var actionBtnHorizontalMargin: CGFloat = CGFloat(kActionBtnHorizontalMargin) {
  134. didSet {
  135. setupSubviews()
  136. }
  137. }
  138. // 按钮的圆角大小, default is 5.f
  139. public var actionBtnCornerRadius: CGFloat = 5.0 {
  140. didSet {
  141. actionButton.layer.cornerRadius = actionBtnCornerRadius
  142. }
  143. }
  144. // 按钮边框border的宽度, default is 0
  145. public var actionBtnBorderWidth: CGFloat = 0.0 {
  146. didSet {
  147. actionButton.layer.borderWidth = actionBtnBorderWidth
  148. }
  149. }
  150. // 按钮边框颜色
  151. public var actionBtnBorderColor: UIColor = .clear {
  152. didSet {
  153. actionButton.layer.borderColor = actionBtnBorderColor.cgColor
  154. }
  155. }
  156. // 按钮文字颜色
  157. public var actionBtnTitleColor: UIColor = kBlackColor {
  158. didSet {
  159. actionButton.setTitleColor(actionBtnTitleColor, for: .normal)
  160. }
  161. }
  162. // 按钮背景颜色
  163. public var actionBtnBackGroundColor: UIColor = .clear {
  164. didSet {
  165. actionButton.backgroundColor = actionBtnBackGroundColor
  166. }
  167. }
  168. //MARK: ----- 初始化方法 ----
  169. override func prepare() {
  170. super.prepare()
  171. self.ly_centerY = 1000//默认值,用来判断是否设置过content的Y值
  172. }
  173. override func setupSubviews() {
  174. super.setupSubviews()
  175. //最大宽度(ScrollView 的宽 - 30)
  176. contentMaxWidth = self.ly_width - CGFloat(kActionBtnHorizontalMargin)
  177. contentWidth = 0
  178. contentHeight = 0
  179. subViweMargin = self.subViewMargin
  180. if self._customView == nil {
  181. //占位图
  182. let imgStr = self._imageStr == nil ? "" :self._imageStr
  183. let image = UIImage.init(named: imgStr! as String)
  184. if image != nil {
  185. self.setupPromptImageView(img: image!)
  186. }else {
  187. promptImageView.removeFromSuperview()
  188. if contentHeight == 0 {
  189. contentHeight = self.center.y
  190. }
  191. }
  192. //标题
  193. if self._titleStr != nil && (self._titleStr?.length)! > 0{
  194. self.setupTitleLabel(titleStr: self._titleStr!)
  195. }else {
  196. titleLabel.removeFromSuperview()
  197. if contentHeight == 0 {
  198. contentHeight = self.center.y
  199. }
  200. }
  201. //详细描述
  202. if self._detailStr != nil && (self._detailStr?.length)! > 0 {
  203. self.setupDetailLabel(detailStr: self._detailStr!)
  204. }else {
  205. detailLabel.removeFromSuperview()
  206. if contentHeight == 0 {
  207. contentHeight = self.center.y
  208. }
  209. }
  210. //按钮
  211. if self._btnTitleStr != nil && (self._btnTitleStr?.length)! > 0{
  212. if _target != nil {
  213. self.setupActionBtn(btnTitle: self._btnTitleStr!, target: self._target, action: self._selector, btnClickBlock: nil)
  214. }else if (_btnClickBlock != nil) {
  215. self.setupActionBtn(btnTitle: self._btnTitleStr!, target: nil, action: nil, btnClickBlock: self._btnClickBlock)
  216. }else {
  217. actionButton.removeFromSuperview()
  218. }
  219. }else {
  220. actionButton.removeFromSuperview()
  221. }
  222. }
  223. setSubViewFrame()
  224. }
  225. func setSubViewFrame() {
  226. //获取self原始宽高
  227. let scrollViewWidth = self.ly_width
  228. let scrollViewHeight = self.ly_height
  229. //重新设置self的frame(大小为content的大小)
  230. self.ly_size = CGSize.init(width: contentWidth!, height: contentHeight!)
  231. self.center = CGPoint.init(x: scrollViewWidth*0.5, y: scrollViewHeight*0.5)
  232. //设置contentView
  233. self.contentView?.frame = self.bounds
  234. //子控件的centerX设置
  235. let centerX = self.ly_centerX
  236. if self._customView != nil {
  237. self._customView?.frame = self.bounds
  238. self.contentView!.addSubview(_customView!)
  239. }else {
  240. if promptImageView.image != nil {
  241. self.contentView?.addSubview(promptImageView)
  242. }
  243. self.contentView!.addSubview(titleLabel)
  244. self.contentView!.addSubview(detailLabel)
  245. self.contentView!.addSubview(actionButton)
  246. //
  247. self.promptImageView.ly_centerX = centerX
  248. self.promptImageView.ly_centerY = self.ly_centerY
  249. self.titleLabel.ly_centerX = centerX
  250. detailLabel.ly_centerX = centerX
  251. actionButton.ly_centerX = centerX
  252. }
  253. //有无偏移
  254. if self.contentViewOffset > 0 {
  255. self.contentView.ly_centerY += self.contentViewOffset
  256. }
  257. //有无设置Y坐标
  258. if self.contentViewY < 1000 {
  259. self.contentView.ly_top = self.contentViewY
  260. }
  261. }
  262. }
  263. //MARK: ------- Setup View ------
  264. extension HDEmptyView {
  265. // ImageView
  266. func setupPromptImageView(img: UIImage) {
  267. self.promptImageView.image = img
  268. var imgViewWidth = img.size.width
  269. var imgViewHeight = img.size.height
  270. if self.imageSize.width > 0 && self.imageSize.height > 0{
  271. if imgViewWidth > imgViewHeight {
  272. imgViewHeight = (imgViewHeight/imgViewWidth)*self.imageSize.width
  273. imgViewWidth = self.imageSize.width
  274. }else {
  275. imgViewWidth = (imgViewWidth / imgViewHeight) * self.imageSize.height
  276. imgViewHeight = self.imageSize.height
  277. }
  278. }
  279. self.promptImageView.frame = CGRect.init(x: 0, y: 0, width: imgViewWidth, height: imgViewHeight)
  280. self.promptImageView.center = CGPoint.init(x: self.ly_centerX, y: self.ly_centerY-imgViewHeight*0.5)
  281. contentWidth = self.promptImageView.ly_width
  282. contentHeight = self.promptImageView.ly_maxY
  283. }
  284. //titleLabel
  285. func setupTitleLabel(titleStr: NSString) {
  286. let fontSize: CGFloat = self.titleLabFont.pointSize
  287. let width: CGFloat = self.getTextWidth(text: titleStr, size: CGSize.init(width: contentMaxWidth!, height: fontSize), font: self.titleLabFont).width
  288. titleLabel.frame = CGRect.init(x: 0, y: contentHeight!+subViweMargin!, width: width, height: fontSize)
  289. self.titleLabel.center = CGPoint.init(x: self.ly_centerX, y: titleLabel.ly_centerY)
  290. titleLabel.font = self.titleLabFont
  291. titleLabel.textColor = titleLabTextColor
  292. titleLabel.text = self._titleStr! as String
  293. contentWidth = (Float(width) > Float(contentWidth!)) ? width : contentWidth
  294. contentHeight = titleLabel.ly_maxY
  295. }
  296. //DetailLabel
  297. func setupDetailLabel(detailStr: NSString) {
  298. let size: CGSize = self.getTextWidth(text: detailStr, size: CGSize.init(width: contentMaxWidth!, height: 900), font: self.detailLabFont)
  299. var width = size.width
  300. if width < contentMaxWidth! {
  301. width = contentMaxWidth!
  302. }
  303. detailLabel.frame = CGRect.init(x: contentMaxWidth!/2.0, y: contentHeight!+subViweMargin!, width: width, height: size.height+5)
  304. detailLabel.center = CGPoint.init(x: self.ly_centerX, y: detailLabel.ly_centerY)
  305. detailLabel.font = self.titleLabFont
  306. detailLabel.text = self._detailStr! as String
  307. detailLabel.textColor = detailLabTextColor
  308. contentWidth = (Float(width) > Float(contentWidth!)) ? width : contentWidth
  309. contentHeight = detailLabel.ly_maxY
  310. }
  311. //button
  312. func setupActionBtn(btnTitle: NSString, target:AnyObject?, action: Selector?, btnClickBlock: HDTapBlock?) {
  313. let fontSize: CGFloat = self.actionBtnFont.pointSize
  314. var btnWidth: CGFloat = self.getTextWidth(text: btnTitle, size: CGSize.init(width: contentMaxWidth!, height: fontSize), font: self.actionBtnFont).width + self.actionBtnHorizontalMargin*2
  315. let btnHeight = self.actionBtnHeight
  316. if btnWidth < self.actionBtnWidth {
  317. btnWidth = self.actionBtnWidth
  318. }
  319. actionButton.frame = CGRect.init(x: 0, y: contentHeight!+subViewMargin, width: btnWidth, height: btnHeight)
  320. actionButton.center = CGPoint.init(x: self.ly_centerX, y: actionButton.ly_centerY)
  321. actionButton.setTitle(btnTitle as String, for: .normal)
  322. actionButton.setTitleColor(self.actionBtnTitleColor, for: .normal)
  323. actionButton.titleLabel?.font = self.actionBtnFont
  324. actionButton.backgroundColor = self.actionBtnBackGroundColor
  325. actionButton.layer.borderWidth = self.actionBtnBorderWidth
  326. actionButton.layer.borderColor = self.actionBtnBorderColor.cgColor
  327. actionButton.layer.cornerRadius = self.actionBtnCornerRadius
  328. if action != nil {
  329. actionButton.addTarget(target!, action: action!, for: UIControl.Event.touchUpInside)
  330. actionButton.addTarget(self, action: #selector(actionBtnClick(_:)), for: UIControl.Event.touchUpInside)
  331. }else {
  332. actionButton.addTarget(self, action: #selector(actionBtnClick(_:)), for: UIControl.Event.touchUpInside)
  333. }
  334. }
  335. //MARK: ----
  336. func getTextWidth(text: NSString , size: CGSize, font: UIFont) -> CGSize {
  337. let textSize: CGSize = (text.boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [kCTFontAttributeName as NSAttributedString.Key: font], context: nil)).size
  338. return textSize
  339. }
  340. @objc func actionBtnClick(_ sender: UIButton) {
  341. if self._btnClickBlock != nil {
  342. self._btnClickBlock!()
  343. }
  344. }
  345. }