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
sQop2HQjbzkQm&LIGB_Yzxj{
+
+
+
+ SchemeUserState
+
+ Promises (Playground) 1.xcscheme
+
+ isShown
+
+ orderHint
+ 59
+
+ Promises (Playground) 2.xcscheme
+
+ isShown
+
+ orderHint
+ 60
+
+ Promises (Playground).xcscheme
+
+ isShown
+
+ orderHint
+ 58
+
+
+
+
diff --git a/SwiftProject/SwiftProject/Assets.xcassets/ProblemSuggestion description'logo.imageset/Contents.json b/SwiftProject/SwiftProject/Assets.xcassets/ProblemSuggestion description'logo.imageset/Contents.json
new file mode 100644
index 0000000..5c114fc
--- /dev/null
+++ b/SwiftProject/SwiftProject/Assets.xcassets/ProblemSuggestion description'logo.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "_@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "_@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/SwiftProject/SwiftProject/Assets.xcassets/ProblemSuggestion description'logo.imageset/_@2x.png b/SwiftProject/SwiftProject/Assets.xcassets/ProblemSuggestion description'logo.imageset/_@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..d24f6fcb02c11652fcafa73269481ca84d2c60bd
GIT binary patch
literal 553
zcmV+^0@nSBP)Px$<4Ht8R5(wSlCf)3Q5431--|IQwE+#(p>C3;;vy(+f;I2GNP;2-3ogzM4i46#
z7^$MTsPsQ@D8WFnAT$XrcC+eGRHB262Ybg+)D!mo%fJ<2UX{xA|AT{I6tinc&r~iKc7&}^@Tk=i3=REJq2M-(
zEDUovcN3UVr83dI2N8z5sn;V}K0iRC5n{H4**B8OpOi{XvRR)fx{WkNx%_~U5s#IX
zB(2s#VzD%4pJYLB9=L&-2P`2KX|=u*j~{MNHY;K_Lp;8pD9Qsqk^$2)-@kx#2D3fD
z0FXkeu-Mnk5|oDgo~vf00000NkvXXu0mjfh%fQ<
literal 0
HcmV?d00001
diff --git a/SwiftProject/SwiftProject/Assets.xcassets/ProblemSuggestion description'logo.imageset/_@3x.png b/SwiftProject/SwiftProject/Assets.xcassets/ProblemSuggestion description'logo.imageset/_@3x.png
new file mode 100644
index 0000000000000000000000000000000000000000..bec067fbf759f2b0de9ebf773b274f26d9fb12f7
GIT binary patch
literal 877
zcmV-z1CsoSP)Px&CrLy>R7gv$ly7KNbr{D#&+puwyG(D+2+QUs%a~$hAR!k-7pUhRHzvIp^(K5#
z!UA6?LRl|D@kJ_RA%rPtMD(T+g%fuGWvG!ewqBB#a$~17%_VyOy_|r=4&=~k;
zDHc!PJMg-7%_Pakzzjq#VeO{-!+7=TCNi0iP@RRyd6J}CjvqgN?~KE+5!FMeK741lRlHT4M>0M{%EJ~&281oFO&!V~j_))aIeKARL7}dH80}G4*PFB&_gFSfOjN8B>
zzf&x}Kp3{58lbugcocZBs)8ZWLSY5ajp|%fXCgBGz^)xg*ln%<;
zl@(@yMY&hOu9R)-6c`<&D6k!f)oAgV@z^spz7z0j_$6u
zxpsEWb^j`|bW!K9_SNc*S1Y%*Yv*Ik9#o%1M1h|um$ylO|J8{t(=dFZvhil7cOs`S
zW}6&4b}{{|PS7A&ipb8&7IO~UK|cSrY~Su|KIv!>tVd)ks;=LI7_-aGVKQ)6m&fpM
zD|K~mp!y}b+=ml~QbWY`yS{!4*1A2hk0=@vaFuck?BGjMxR;;a00000NkvXXu0mjf
D{>ZH$
literal 0
HcmV?d00001
diff --git a/SwiftProject/SwiftProject/Project/Controller/MenuVC/FeedBackVC.swift b/SwiftProject/SwiftProject/Project/Controller/MenuVC/FeedBackVC.swift
new file mode 100644
index 0000000..561f3d5
--- /dev/null
+++ b/SwiftProject/SwiftProject/Project/Controller/MenuVC/FeedBackVC.swift
@@ -0,0 +1,233 @@
+//
+// FeedBackVC.swift
+// SwiftProject
+//
+// Created by Mr.Zhou on 2024/4/12.
+//
+
+import UIKit
+
+class FeedBackVC: BaseController, UITextViewDelegate, UITextFieldDelegate {
+ //问题意见标题Label
+ private lazy var problemTitleLabel:UILabel = setLabel(NSLocalizedString("v1.5_problem/suggestion title", comment: ""), color: .init(r: 255, g: 255, b: 255, a: 0.8), font: .systemFont(ofSize: 16, weight: .medium))
+ //问题意见文本框
+ private lazy var problemTextView:UITextView = {
+ let textView:UITextView = .init()
+ textView.textColor = .white
+ textView.font = .systemFont(ofSize: 14, weight: .medium)
+ textView.text = ""
+ textView.backgroundColor = .clear
+ textView.delegate = self
+ return textView
+ }()
+ //问题意见占位字符
+ private lazy var problemPlaceholderLabel:UILabel = setLabel(NSLocalizedString("v1.5_problem/suggestion placeholder", comment: ""), color: .init(r: 255, g: 255, b: 255, a: 0.6), font: .systemFont(ofSize: 14, weight: .medium))
+ //1号计数Label
+ private lazy var oneNumbersLabel:UILabel = setLabel("0/500", color: .init(r: 255, g: 255, b: 255, a: 0.5), font: .systemFont(ofSize: 14, weight: .medium))
+ //问联系信息标题Label
+ private lazy var contactTitleLabel:UILabel = setLabel(NSLocalizedString("v1.5_contact information title", comment: ""), color: .init(r: 255, g: 255, b: 255, a: 0.8), font: .systemFont(ofSize: 16, weight: .medium))
+
+ //联系信息输入框
+ private lazy var contactTextField:UITextField = {
+ let textField:UITextField = .init()
+ textField.text = ""
+ textField.textColor = .white
+ textField.font = .systemFont(ofSize: 14, weight: .medium)
+ textField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("v1.5_contact information placeholder", comment: ""), attributes: [.foregroundColor:UIColor(r: 255, g: 255, b: 255, a: 0.6), .font:UIFont.systemFont(ofSize: 14, weight: .medium)])
+ textField.borderStyle = .none
+ textField.delegate = self
+ return textField
+ }()
+ //二号计数Label
+ private lazy var twoNumbersLabel:UILabel = setLabel("0/30", color: .init(r: 255, g: 255, b: 255, a: 0.5), font: .systemFont(ofSize: 14, weight: .medium))
+ //提交按钮
+ private lazy var submitButton:UIButton = {
+ let btn = UIButton()
+ btn.setTitle(NSLocalizedString("v1.5_submit", comment: ""), for: .normal)
+ btn.setTitle(NSLocalizedString("v1.5_submit", comment: ""), for: .disabled)
+ btn.setTitleColor(.init(r: 255, g: 255, b: 255, a: 0.6), for: .disabled)
+ btn.setTitleColor(.white, for: .normal)
+ btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
+ btn.addTarget(self, action: #selector(submitClick(_ :)), for: .touchUpInside)
+ //不可选中颜色
+ btn.backgroundColor = .init(r: 42, g: 42, b: 42, a: 1)
+ btn.layer.masksToBounds = true
+ btn.layer.cornerRadius = 12
+
+ return btn
+ }()
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ navLine?.isHidden = true
+ setLeftOneBtnImg(imgStr: "menuvc_backbtn")
+ leftBtn1?.addTarget(self, action: #selector(popVC(_ :)), for: .touchUpInside)
+ self.view.backgroundColor = UIColor(r: 6, g: 5, b: 7, a: 1)
+ //设置标题
+ titleLab?.isHidden = false
+ setNavgaionTitle(string: NSLocalizedString("v1.5_feedback", comment: ""))
+ setNavgationTitleAttribute(font: .systemFont(ofSize: 18, weight: .medium), color: .white)
+ configureUI()
+ }
+
+ //生成label
+ private func setLabel(_ text:String, color:UIColor, font:UIFont) -> UILabel {
+ let label = UILabel()
+ label.text = text
+ label.textColor = color
+ label.font = font
+ label.numberOfLines = 0
+ return label
+ }
+ //配置UI
+ private func configureUI() {
+ //配置问题/意见View
+ let problemView = problemView()
+ view.addSubview(problemView)
+ problemView.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.top.equalToSuperview().offset(145)
+ make.width.equalTo(345)
+ make.height.equalTo(120)
+ }
+ view.addSubview(problemTitleLabel)
+ problemTitleLabel.snp.makeConstraints { make in
+ make.left.equalTo(problemView.snp.left).offset(12)
+ make.bottom.equalTo(problemView.snp.top).offset(-12)
+ }
+ let imageView = UIImageView(image: .init(named: "ProblemSuggestion description'logo"))
+ view.addSubview(imageView)
+ imageView.snp.makeConstraints { make in
+ make.top.equalTo(problemTitleLabel)
+ make.left.equalTo(problemTitleLabel.snp.right)
+ }
+ //配置联系我们View
+ let contactView = contactView()
+ view.addSubview(contactView)
+ contactView.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.top.equalTo(problemView.snp.bottom).offset(72)
+ make.width.equalTo(345)
+ make.height.equalTo(56)
+ }
+ view.addSubview(contactTitleLabel)
+ contactTitleLabel.snp.makeConstraints { make in
+ make.left.equalTo(problemTitleLabel)
+ make.bottom.equalTo(contactView.snp.top).offset(-10)
+ }
+ //添加提交按钮
+ view.addSubview(submitButton)
+ submitButton.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().offset(-52)
+ make.width.equalTo(345)
+ make.height.equalTo(54)
+ }
+ }
+ //生成问题意见View
+ private func problemView() -> UIView {
+ let bgView = UIView()
+ bgView.backgroundColor = .init(r: 29, g: 29, b: 29, a: 1)
+ bgView.layer.masksToBounds = true
+ bgView.layer.cornerRadius = 12
+ bgView.addSubview(problemTextView)
+ problemTextView.snp.makeConstraints { make in
+ make.top.left.equalToSuperview().offset(12)
+ make.right.equalToSuperview().offset(-12)
+ make.height.equalTo(72)
+ }
+ bgView.addSubview(problemPlaceholderLabel)
+ problemTitleLabel.snp.makeConstraints { make in
+ make.top.left.right.equalTo(problemTextView)
+ }
+ bgView.addSubview(oneNumbersLabel)
+ oneNumbersLabel.snp.makeConstraints { make in
+ make.right.bottom.equalToSuperview().offset(-12)
+ }
+ return bgView
+ }
+ //生成联系我们View
+ private func contactView() -> UIView {
+ let bgView = UIView()
+ bgView.backgroundColor = .init(r: 29, g: 29, b: 29, a: 1)
+ bgView.layer.masksToBounds = true
+ bgView.layer.cornerRadius = 8
+ bgView.addSubview(twoNumbersLabel)
+ twoNumbersLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().offset(-12)
+ }
+ bgView.addSubview(contactTextField)
+ contactTextField.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().offset(12)
+ make.right.equalToSuperview().offset(-42)
+ }
+ return bgView
+ }
+ //MARK: - textField And textView
+ func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
+ let text = (textField.text! as NSString).replacingCharacters(in: range, with: string)
+ guard text.count <= 30 else {
+ twoNumbersLabel.text = "30/30"
+ return false
+ }
+ twoNumbersLabel.text = "\(text.count)/30"
+ return true
+ }
+ func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
+ self.problemPlaceholderLabel.isHidden = true // 隐藏
+ return true
+ }
+ func textViewDidBeginEditing(_ textView: UITextView) {
+
+ }
+ func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
+ return true
+ }
+ func textViewDidEndEditing(_ textView: UITextView) {
+ if textView.text.isEmpty {
+ self.problemPlaceholderLabel.isHidden = false // 显示
+ }
+ else{
+ self.problemPlaceholderLabel.isHidden = true // 隐藏
+ }
+ }
+ func textViewDidChange(_ textView: UITextView) {
+
+ }
+ //获取textView字符内容
+ func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
+ let str = (textView.text! as NSString).replacingCharacters(in: range, with: text)
+ guard text.count <= 500 else {
+ oneNumbersLabel.text = "500/500"
+ submitButton.isEnabled = true
+ submitButton.backgroundColor = .init(r: 83, g: 38, b: 214, a: 1)
+ return false
+ }
+ if text.count >= 5 {
+ submitButton.isEnabled = true
+ submitButton.backgroundColor = .init(r: 83, g: 38, b: 214, a: 1)
+ }else {
+ submitButton.isEnabled = false
+ submitButton.backgroundColor = .init(r: 42, g: 42, b: 42, a: 1)
+ }
+ oneNumbersLabel.text = "\(text.count)/500"
+ return true
+ }
+ //pop回上一个控制器
+ @objc private func popVC(_ sender:UIButton) {
+ navigationController?.popViewController(animated: true)
+ }
+ //提交
+ @objc private func submitClick(_ sender:UIButton) {
+ //获取
+ let probleText = problemTextView.text
+ let contact = contactTextField.text
+ //获取设备唯一标识
+
+ //上传用户反馈的内容
+
+ //pop退出页面
+ navigationController?.popViewController(animated: true)
+ }
+}
diff --git a/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVC.swift b/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVC.swift
index b46b200..325f6c1 100644
--- a/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVC.swift
+++ b/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVC.swift
@@ -11,18 +11,13 @@ import Firebase
class MenuVC: BaseController,UITableViewDelegate,UITableViewDataSource {
static let kMenuVCCell_identifier = "kMenuVCCell_identifier"
- var dataSource:[[[String:String]]] {
+ var dataSource:[[[String:Any]]]{
get {
- return [[["image":"icon","title":NSLocalizedString("Share VPCamera", comment: "")],
- ["image":"icon","title":NSLocalizedString("Feedback", comment: "")]],
- [["image":"icon","title":NSLocalizedString("Privacy Policy", comment: "")],
- ["image":"icon","title":NSLocalizedString("Terms of Service", comment: "")]],
- [["image":"icon","title":NSLocalizedString("WeChat", comment: "")],
- ["image":"icon","title":NSLocalizedString("Tencent QQ", comment: "")],
- ["image":"icon","title":NSLocalizedString("Telegram", comment: "")],
- ["image":"icon","title":NSLocalizedString("Share VPCamera", comment: "")]]]
+ [getDatasourceOneSection(), getDatasourceTwoSection(), getDatasourceThreeSection()]
}
}
+
+
override func viewDidLoad() {
super.viewDidLoad()
self.configureUI()
@@ -62,9 +57,10 @@ class MenuVC: BaseController,UITableViewDelegate,UITableViewDataSource {
make.left.right.equalToSuperview()
make.height.equalTo(162)
}
-
+ //创建一个底部View(内置一个tableView)
let bottomView = buttomView()
self.view.addSubview(bottomView)
+ //覆盖主视图下半部分
bottomView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
make.bottom.equalToSuperview().offset(-20)
@@ -109,47 +105,141 @@ class MenuVC: BaseController,UITableViewDelegate,UITableViewDataSource {
func buttomView() -> UIView {
let bgView = UIView()
+ //创建tableView
let tableView = UITableView(frame: .zero, style: .insetGrouped)
+ //注册cell
tableView.register(MenuVCCell.classForCoder(), forCellReuseIdentifier: MenuVC.kMenuVCCell_identifier)
+ //将tableView添加入bgView
bgView.addSubview(tableView)
+ //tableView全覆盖
tableView.snp.makeConstraints { make in
- make.left.top.bottom.right.equalToSuperview()
+ make.top.bottom.equalToSuperview()
+ make.left.equalToSuperview().offset(24)
+ make.right.equalToSuperview().offset(-24)
}
- tableView.backgroundColor = .red
+ //实现tableView数据源和代理
+ tableView.dataSource = self
+ tableView.delegate = self
+ //颜色为透明
+ tableView.backgroundColor = .clear
return bgView
}
@objc func dismissVC(sender:UIButton) {
self.dismiss(animated: true)
}
-
-
-
- //MARK: - TableViewDelegate and DataSource
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 0
+ //数据源第一组(Share VPCamera And Feedback),key值为image、title
+ private func getDatasourceOneSection () -> [[String:Any]] {
+ return [
+ ["image":UIImage(named: "")!, "title":NSLocalizedString("v1.5_share vpcamera", comment: "")],
+ ["image":UIImage(named: "")!, "title":NSLocalizedString("v1.5_feedback", comment: "")]
+ ]
+ }
+ //数据源第二组(Privacy Policy And Terms of Service),key值为image、title
+ private func getDatasourceTwoSection () -> [[String:Any]] {
+ return [
+ ["image":UIImage(named: "")!, "title":NSLocalizedString("v1.5_privacy policy", comment: "")],
+ ["image":UIImage(named: "")!, "title":NSLocalizedString("v1.5_terms of service", comment: "")]
+ ]
+ }
+ //数据源第三组,网络获取,key值为 image、title、url
+ private func getDatasourceThreeSection () -> [[String:Any]] {
+ let url = URL(string: "XXXXXX")
+
+ return [
+ ["image":UIImage(named: ""), "title":"title", "url":"url"]
+ ]
}
+ //MARK: - TableViewDelegate and DataSource
func numberOfSections(in tableView: UITableView) -> Int {
- return 3
+ return dataSource.count
+ }
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return dataSource[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = tableView.dequeueReusableCell(withIdentifier: MenuVC.kMenuVCCell_identifier, for: indexPath)
+ let cell = tableView.dequeueReusableCell(withIdentifier: MenuVC.kMenuVCCell_identifier, for: indexPath) as! MenuVCCell
+ cell.data = dataSource[indexPath.section][indexPath.row]
+ if dataSource[indexPath.section].count == 1 {
+ //这一组只有一行
+ cell.radiusType = .all
+ }else {
+ switch indexPath.row {
+ case 0:
+ cell.radiusType = .top
+ case dataSource[indexPath.section].count - 1:
+ cell.radiusType = .bottom
+ default:
+ cell.radiusType = ._none
+ }
+ }
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
- 55
- }
-
- func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-
+ return 52
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
- return UIView()
+ let sectionView:UIView = .init(frame: .init(x: 0, y: 0, width: tableView.bounds.width, height: 54))
+ sectionView.backgroundColor = .clear
+ //添加一个Label
+ let titleLabel = UILabel()
+ titleLabel.textColor = .init(r: 255, g: 255, b: 255, a: 0.5)
+ titleLabel.text = section == 2 ? NSLocalizedString("v1.5_contact us", comment: ""):""
+ titleLabel.font = .systemFont(ofSize: 15, weight: .medium)
+ sectionView.addSubview(titleLabel)
+ titleLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().offset(-10)
+ make.left.equalToSuperview()
+ }
+ titleLabel.isHidden = !(section == 2)
+ return sectionView
+ }
+ func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
+ switch section {
+ case 0:
+ return 0
+ case dataSource[section].count - 1:
+ return 54
+ default:
+ return 18
+ }
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ switch indexPath.section {
+ case 0://第一组
+ switch indexPath.row {
+ case 0://Share VPCamera,执行分享
+ //设置分享文本
+ let text = "VPCamera"
+ //分享图片icon
+ let image = UIImage(named: "AppIcon")
+ //设置分享路径
+ let url = URL(string: "")
+ let activityItems = [text,image as Any,url as Any]
+ //弹出分享框
+ let activityViewController = UIActivityViewController(activityItems: activityItems, applicationActivities:nil)
+ present(activityViewController, animated: true, completion: nil)
+ //分享结束后的回调
+ activityViewController.completionWithItemsHandler = { [weak self] ( activityType, isCompleted, returnedItems, error) -> Void in
+ print(isCompleted ? "Share Success":"Share Failure")
+ }
+ default://反馈
+ let feedVC = FeedBackVC()
+ navigationController?.pushViewController(feedVC, animated: true)
+ }
+ case 1://第二组
+ switch indexPath.row {
+ case 0://Privacy Policy,执行隐私政策
+ break
+ default://Terms of Service, 执行服务条例
+ break
+ }
+ default://跳转组
+ break
+ }
}
-
-
}
diff --git a/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVCCell.swift b/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVCCell.swift
index 5898301..1f36206 100644
--- a/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVCCell.swift
+++ b/SwiftProject/SwiftProject/Project/Controller/MenuVC/MenuVCCell.swift
@@ -8,29 +8,91 @@
import Foundation
import UIKit
class MenuVCCell: UITableViewCell {
- var limgView:UIImageView?
- var ltitleLabel:UILabel?
+ //cell圆角类型
+ enum MenuVCCellCornerRadiusType:Int {
+ ///没有圆角
+ case _none = 0
+ ///上圆角
+ case top = 1
+ ///下圆角
+ case bottom = 2
+ ///全部圆角
+ case all = 3
+ ///对应切除范围
+ var maskcorners:CACornerMask {
+ switch self {
+ case ._none:
+ return []
+ case .top:
+ return [.layerMinXMinYCorner, .layerMaxXMinYCorner]
+ case .bottom:
+ return [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
+ case .all:
+ return [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
+ }
+ }
+ ///对应圆角度数
+ var corner:CGFloat{
+ switch self {
+ case ._none:
+ return 0
+ default:
+ return 12
+ }
+ }
+ }
+ //当前cell的圆角
+ var radiusType:MenuVCCellCornerRadiusType! {
+ didSet{
+ layer.maskedCorners = radiusType.maskcorners
+ layer.cornerRadius = radiusType.corner
+ }
+ }
+ //展示内容
+ var data:[String:Any]!{
+ didSet{
+ //获取图片
+ iconImageView.image = data["image"] as? UIImage
+ //设置标题
+ titleLabel.text = data["title"] as? String
+ }
+ }
+
+ //icon展示
+ fileprivate lazy var iconImageView:UIImageView = {
+ let imageView:UIImageView = .init()
+ imageView.contentMode = .scaleAspectFill
+ return imageView
+ }()
+ //标题Label
+ fileprivate lazy var titleLabel:UILabel = {
+ let label = UILabel()
+ label.textColor = .white
+ label.font = .systemFont(ofSize: 14, weight: .medium)
+ label.text = "Text"
+ return label
+ }()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
- self.backgroundColor = UIColor(r: 29, g: 29, b: 29, a: 1)
- limgView = UIImageView()
- self.contentView.addSubview(limgView!)
- ltitleLabel = UILabel()
- self.contentView.addSubview(ltitleLabel!)
-
- limgView?.snp.makeConstraints({ make in
- make.width.height.equalTo(20)
+ backgroundColor = UIColor(r: 29, g: 29, b: 29, a: 1)
+ selectionStyle = .none
+ //设置icon
+ addSubview(iconImageView)
+ iconImageView.snp.makeConstraints { make in
+ make.left.equalTo(16)
make.centerY.equalToSuperview()
- make.left.equalToSuperview().offset(16)
- })
-
- ltitleLabel?.snp.makeConstraints {[weak self] make in
- make.centerY.equalToSuperview()
- make.left.equalTo((self?.limgView!.snp.right)!).offset(12)
+ make.width.height.equalTo(16)
}
+ //设置标题Label
+ addSubview(titleLabel)
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalTo(12)
+ make.right.equalToSuperview().offset(-16)
+ }
+ //设置超出范围切除
+ layer.masksToBounds = true
- ltitleLabel!.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
- ltitleLabel!.font = UIFont(name: "PingFangSC-Medium", size: 14)
}
required init?(coder: NSCoder) {
diff --git a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayForVideoTask.swift b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayForVideoTask.swift
index b934c53..8b20b6d 100644
--- a/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayForVideoTask.swift
+++ b/SwiftProject/SwiftProject/Project/Controller/RecordingVideo/CCSpatialVideoDisplayController/CCSpatialVideoDisplayForVideoTask.swift
@@ -139,7 +139,6 @@ extension CCSpatialVideoDisplayController {
assetReader?.cancelReading()
}
assetReader = try! AVAssetReader(asset: self.videoOriginalAsset)
-
assetOutput = AVAssetReaderTrackOutput(
track: self.assetTrack!,
outputSettings: [
diff --git a/SwiftProject/SwiftProject/en.lproj/Localizable.strings b/SwiftProject/SwiftProject/en.lproj/Localizable.strings
index f9ba9fb..e1b90f0 100644
--- a/SwiftProject/SwiftProject/en.lproj/Localizable.strings
+++ b/SwiftProject/SwiftProject/en.lproj/Localizable.strings
@@ -121,3 +121,14 @@
"v1.5_praise" = "Praise";
"v1.5_negative" = "Negative";
"v1.5_feedbackdesc" = "Do you like VPCamera?\nPlease rate a Five star or give a feed\n back to us";
+//V1.5版本,用于功能集合页
+"v1.5_share vpcamera" = "Share VPCamera"
+"v1.5_feedback" = "Feedback"
+"v1.5_privacy policy" = "Privacy Policy"
+"v1.5_terms of service" = "Terms of Service"
+"v1.5_contact us" = "Contact us"
+"v1.5_problem/suggestion placeholder" = "Please let us kno'w your prablems or suggestions. Our service team will deal with it soon."
+"v1.5_problem/suggestion title" = "Problem/Suggestion description"
+"v1.5_contact information placeholder" = "Please @xxxx.com"
+"v1.5_contact information title" = "Contact information"
+"v1.5_submit" = "Submit"
diff --git a/SwiftProject/SwiftProject/zh-Hans.lproj/Localizable.strings b/SwiftProject/SwiftProject/zh-Hans.lproj/Localizable.strings
index 1a1e054..91648a1 100644
--- a/SwiftProject/SwiftProject/zh-Hans.lproj/Localizable.strings
+++ b/SwiftProject/SwiftProject/zh-Hans.lproj/Localizable.strings
@@ -117,7 +117,14 @@
"右侧中间键长按3s" = "右侧中间键长按3s";
"右侧亮度循环按键" ="右侧亮度循环按键\n长按 3s 切换 HSBS\n长按 7s 切换 FSBS";
-
-
-
-
+//V1.5版本,用于功能集合页
+"v1.5_share vpcamera" = "分享 VPCamera"
+"v1.5_feedback" = "反馈意见"
+"v1.5_privacy policy" = "隐私政策"
+"v1.5_terms of service" = "服务条款"
+"v1.5_contact us" = "联系我们"
+"v1.5_problem/suggestion title" = "问题/建议描述"
+"v1.5_problem/suggestion placeholder" = "请告知我们您的问题或建议。我们的服务团队将尽快处理。"
+"v1.5_contact information title" = "联系信息"
+"v1.5_contact information placeholder" = "请输入 @xxxx.com"
+"v1.5_submit" = "提交"