AboutViewController.swift 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. //
  2. // AboutViewController.swift
  3. // VenusKitto
  4. //
  5. // Created by Neoa on 2025/8/27.
  6. //
  7. import UIKit
  8. import WebKit
  9. final class AboutViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
  10. // 可按需替换为你们的线上链接
  11. private let PRIVACY_URL = URL(string: "https://ytwljs.github.io/gl-policy.html")!
  12. private let TERMS_URL = URL(string: "https://ytwljs.github.io/gl-user.html")!
  13. private let titleLabel: UILabel = {
  14. let l = UILabel()
  15. l.text = "关于我们"
  16. l.font = .systemFont(ofSize: 28, weight: .semibold)
  17. l.textColor = UIColor(hex: "#2B2B2B")
  18. return l
  19. }()
  20. private let logoImageView: UIImageView = {
  21. let iv = UIImageView(image: UIImage(named: "Home372"))
  22. iv.contentMode = .scaleAspectFit
  23. iv.clipsToBounds = true
  24. iv.layer.cornerRadius = 20
  25. return iv
  26. }()
  27. private let versionLabel: UILabel = {
  28. let l = UILabel()
  29. l.font = .systemFont(ofSize: 14)
  30. l.textColor = UIColor(hex: "#888888")
  31. l.textAlignment = .center
  32. return l
  33. }()
  34. private let tableView: UITableView = {
  35. let tv = UITableView(frame: .zero, style: .insetGrouped)
  36. tv.backgroundColor = .clear
  37. tv.showsVerticalScrollIndicator = false
  38. tv.separatorInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
  39. return tv
  40. }()
  41. override func viewDidLoad() {
  42. super.viewDidLoad()
  43. view.backgroundColor = UIColor(hex: "#FFFEFC")
  44. if let backImage = UIImage(named: "AddPet385") {
  45. let backButton = UIBarButtonItem(image: backImage.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(tapCancel))
  46. navigationItem.leftBarButtonItem = backButton
  47. }
  48. buildUI()
  49. fillInfo()
  50. tableView.dataSource = self
  51. tableView.delegate = self
  52. }
  53. private func buildUI() {
  54. view.addSubview(titleLabel)
  55. titleLabel.translatesAutoresizingMaskIntoConstraints = false
  56. NSLayoutConstraint.activate([
  57. titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 12),
  58. titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24)
  59. ])
  60. // 中心内容
  61. let centerWrap = UIView()
  62. view.addSubview(centerWrap)
  63. centerWrap.translatesAutoresizingMaskIntoConstraints = false
  64. NSLayoutConstraint.activate([
  65. centerWrap.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 24),
  66. centerWrap.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 24),
  67. centerWrap.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -24)
  68. ])
  69. centerWrap.addSubview(logoImageView)
  70. centerWrap.addSubview(versionLabel)
  71. logoImageView.translatesAutoresizingMaskIntoConstraints = false
  72. versionLabel.translatesAutoresizingMaskIntoConstraints = false
  73. NSLayoutConstraint.activate([
  74. logoImageView.topAnchor.constraint(equalTo: centerWrap.topAnchor, constant: 24),
  75. logoImageView.centerXAnchor.constraint(equalTo: centerWrap.centerXAnchor),
  76. logoImageView.widthAnchor.constraint(equalToConstant: 80),
  77. logoImageView.heightAnchor.constraint(equalToConstant: 80),
  78. versionLabel.topAnchor.constraint(equalTo: logoImageView.bottomAnchor, constant: 8),
  79. versionLabel.centerXAnchor.constraint(equalTo: centerWrap.centerXAnchor),
  80. versionLabel.bottomAnchor.constraint(equalTo: centerWrap.bottomAnchor)
  81. ])
  82. view.addSubview(tableView)
  83. tableView.translatesAutoresizingMaskIntoConstraints = false
  84. NSLayoutConstraint.activate([
  85. tableView.topAnchor.constraint(equalTo: centerWrap.bottomAnchor, constant: 24),
  86. tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
  87. tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
  88. tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
  89. ])
  90. }
  91. @objc private func tapCancel() { navigationController?.popViewController(animated: true)
  92. }
  93. private func fillInfo() {
  94. let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "-"
  95. versionLabel.text = "版本 v\(version)"
  96. }
  97. // MARK: - UITableViewDataSource
  98. func numberOfSections(in tableView: UITableView) -> Int { 1 }
  99. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 2 }
  100. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  101. let identifier = "PolicyCell"
  102. let cell = tableView.dequeueReusableCell(withIdentifier: identifier) ??
  103. UITableViewCell(style: .default, reuseIdentifier: identifier)
  104. cell.accessoryType = .disclosureIndicator
  105. cell.selectionStyle = .default
  106. cell.textLabel?.font = .systemFont(ofSize: 16, weight: .regular)
  107. cell.textLabel?.textColor = UIColor(hex: "#2B2B2B")
  108. cell.backgroundColor = .white
  109. cell.contentView.backgroundColor = .white
  110. cell.textLabel?.text = (indexPath.row == 0) ? "隐私协议" : "用户协议"
  111. return cell
  112. }
  113. // MARK: - UITableViewDelegate
  114. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 52 }
  115. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  116. tableView.deselectRow(at: indexPath, animated: true)
  117. let isPrivacy = (indexPath.row == 0)
  118. let url = isPrivacy ? PRIVACY_URL : TERMS_URL
  119. let title = isPrivacy ? "隐私协议" : "用户协议"
  120. let vc = PolicyWebController(url: url, titleText: title)
  121. vc.hidesBottomBarWhenPushed = true
  122. navigationController?.pushViewController(vc, animated: true)
  123. }
  124. }
  125. // 简易内置 Web 容器
  126. final class PolicyWebController: UIViewController, WKNavigationDelegate {
  127. private let url: URL
  128. private let titleText: String
  129. private var webView: WKWebView!
  130. init(url: URL, titleText: String) {
  131. self.url = url
  132. self.titleText = titleText
  133. super.init(nibName: nil, bundle: nil)
  134. }
  135. required init?(coder: NSCoder) { fatalError() }
  136. override func viewDidLoad() {
  137. super.viewDidLoad()
  138. view.backgroundColor = UIColor(hex: "#FFFEFC")
  139. if let backImage = UIImage(named: "AddPet385") {
  140. let backButton = UIBarButtonItem(image: backImage.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(tapCancel))
  141. navigationItem.leftBarButtonItem = backButton
  142. }
  143. let titleLabel = UILabel()
  144. titleLabel.text = titleText
  145. titleLabel.font = .systemFont(ofSize: 20, weight: .semibold)
  146. titleLabel.textColor = UIColor(hex: "#2B2B2B")
  147. view.addSubview(titleLabel)
  148. titleLabel.translatesAutoresizingMaskIntoConstraints = false
  149. NSLayoutConstraint.activate([
  150. titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8),
  151. titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)
  152. ])
  153. webView = WKWebView(frame: .zero)
  154. webView.navigationDelegate = self
  155. view.addSubview(webView)
  156. webView.translatesAutoresizingMaskIntoConstraints = false
  157. NSLayoutConstraint.activate([
  158. webView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8),
  159. webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
  160. webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
  161. webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
  162. ])
  163. webView.load(URLRequest(url: url))
  164. }
  165. @objc private func tapCancel() { navigationController?.popViewController(animated: true)
  166. }
  167. }