MCNavBarView.swift 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. //
  2. // MCNavBarView.swift
  3. // HCQuanfangtong
  4. //
  5. // Created by Apple on 2022/8/1.
  6. // Copyright © 2022 Jyp. All rights reserved.
  7. //
  8. import Foundation
  9. import UIKit
  10. import RxSwift
  11. import RxCocoa
  12. enum MCNavBarType {
  13. case defaults
  14. case search
  15. case segment
  16. case custom
  17. }
  18. class MCNavBarView: UIView{
  19. init(title: String?, subTitle: String?, style: MCNavBarStyle? = nil){
  20. self.navStyle = style ?? MCNavBarStyle.init()
  21. super.init(frame: CGRect.zero)
  22. self.backgroundColor = self.navStyle.styleForBackgroundColor
  23. self.addSubview(self.contentView)
  24. self.addSubview(self.leftStackView)
  25. self.addSubview(self.rightStackView)
  26. if title.isNotNil{
  27. self.titleLabel.text = title
  28. self.contentView.addArrangedSubview(self.titleLabel)
  29. }
  30. if subTitle.isNotNil{
  31. self.subTitleLabel.text = subTitle
  32. self.contentView.addArrangedSubview(self.subTitleLabel)
  33. }
  34. let backBtn = MCNavBtn.init(type: .custom)
  35. backBtn.image = self.navStyle.styleForBackImage
  36. backBtn.setImage(self.navStyle.styleForBackImage, for: .normal)
  37. _ = backBtn.rx.tap.takeUntil(self.rx.deallocated).subscribe(onNext:{[unowned self] in
  38. self.navBarBackBlock?()
  39. })
  40. self.leftBtns.append(backBtn)
  41. self.leftStackView.addArrangedSubview(backBtn)
  42. self.resetConstraint()
  43. }
  44. //MARK: - Property MCNavBarDelegate
  45. var showNavBackBtn: Bool = true{
  46. willSet{
  47. if newValue == self.showNavBackBtn{
  48. return
  49. }
  50. self.showNavBackBtn = newValue
  51. self.leftBtns[0].isHidden = !self.showNavBackBtn
  52. self.resetConstraint()
  53. }
  54. }
  55. /// 返回事件
  56. var navBarBackBlock: (() -> Void)?
  57. /// 高度监听
  58. var navBarHeightSubject: BehaviorSubject<CGFloat> = BehaviorSubject.init(value: 0)
  59. /// 样式
  60. var navStyle: MCNavBarStyle
  61. /// 透明样式
  62. var navTransparentStyle: MCNavBarTransparentColorStyle?{
  63. didSet{
  64. if self.leftBtns.count > 0{
  65. self.leftBtns[0].transparentImage = self.navTransparentStyle?.styleForBackImage
  66. }
  67. self.resetStyle()
  68. }
  69. }
  70. weak var navTransparentBinderedScrollView: UIScrollView?{
  71. didSet{
  72. if let scrollView = self.navTransparentBinderedScrollView {
  73. _ = scrollView.rx.contentOffset.takeUntil(scrollView.rx.deallocated).subscribe(onNext:{[unowned self] point in
  74. guard let transparentStyle = self.navTransparentStyle else {
  75. return
  76. }
  77. if point.y > transparentStyle.styleForScrollDistanceChange && self.navIsTransparent{
  78. self.resetStyle()
  79. }
  80. else if point.y <= transparentStyle.styleForScrollDistanceChange && !self.navIsTransparent{
  81. self.resetStyle()
  82. }
  83. })
  84. }
  85. }
  86. }
  87. //MARK: - 类型
  88. var type: MCNavBarType{
  89. .defaults
  90. }
  91. //MARK: - Private
  92. private var leftBtns: [MCNavBtn] = []
  93. lazy private var leftStackView: UIStackView = {[unowned self] in
  94. let stackView = UIStackView.init(frame: CGRect.zero)
  95. stackView.axis = .horizontal
  96. stackView.alignment = .fill
  97. stackView.distribution = .fillProportionally
  98. stackView.spacing = self.navStyle.styleForElementSpace
  99. return stackView
  100. }()
  101. private var rightBtns: [MCNavBtn] = []
  102. lazy private var rightStackView: UIStackView = {[unowned self] in
  103. let stackView = UIStackView.init(frame: CGRect.zero)
  104. stackView.axis = .horizontal
  105. stackView.alignment = .fill
  106. stackView.distribution = .fillProportionally
  107. stackView.spacing = self.navStyle.styleForElementSpace
  108. return stackView
  109. }()
  110. /// 标题,副标题
  111. lazy var contentView: UIStackView = {[unowned self] in
  112. let stackView = UIStackView.init(frame: CGRect.zero)
  113. stackView.axis = .vertical
  114. stackView.alignment = .fill
  115. stackView.distribution = .fill
  116. stackView.spacing = self.navStyle.styleForTitleAndSubTitleDistance
  117. return stackView
  118. }()
  119. lazy private var titleLabel: UILabel = {[unowned self] in
  120. let label = UILabel.init(frame: CGRect.zero)
  121. label.font = self.navStyle.styleForTitleFont
  122. label.textColor = self.navStyle.styleForTitleColor
  123. label.textAlignment = .center
  124. return label
  125. }()
  126. lazy private var subTitleLabel: UILabel = {[unowned self] in
  127. let label = UILabel.init(frame: CGRect.zero)
  128. label.font = self.navStyle.styleForSubTitleFont
  129. label.textColor = self.navStyle.styleForSubTitleColor
  130. label.textAlignment = .center
  131. return label
  132. }()
  133. /// 当前是否为透明
  134. private var navIsTransparent: Bool = false
  135. //MARK: -
  136. required init?(coder: NSCoder) {
  137. fatalError("init(coder:) has not been implemented")
  138. }
  139. }
  140. extension MCNavBarView{
  141. func resetConstraint(){
  142. //左边
  143. //计算返回按钮
  144. if self.type == .defaults{
  145. self.contentView.axis = .vertical
  146. }
  147. else{
  148. self.contentView.axis = .horizontal
  149. }
  150. var leftBtnWidth: CGFloat = 0
  151. var rightBtnWidth: CGFloat = 0
  152. for i in 0..<self.leftBtns.count{
  153. let btn = self.leftBtns[i]
  154. if i == 0 && showNavBackBtn{
  155. let btnContentWidth = btn.getAdjustWidth(minWidth: 0, titleDistanceImage: self.navStyle.styleForBtnTitleAndImageDistance)
  156. var maxWidth = btnContentWidth + self.navStyle.styleForBackEdgeInset.left + self.navStyle.styleForBackEdgeInset.right
  157. if maxWidth < self.navStyle.styleForBackMinWidth{
  158. maxWidth = self.navStyle.styleForBackMinWidth;
  159. }
  160. if btn.image(for: .normal).isNotNil && btn.title(for: .normal).isNotEmptyStr{
  161. //两个都存在
  162. btn.imageEdgeInsets = UIEdgeInsets.init(top: 0, left: -((maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left - self.navStyle.styleForBtnTitleAndImageDistance * 0.5), bottom: 0, right: (maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left - self.navStyle.styleForBtnTitleAndImageDistance * 0.5)
  163. btn.titleEdgeInsets = UIEdgeInsets.init(top: 0, left: -((maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left + self.navStyle.styleForBtnTitleAndImageDistance * 0.5), bottom: 0, right: (maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left + self.navStyle.styleForBtnTitleAndImageDistance * 0.5)
  164. }
  165. else if btn.image(for: .normal).isNotNil{
  166. //只存在图片
  167. btn.imageEdgeInsets = UIEdgeInsets.init(top: 0, left: -((maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left), bottom: 0, right: (maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left)
  168. }
  169. else{
  170. //只存在文本
  171. btn.titleEdgeInsets = UIEdgeInsets.init(top: 0, left: -((maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left), bottom: 0, right: (maxWidth - btnContentWidth) * 0.5 - self.navStyle.styleForBackEdgeInset.left)
  172. }
  173. btn.mas_updateConstraints { make in
  174. make?.width.offset()(maxWidth)
  175. }
  176. leftBtnWidth += maxWidth
  177. leftBtnWidth += self.leftStackView.spacing
  178. }
  179. else{
  180. if !btn.isHidden{
  181. btn.setTitleAndImageDistance(self.navStyle.styleForBtnTitleAndImageDistance)
  182. let btnWidth = btn.getAdjustWidth(minWidth: self.navStyle.styleForTapMinWidth, titleDistanceImage: self.navStyle.styleForBtnTitleAndImageDistance)
  183. btn.mas_updateConstraints { make in
  184. make?.width.offset()(btnWidth)
  185. }
  186. leftBtnWidth += btnWidth
  187. leftBtnWidth += self.leftStackView.spacing
  188. }
  189. }
  190. }
  191. for btn in self.rightBtns{
  192. if !btn.isHidden{
  193. let btnWidth = btn.getAdjustWidth(minWidth: self.navStyle.styleForTapMinWidth, titleDistanceImage: self.navStyle.styleForBtnTitleAndImageDistance)
  194. btn.mas_updateConstraints { make in
  195. make?.width.offset()(btnWidth)
  196. }
  197. rightBtnWidth += btnWidth
  198. rightBtnWidth += self.rightStackView.spacing
  199. }
  200. }
  201. self.leftStackView.mas_remakeConstraints { make in
  202. make?.left.mas_equalTo()(self)?.offset()(self.showNavBackBtn ? 0:self.navStyle.styleForContentEdge.left)
  203. make?.top.mas_equalTo()(self)?.offset()(kStatuBarHeight)
  204. make?.height.offset()(self.navBarHeight() - kStatuBarHeight)
  205. }
  206. self.rightStackView.mas_remakeConstraints { make in
  207. make?.right.mas_equalTo()(self)?.offset()(-self.navStyle.styleForContentEdge.right)
  208. make?.top.mas_equalTo()(self)?.offset()(kStatuBarHeight)
  209. make?.height.offset()(self.navBarHeight() - kStatuBarHeight)
  210. }
  211. MAIN({})
  212. let leftBtnContains = self.leftBtns.compactMap { btn in
  213. !btn.isHidden
  214. }.count > 0
  215. let rightBtnContains = self.rightBtns.compactMap { btn in
  216. !btn.isHidden
  217. }.count > 0
  218. let leftWidth = (self.showNavBackBtn ? leftBtnWidth:(leftBtnWidth + self.navStyle.styleForContentEdge.left)) + (leftBtnContains ? (self.navStyle.styleForElementSpace - self.leftStackView.spacing):0)
  219. let rightWidth = rightBtnWidth + self.navStyle.styleForContentEdge.right + (rightBtnContains ? (self.navStyle.styleForElementSpace + self.rightStackView.spacing):0)
  220. if self.navStyle.styleForContentViewWidth > -1{
  221. //定了宽度
  222. //计算当前剩余的宽度是否可以放下content
  223. var remainingWidth = kSCREEN_WIDTH - leftWidth - rightWidth
  224. if remainingWidth < self.navStyle.styleForContentViewWidth{
  225. //放不下
  226. self.contentView.mas_remakeConstraints { make in
  227. make?.left.equalTo()(leftBtnContains ? self.leftStackView.mas_right:self)?.offset()(leftBtnContains ? self.navStyle.styleForElementSpace:self.navStyle.styleForContentEdge.left)
  228. make?.right.equalTo()(rightBtnContains ? self.rightStackView.mas_left:self)?.offset()(rightBtnContains ? -self.navStyle.styleForElementSpace:-self.navStyle.styleForContentEdge.right)
  229. make?.centerY.mas_equalTo()(self.leftStackView)
  230. }
  231. }
  232. else{
  233. //放得下
  234. //计算居中可以放下不
  235. let maxWidth = max(leftWidth, rightWidth)
  236. remainingWidth = kSCREEN_WIDTH - maxWidth * 2
  237. if remainingWidth < self.navStyle.styleForContentViewWidth{
  238. //居中放不下
  239. //在剩下的区域居中
  240. let distance = (remainingWidth - self.navStyle.styleForContentViewWidth) * 0.5
  241. self.contentView.mas_remakeConstraints { make in
  242. make?.left.mas_equalTo()(self)?.offset()(leftWidth + distance)
  243. make?.right.mas_equalTo()(self)?.offset()(-(rightWidth + distance))
  244. make?.centerY.mas_equalTo()(self.leftStackView)
  245. }
  246. }
  247. else{
  248. //居中
  249. self.contentView.mas_remakeConstraints { make in
  250. make?.width.offset()(self.navStyle.styleForContentViewWidth)
  251. make?.centerY.mas_equalTo()(self.leftStackView)
  252. make?.centerX.mas_equalTo()(self)
  253. }
  254. }
  255. }
  256. }
  257. else{
  258. self.contentView.mas_remakeConstraints { make in
  259. if self.navStyle.styleForContentViewIsMiddle{
  260. if leftWidth > rightWidth{
  261. make?.left.equalTo()(leftBtnContains ? self.leftStackView.mas_right:self)?.offset()(leftBtnContains ? self.navStyle.styleForElementSpace:self.navStyle.styleForContentEdge.left)
  262. }
  263. else{
  264. make?.right.equalTo()(rightBtnContains ? self.rightStackView.mas_left:self)?.offset()(rightBtnContains ? -self.navStyle.styleForElementSpace:-self.navStyle.styleForContentEdge.right)
  265. }
  266. make?.centerY.mas_equalTo()(self.leftStackView)
  267. make?.centerX.mas_equalTo()(self)
  268. }
  269. else{
  270. make?.left.equalTo()(leftBtnContains ? self.leftStackView.mas_right:self)?.offset()(leftBtnContains ? self.navStyle.styleForElementSpace:self.navStyle.styleForContentEdge.left)
  271. make?.right.equalTo()(rightBtnContains ? self.rightStackView.mas_left:self)?.offset()(rightBtnContains ? -self.navStyle.styleForElementSpace:-self.navStyle.styleForContentEdge.right)
  272. make?.centerY.mas_equalTo()(self.leftStackView)
  273. }
  274. }
  275. }
  276. self.navBarHeightSubject.onNext(self.navBarHeight())
  277. }
  278. }
  279. extension MCNavBarView{
  280. //重设样式
  281. @objc func resetStyle(){
  282. guard let transparentStyle = self.navTransparentStyle else{
  283. self.resetConstraint()
  284. return
  285. }
  286. guard let scrollView = self.navTransparentBinderedScrollView else{
  287. self.resetTransparentStyle()
  288. self.resetConstraint()
  289. return
  290. }
  291. //包含透明样式
  292. if scrollView.contentOffset.y > transparentStyle.styleForScrollDistanceChange{
  293. //正常样式
  294. self.resetNormalStyle()
  295. }
  296. else{
  297. //透明样式
  298. self.resetTransparentStyle()
  299. }
  300. self.resetConstraint()
  301. }
  302. @objc func resetNormalStyle(){
  303. self.navIsTransparent = false
  304. self.backgroundColor = self.navStyle.styleForBackgroundColor
  305. self.titleLabel.textColor = self.navStyle.styleForTitleColor
  306. self.subTitleLabel.textColor = self.navStyle.styleForSubTitleColor
  307. _ = self.leftBtns.map { btn in
  308. btn.setImage(btn.image, for: .normal)
  309. }
  310. _ = self.rightBtns.map { btn in
  311. btn.setImage(btn.image, for: .normal)
  312. }
  313. }
  314. @objc func resetTransparentStyle(){
  315. self.navIsTransparent = true
  316. self.backgroundColor = self.navTransparentStyle?.styleForBackgroundColor
  317. self.titleLabel.textColor = self.navTransparentStyle?.styleForTitleColor
  318. self.subTitleLabel.textColor = self.navTransparentStyle?.styleForSubTitleColor
  319. _ = self.leftBtns.map { btn in
  320. btn.setImage(btn.transparentImage, for: .normal)
  321. }
  322. _ = self.rightBtns.map { btn in
  323. btn.setImage(btn.transparentImage, for: .normal)
  324. }
  325. }
  326. }
  327. extension MCNavBarView: MCNavBarDelegate{
  328. @objc func navBarHeight() -> CGFloat {
  329. if type == .defaults{
  330. if self.subTitleLabel.text.isNotEmptyStr{
  331. return kNavAndStatuHeight + 22
  332. }
  333. }
  334. return kNavAndStatuHeight
  335. }
  336. @objc func setNavSubTitle(_ title: String?){
  337. if type == .defaults{
  338. self.subTitleLabel.text = title
  339. if self.subTitleLabel.superview.isNil{
  340. self.contentView.addArrangedSubview(self.subTitleLabel)
  341. self.contentView.insertArrangedSubview(self.subTitleLabel, at: self.contentView.arrangedSubviews.count - 1)
  342. }
  343. self.subTitleLabel.isHidden = title.isEmptyStr
  344. self.resetConstraint()
  345. }
  346. }
  347. @objc func setNavTitle(_ title: String?){
  348. if type == .defaults{
  349. self.titleLabel.text = title
  350. if self.titleLabel.superview.isNil{
  351. self.contentView.addArrangedSubview(self.titleLabel)
  352. self.contentView.insertArrangedSubview(self.titleLabel, at: 0)
  353. }
  354. self.titleLabel.isHidden = title.isEmptyStr
  355. self.resetConstraint()
  356. }
  357. }
  358. /// 设置右边按钮的标题 图片
  359. /// - Parameters:
  360. /// - title: <#title description#>
  361. /// - image: <#image description#>
  362. /// - index: <#index description#>
  363. func setNavRightBtnTitle(_ title: String?, image: String?, at index: Int){
  364. let search = self.rightBtns.canGet(at: index)
  365. if search.0{
  366. let index = search.1
  367. let btn = self.rightBtns[index]
  368. btn.setTitle(title, for: .normal)
  369. let image: UIImage? = image.isEmptyStr ? nil:UIImage.init(named: image!)
  370. btn.setImage(image, for: .normal)
  371. btn.image = image
  372. self.resetStyle()
  373. }
  374. }
  375. func setNavLeftBtnTitle(_ title: String?, image: String?, at index: Int){
  376. let search = self.leftBtns.canGet(at: index)
  377. if search.0{
  378. let index = search.1
  379. let btn = self.leftBtns[index]
  380. btn.setTitle(title, for: .normal)
  381. let image: UIImage? = image.isEmptyStr ? nil:UIImage.init(named: image!)
  382. btn.setImage(image, for: .normal)
  383. btn.image = image
  384. self.resetStyle()
  385. }
  386. }
  387. /// 新增按钮
  388. /// - Parameters:
  389. /// - title: <#title description#>
  390. /// - image: <#image description#>
  391. /// - tap: <#tap description#>
  392. /// - semantic
  393. /// - index: <#index description#>
  394. func insertNavRightBtn(_ title: String?, image: String?, tap: (()->Void)?, semantic: UISemanticContentAttribute?, at index: Int){
  395. let search = self.rightBtns.canInsert(at: index)
  396. if search.0{
  397. let index = search.1
  398. let image: UIImage? = image.isEmptyStr ? nil:UIImage.init(named: image!)
  399. let btn = MCNavBtn.createButton(withTitle: title, titleColor: self.navStyle.styleForBtnTitleColor, font: self.navStyle.styleForBtnTitleFont, image: image, tap: tap)
  400. btn.image = image
  401. btn.semanticContentAttribute = semantic ?? .forceRightToLeft
  402. btn.setTitleAndImageDistance(self.navStyle.styleForBtnTitleAndImageDistance)
  403. self.rightBtns.insert(btn, at: index)
  404. self.rightStackView.insertArrangedSubview(btn, at: index)
  405. self.resetStyle()
  406. }
  407. }
  408. func insertNavLeftBtn(_ title: String?, image: String?, tap: (()->Void)?, semantic: UISemanticContentAttribute?, at index: Int){
  409. let search = self.leftBtns.canInsert(at: index)
  410. if search.0{
  411. let index = search.1
  412. let image: UIImage? = image.isEmptyStr ? nil:UIImage.init(named: image!)
  413. let btn = MCNavBtn.createButton(withTitle: title, titleColor: self.navStyle.styleForBtnTitleColor, font: self.navStyle.styleForBtnTitleFont, image: image, tap: tap)
  414. btn.image = image
  415. btn.semanticContentAttribute = semantic ?? .forceRightToLeft
  416. btn.setTitleAndImageDistance(self.navStyle.styleForBtnTitleAndImageDistance)
  417. self.leftBtns.insert(btn, at: index)
  418. self.leftStackView.insertArrangedSubview(btn, at: index)
  419. self.resetStyle()
  420. }
  421. }
  422. /// 设置隐藏
  423. /// - Parameters:
  424. /// - hidden: <#hidden description#>
  425. /// - index: <#index description#>
  426. func setNavRightBtnHidden(_ hidden: Bool, at index: Int){
  427. let search = self.rightBtns.canGet(at: index)
  428. if search.0{
  429. let index = search.1
  430. let btn = self.rightBtns[index]
  431. btn.isHidden = hidden
  432. self.resetConstraint()
  433. }
  434. }
  435. func setNavLeftBtnHidden(_ hidden: Bool, at index: Int) {
  436. let search = self.leftBtns.canGet(at: index)
  437. if search.0{
  438. let index = search.1
  439. if index == 0{
  440. self.showNavBackBtn = !hidden
  441. }
  442. else{
  443. let btn = self.leftBtns[index]
  444. btn.isHidden = hidden
  445. self.resetConstraint()
  446. }
  447. }
  448. }
  449. /// 删除按钮
  450. /// - Parameter index: <#index description#>
  451. func deleteNavRightBtn(at index: Int){
  452. let search = self.rightBtns.canDelete(at: index)
  453. if search.0{
  454. let index = search.1
  455. self.rightStackView.removeArrangedSubview(self.rightBtns[index])
  456. self.rightBtns.remove(at: index)
  457. self.resetConstraint()
  458. }
  459. }
  460. /// 删除左边按钮 不可以删除返回按钮,可以操作隐藏
  461. /// - Parameter index: <#index description#>
  462. func deleteNavLeftBtn(at index: Int){
  463. let search = self.leftBtns.canDelete(at: index)
  464. if search.0{
  465. let index = search.1
  466. if index == 0{
  467. return
  468. }
  469. self.leftStackView.removeArrangedSubview(self.leftBtns[index])
  470. self.leftBtns.remove(at: index)
  471. self.resetConstraint()
  472. }
  473. }
  474. /// 获取右侧按钮的位置
  475. /// - Parameter index: <#index description#>
  476. func getNavRightBtnFrame(at index: Int) -> CGRect?{
  477. MAIN {}
  478. let search = self.rightBtns.canGet(at: index)
  479. if search.0{
  480. let index = search.1
  481. let searchBtn = self.rightBtns[index]
  482. return self.rightStackView.convert(searchBtn.frame, to: self)
  483. }
  484. return nil
  485. }
  486. /// 获取左侧按钮的位置
  487. /// - Parameter index: <#index description#>
  488. func getNavLeftBtnFrame(at index: Int) -> CGRect?{
  489. MAIN {}
  490. let search = self.leftBtns.canGet(at: index)
  491. if search.0{
  492. let index = search.1
  493. let searchBtn = self.leftBtns[index]
  494. return self.leftStackView.convert(searchBtn.frame, to: self)
  495. }
  496. return nil
  497. }
  498. /// 设置右边按钮 透明导航 图片
  499. /// - Parameters:
  500. /// - img: <#img description#>
  501. /// - index: <#index description#>
  502. func setNavRightBtnTransparentImage(_ img: String, at index: Int){
  503. let search = self.rightBtns.canGet(at: index)
  504. if search.0{
  505. let index = search.1
  506. let image = img.isEmpty ? nil:UIImage.init(named: img)
  507. let btn = self.rightBtns[index]
  508. btn.transparentImage = image
  509. self.resetStyle()
  510. }
  511. }
  512. /// 设置左边按钮 透明导航 图片
  513. /// - Parameters:
  514. /// - img: <#img description#>
  515. /// - index: <#index description#>
  516. func setNavLeftBtnTransparentImage(_ img: String, at index: Int){
  517. let search = self.leftBtns.canGet(at: index)
  518. if search.0{
  519. let index = search.1
  520. let image = img.isEmpty ? nil:UIImage.init(named: img)
  521. let btn = self.leftBtns[index]
  522. btn.transparentImage = image
  523. self.resetStyle()
  524. }
  525. }
  526. }
  527. extension Reactive where Base : NSLayoutConstraint{
  528. /// Reactive wrapper for `.constant`
  529. public var constBind : Binder<CGFloat>{
  530. return Binder(self.base) { layoutConst, constBind in
  531. layoutConst.constant = constBind
  532. }
  533. }
  534. }
  535. fileprivate class MCNavBtn: UIButton{
  536. //透明图片
  537. var transparentImage: UIImage?
  538. //图片
  539. var image: UIImage?
  540. }
  541. extension UIButton{
  542. func getAdjustWidth(minWidth: CGFloat, titleDistanceImage: CGFloat = 2) -> CGFloat{
  543. var adjustWidth: CGFloat = 0;
  544. if let title = self.title(for: .normal){
  545. if let font = self.titleLabel?.font{
  546. let rect = title.boundingRect(with: CGSize.init(width: .greatestFiniteMagnitude, height: font.pointSize), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font:font], context: nil)
  547. adjustWidth += CGFloat(ceilf(Float(rect.width)))
  548. }
  549. }
  550. if let image = self.image(for: .normal){
  551. if titleDistanceImage > 0 && adjustWidth > 0{
  552. adjustWidth += titleDistanceImage
  553. }
  554. adjustWidth += image.size.width
  555. }
  556. if adjustWidth < minWidth{
  557. adjustWidth = minWidth
  558. }
  559. return adjustWidth
  560. }
  561. }