Commit 560ec868 authored by shenyong's avatar shenyong

Merge branch 'dev_main' into dev_syong

parents 83f33d9f 92bec182
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// LockSreen.swift // LockSreen.swift
// LockSreen // LockSreen
// //
// Created by edy on 2025/5/12. // Created by edy on 2025/5/19.
// //
import WidgetKit import WidgetKit
...@@ -115,3 +115,4 @@ struct lockArcShape: Shape { ...@@ -115,3 +115,4 @@ struct lockArcShape: Shape {
return path return path
} }
} }
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
// LockSreenBundle.swift // LockSreenBundle.swift
// LockSreen // LockSreen
// //
// Created by edy on 2025/5/12. // Created by edy on 2025/5/19.
// //
import WidgetKit import WidgetKit
import SwiftUI import SwiftUI
let kind: String = "LockSreen" let kind: String = "LockSreen"
let kind1: String = "LockSreen1" let kind1: String = "LockSreen1"
...@@ -56,3 +57,4 @@ struct LockBothSreen: Widget { ...@@ -56,3 +57,4 @@ struct LockBothSreen: Widget {
.supportedFamilies([.accessoryRectangular]) .supportedFamilies([.accessoryRectangular])
} }
} }
This diff is collapsed.
...@@ -54,6 +54,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ...@@ -54,6 +54,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
AdvManager.shared.initAdertisementSDK() AdvManager.shared.initAdertisementSDK()
PMEmailManager.shareManager.restore() PMEmailManager.shareManager.restore()
SettingConfiguration.share.initData() SettingConfiguration.share.initData()
HapticManager.share.setupHapticEngine()
// 相册基本资源加载 // 相册基本资源加载
PhotoManager.shared.config() PhotoManager.shared.config()
......
//
// PMAboutUsController.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import UIKit
import MessageUI
class PMAboutUsController: BaseViewController, MFMailComposeViewControllerDelegate {
@IBOutlet weak var despLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
titleView.model.title = "About Us"
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setConfigs()
addClick()
}
private func setConfigs() -> Void {
var mutableText:NSMutableAttributedString = NSMutableAttributedString(attributedString: despLabel.attributedText ?? NSMutableAttributedString(string: ""))
let paragraph = NSMutableParagraphStyle()
paragraph.lineSpacing = 2
mutableText.addAttributes([NSAttributedString.Key.paragraphStyle : paragraph], range: NSRange(location: 0, length: mutableText.length))
if let rang = mutableText.string.range(of: "OUR APPROACH") {
let startIndex = rang.lowerBound
let endIndex = rang.upperBound
let start = mutableText.string.distance(from: mutableText.string.startIndex, to: startIndex)
let end = mutableText.string.distance(from: mutableText.string.startIndex, to: endIndex)
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16, weight: .bold)], range: NSRange(location: start, length: end - start))
}
if let rang = mutableText.string.range(of: "apps.columbusdev.com") {
let startIndex = rang.lowerBound
let endIndex = rang.upperBound
let start = mutableText.string.distance(from: mutableText.string.startIndex, to: startIndex)
let end = mutableText.string.distance(from: mutableText.string.startIndex, to: endIndex)
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .regular),NSAttributedString.Key.foregroundColor:UIColor.colorWithHex(hexStr: "#0082FF"),.underlineStyle:NSUnderlineStyle.single.rawValue,.underlineColor:UIColor.colorWithHex(hexStr: "#0082FF")],
range: NSRange(location: start, length: end - start))
}
if let rang = mutableText.string.range(of: "ligaili1217@163.com") {
let startIndex = rang.lowerBound
let endIndex = rang.upperBound
let start = mutableText.string.distance(from: mutableText.string.startIndex, to: startIndex)
let end = mutableText.string.distance(from: mutableText.string.startIndex, to: endIndex)
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .regular),NSAttributedString.Key.foregroundColor:UIColor.colorWithHex(hexStr: "#0082FF"),.underlineStyle:NSUnderlineStyle.single.rawValue,.underlineColor:UIColor.colorWithHex(hexStr: "#0082FF")],
range: NSRange(location: start, length: end - start))
}
despLabel.attributedText = mutableText
}
private func addClick() -> Void {
let click = ["apps.columbusdev.com","ligaili1217@163.com"]
despLabel.AddTapped(click) {[weak self] text in
guard let self = self else { return }
if text == click[0] {
guard let url = URL(string: "https://apps.columbusdev.com/") else { return }
UIApplication.shared.open(url)
}else{
self.sendMail()
}
}
}
private func sendMail() -> Void {
let email = "ligaili1217@163.com"
let subject = ""//邮件主题
let body = ""//邮件正文
let defaultURL = URL(string: "mailto:\(email)?subject=\(subject)&body=\(body)")
let application = UIApplication.shared
if let url = defaultURL,application.canOpenURL(url) {
application.open(url)
}else{
print("Unable to send email")
PMAlert(title: nil, messsage: "", action: ["Ok"])
}
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: (any Error)?) {
controller.dismiss(animated: true)
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PMAboutUsController" customModule="PhoneManager" customModuleProvider="target">
<connections>
<outlet property="despLabel" destination="zuX-UN-ngF" id="z6D-sl-gOi"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tXM-qs-7LP">
<rect key="frame" x="16" y="139" width="361" height="679"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TrU-Y1-jr0">
<rect key="frame" x="0.0" y="0.0" width="361" height="583.33333333333337"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zuX-UN-ngF">
<rect key="frame" x="16" y="16" width="329" height="551.33333333333337"/>
<mutableString key="text">OUR APPROACH
Curiosity drives our exploration. Dedication fuels our efforts.Collaboration binds us together. At the core of everything we do are the people we serve.

We persevere through challenges and find joy in our shared progress. We recognize that collective wisdom surpasses individual insights.

We respect every voice, understanding that diverse perspectives enrich our work. We approach each task with open minds and a hunger to learn.

We know that excellence is achieved through consistent, incremental growth. We value clarity and simplicity in all we create. We stay flexible, ready to pivot when needed.

We welcome change as an opportunity to evolve and keep moving forward. We understand setbacks are stepping stones to success. We take risks, learn from failures, and use them as motivation to improve. We're committed to our unique way of working and making a difference. 

apps.columbusdev.com
ligaili1217@163.com

©2025 2025 Columbus Trading. All rights reserved.</mutableString>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.94901960784313721" green="0.96470588235294119" blue="0.9882352941176471" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="zuX-UN-ngF" firstAttribute="leading" secondItem="TrU-Y1-jr0" secondAttribute="leading" constant="16" id="GRf-GR-BeP"/>
<constraint firstAttribute="trailing" secondItem="zuX-UN-ngF" secondAttribute="trailing" constant="16" id="NQJ-41-oOR"/>
<constraint firstItem="zuX-UN-ngF" firstAttribute="top" secondItem="TrU-Y1-jr0" secondAttribute="top" constant="16" id="cXh-Xx-LFC"/>
<constraint firstAttribute="bottom" secondItem="zuX-UN-ngF" secondAttribute="bottom" constant="16" id="sCh-Wo-z7z"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="Radius">
<real key="value" value="12"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="TrU-Y1-jr0" secondAttribute="bottom" id="2Yf-R2-5ee"/>
<constraint firstAttribute="trailing" secondItem="TrU-Y1-jr0" secondAttribute="trailing" id="3P5-fh-O54"/>
<constraint firstItem="TrU-Y1-jr0" firstAttribute="top" secondItem="tXM-qs-7LP" secondAttribute="top" id="SSk-ev-Zpu"/>
<constraint firstItem="TrU-Y1-jr0" firstAttribute="centerX" secondItem="tXM-qs-7LP" secondAttribute="centerX" id="lV6-id-DLi"/>
<constraint firstItem="TrU-Y1-jr0" firstAttribute="leading" secondItem="tXM-qs-7LP" secondAttribute="leading" id="qgC-EG-fwb"/>
</constraints>
</scrollView>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="tXM-qs-7LP" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="80" id="7gF-2c-7Yc"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="tXM-qs-7LP" secondAttribute="bottom" id="PVp-uI-af2"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="tXM-qs-7LP" secondAttribute="trailing" constant="16" id="lbt-x9-4qq"/>
<constraint firstItem="tXM-qs-7LP" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="16" id="lu9-Zo-4Sa"/>
</constraints>
<point key="canvasLocation" x="131" y="-12"/>
</view>
</objects>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
...@@ -21,14 +21,12 @@ class CompressController : BaseViewController { ...@@ -21,14 +21,12 @@ class CompressController : BaseViewController {
private var compressNav:CompressNavView? private var compressNav:CompressNavView?
// 排序 // 排序
var currentSort : Int = 0 { var currentSort : ResouceSortType = .largest {
didSet{ didSet{
clearSelected() clearSelected()
} }
} }
// 资源类型 - 相册或者视频 // 资源类型 - 相册或者视频
var currentResourceType : CompressType = .compressPhoto var currentResourceType : CompressType = .compressPhoto
...@@ -122,22 +120,17 @@ class CompressController : BaseViewController { ...@@ -122,22 +120,17 @@ class CompressController : BaseViewController {
let datas = Singleton.shared.resourceModel let datas = Singleton.shared.resourceModel
if datas.count > 0 { if datas.count > 0 {
// 这里需要重新排序下 // 这里需要重新排序下
if self.currentSort == 0 { self.resourceData = datas
self.resourceData = datas.sorted {$0.assetSize > $1.assetSize } self.sortByType(sortType: self.currentSort)
}else if self.currentSort == 1 {
self.resourceData = datas.sorted {$0.assetSize < $1.assetSize }
}else if self.currentSort == 2 {
self.resourceData = datas.sorted {$0.createDate > $1.createDate }
}else{
self.resourceData = datas.sorted {$0.createDate < $1.createDate }
}
}else{ }else{
PMLoadingHUD.share.show() PMLoadingHUD.share.show("Loading...", "Please wait on the screen. This might take several minutes.")
CompressViewModel().getAllPhotosToAssets(sortType: self.currentSort, assetType: self.currentResourceType) { [weak self] models in CompressViewModel().getAllPhotosToAssets(sortType: self.currentSort, assetType: self.currentResourceType) { [weak self] models in
guard let self else {return} guard let self else {return}
self.resourceData = models self.resourceData = models
Singleton.shared.resourceModel = self.resourceData Singleton.shared.resourceModel = self.resourceData
PMLoadingHUD.share.disMiss() DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
PMLoadingHUD.share.disMiss()
}
} }
} }
} }
...@@ -238,20 +231,10 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo ...@@ -238,20 +231,10 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionHeader { if kind == UICollectionView.elementKindSectionHeader {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "CompressCustomHeaderView", for: indexPath) as! CompressCustomHeaderView let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "CompressCustomHeaderView", for: indexPath) as! CompressCustomHeaderView
header.callBack = {[weak self] text in header.sortViewSubmitCallBack = { [weak self] fileterModel in
guard let self else {return} guard let self else {return}
let sortView = CompressSortView(frame: self.view.bounds) self.currentSort = fileterModel.sortType
self.sortByType(sortType: self.currentSort)
// 这两行是为了进入页面的时候选中
sortView.currentIndex = self.currentSort
sortView.tableView.reloadData()
self.view.addSubview(sortView)
sortView.callBack = {[weak self] sortType in
guard let self else {return}
self.currentSort = sortType as! Int
self.sortByType(sortType: self.currentSort, header: header)
}
} }
header.changeView.callBack = {[weak self] flag in header.changeView.callBack = {[weak self] flag in
guard let self else {return} guard let self else {return}
...@@ -264,9 +247,13 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo ...@@ -264,9 +247,13 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
if self.currentResourceType == .compressPhoto { if self.currentResourceType == .compressPhoto {
self.getViewData() self.getViewData()
}else{ }else{
PMLoadingHUD.share.show("Loading...", "Please wait on the screen. This might take several minutes.")
CompressViewModel().getAllPhotosToAssets(sortType: self.currentSort, assetType: flag) { [weak self] models in CompressViewModel().getAllPhotosToAssets(sortType: self.currentSort, assetType: flag) { [weak self] models in
guard let self else {return} guard let self else {return}
self.resourceData = models self.resourceData = models
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
PMLoadingHUD.share.disMiss()
}
} }
} }
} }
...@@ -284,34 +271,21 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo ...@@ -284,34 +271,21 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
} }
} }
func sortByType(sortType:ResouceSortType){
func sortByType(sortType:Int,header:CompressCustomHeaderView){
let viewModel = CompressViewModel()
switch sortType { switch sortType {
case 0: case .largest:
header.selectlabel.text = "Largest" self.resourceData = self.resourceData.sorted { $0.assetSize > $1.assetSize }
// 按照文件大小降序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 1, sortKind: 0)
break break
case 1: case .smallest:
header.selectlabel.text = "Smallest" self.resourceData = self.resourceData.sorted { $0.assetSize < $1.assetSize }
// 按照文件大小升序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 0, sortKind: 0)
break break
case 2: case .latest:
header.selectlabel.text = "Newest" self.resourceData = self.resourceData.sorted { $0.createDate > $1.createDate }
// 按照时间降序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 1, sortKind: 1)
break break
case 3: case .oldest:
header.selectlabel.text = "Oldest" self.resourceData = self.resourceData.sorted { $0.createDate < $1.createDate }
// 按照时间升序
self.resourceData = viewModel.sortRsource(resource: self.resourceData, sortType: 0, sortKind: 1)
break
default:
break break
} }
} }
func updateSubmitButton(){ func updateSubmitButton(){
......
...@@ -9,7 +9,7 @@ import Foundation ...@@ -9,7 +9,7 @@ import Foundation
class CompressCustomHeaderView: UICollectionReusableView{ class CompressCustomHeaderView: UICollectionReusableView{
var callBack: callBack<Any> = {text in } var sortViewSubmitCallBack : (ResourceFilterBoxModel)->Void = {model in}
var modeData = [AssetModel]() { var modeData = [AssetModel]() {
didSet{ didSet{
...@@ -51,35 +51,21 @@ class CompressCustomHeaderView: UICollectionReusableView{ ...@@ -51,35 +51,21 @@ class CompressCustomHeaderView: UICollectionReusableView{
return label return label
}() }()
lazy var btnView :UIView = { // 筛选按钮
let view = UIView() lazy var filterButton : UIButton = {
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1) let button = UIButton(type: .custom)
view.layer.cornerRadius = 16 button.setImage(UIImage(named: "Frame 1"), for: .normal)
view.clipsToBounds = true button.setTitle("The largest", for: .normal)
button.layer.cornerRadius = 14
button.clipsToBounds = true
let tap = UITapGestureRecognizer() button.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 0.1000)
tap.addTarget(self, action: #selector(selectQulity)) button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
view.isUserInteractionEnabled = true button.setTitleColor(UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1), for: .normal)
view.addGestureRecognizer(tap) button.addTarget(self, action: #selector(filterButtonAction), for: .touchUpInside)
button.isHidden = false
return button
return view
}() }()
lazy var selectImageView :UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_newest_similar")
return view
}()
lazy var selectlabel :UILabel = {
let label = UILabel()
label.text = "Largest"
label.textAlignment = .center
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
return label
}()
lazy var siezLabel :UILabel = { lazy var siezLabel :UILabel = {
let label = UILabel() let label = UILabel()
label.text = "1.02 GB" label.text = "1.02 GB"
...@@ -128,9 +114,7 @@ class CompressCustomHeaderView: UICollectionReusableView{ ...@@ -128,9 +114,7 @@ class CompressCustomHeaderView: UICollectionReusableView{
private func setUI(){ private func setUI(){
self.addSubview(self.titlelabel) self.addSubview(self.titlelabel)
self.addSubview(self.btnView) self.addSubview(self.filterButton)
self.btnView.addSubview(self.selectImageView)
self.btnView.addSubview(self.selectlabel)
self.addSubview(self.siezLabel) self.addSubview(self.siezLabel)
self.addSubview(self.changeView) self.addSubview(self.changeView)
self.addSubview(self.tipView) self.addSubview(self.tipView)
...@@ -144,27 +128,17 @@ class CompressCustomHeaderView: UICollectionReusableView{ ...@@ -144,27 +128,17 @@ class CompressCustomHeaderView: UICollectionReusableView{
make.height.equalTo(28) make.height.equalTo(28)
} }
self.btnView.snp.makeConstraints { make in self.filterButton.snp.makeConstraints { make in
make.centerY.equalTo(self.titlelabel.snp.centerY)
make.right.equalToSuperview().offset(0) make.right.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(12) make.height.equalTo(28)
make.width.equalTo(103 * RScreenW()) make.width.equalTo(98)
make.height.equalTo(32)
}
self.selectImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.centerY.equalToSuperview()
make.width.height.equalTo(20)
}
self.selectlabel.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-12)
make.top.equalToSuperview().offset(6)
make.width.equalTo(60 * RScreenW())
make.height.equalTo(20)
} }
self.siezLabel.snp.makeConstraints { make in self.siezLabel.snp.makeConstraints { make in
make.left.equalTo(0) make.left.equalTo(0)
make.right.equalTo(0) make.right.equalTo(0)
make.top.equalTo(self.btnView.snp.bottom).offset(8) make.top.equalTo(self.filterButton.snp.bottom).offset(8)
make.height.equalTo(20) make.height.equalTo(20)
} }
self.changeView.snp.makeConstraints { make in self.changeView.snp.makeConstraints { make in
...@@ -193,10 +167,20 @@ class CompressCustomHeaderView: UICollectionReusableView{ ...@@ -193,10 +167,20 @@ class CompressCustomHeaderView: UICollectionReusableView{
} }
@objc func selectQulity(){ @objc func filterButtonAction(){
if let cWindow = cWindow {
let filterView : ResourceFilterBoxView = ResourceFilterBoxView.init(frame: cWindow.bounds)
callBack("selectedQulity") // 添加毛玻璃效果
cWindow.showBlur()
cWindow.addSubview(filterView)
filterView.submitCallBack = {model in
DispatchQueue.main.async {
self.filterButton.setTitle(model.sortType.rawValue, for: .normal)
}
self.sortViewSubmitCallBack(model)
}
}
} }
......
...@@ -67,7 +67,7 @@ class CompressViewModel{ ...@@ -67,7 +67,7 @@ class CompressViewModel{
/// 获取相册所有图片 /// 获取相册所有图片
/// - Returns: 图片信息 /// - Returns: 图片信息
func getAllPhotosToAssets(sortType: Int, assetType : CompressType,_ finished: @escaping Finished){ func getAllPhotosToAssets(sortType: ResouceSortType, assetType : CompressType,_ finished: @escaping Finished){
var models : [AssetModel] = [] var models : [AssetModel] = []
...@@ -108,11 +108,11 @@ class CompressViewModel{ ...@@ -108,11 +108,11 @@ class CompressViewModel{
group.leave() group.leave()
if count == assetsArray.count { if count == assetsArray.count {
// 默认按照文件大小排序 // 默认按照文件大小排序
if sortType == 0 { if sortType == .largest {
finished(models.sorted { $0.assetSize > $1.assetSize }) finished(models.sorted { $0.assetSize > $1.assetSize })
}else if sortType == 1 { }else if sortType == .smallest {
finished(models.sorted { $0.assetSize < $1.assetSize }) finished(models.sorted { $0.assetSize < $1.assetSize })
}else if sortType == 2 { }else if sortType == .latest {
finished(models.sorted { $0.createDate > $1.createDate }) finished(models.sorted { $0.createDate > $1.createDate })
}else{ }else{
finished(models.sorted { $0.createDate < $1.createDate }) finished(models.sorted { $0.createDate < $1.createDate })
...@@ -122,30 +122,7 @@ class CompressViewModel{ ...@@ -122,30 +122,7 @@ class CompressViewModel{
} }
} }
} }
/// 对资源进行排序
/// - Parameters:
/// - resource: 原资源
/// - sortType: 排序的类型,升序或者降序。0-升序,1-降序
/// - sortKind: 排序的种类 大小或者时间 0-大小,1-时间
/// - Returns: 返回排序结果
func sortRsource(resource:[AssetModel],sortType:Int,sortKind:Int)->[AssetModel]{
if sortKind == 0 {
if sortType == 0 {
return resource.sorted { $0.assetSize < $1.assetSize }
}else{
return resource.sorted { $0.assetSize > $1.assetSize }
}
}else{
if sortType == 0 {
return resource.sorted { $0.createDate < $1.createDate }
}else{
return resource.sorted { $0.createDate > $1.createDate }
}
}
}
/// 视频压缩 /// 视频压缩
/// - Parameters: /// - Parameters:
......
...@@ -138,7 +138,7 @@ extension ContactBackupDetailViewController:UITableViewDelegate,UITableViewDataS ...@@ -138,7 +138,7 @@ extension ContactBackupDetailViewController:UITableViewDelegate,UITableViewDataS
let sectionTitle = sectionTitles[indexPath.section] let sectionTitle = sectionTitles[indexPath.section]
let contact = sectionedContacts[sectionTitle]?[indexPath.row] let contact = sectionedContacts[sectionTitle]?[indexPath.row]
cell.model = contact cell.model = contact
cell.nameLabel.text = contact?.fullName cell.nameLabel.text = contact?.fullName.count ?? 0 > 0 ? contact?.fullName : "Untitled contact person"
return cell return cell
} }
......
...@@ -140,7 +140,7 @@ extension ContactAllView : UITableViewDataSource,UITableViewDelegate { ...@@ -140,7 +140,7 @@ extension ContactAllView : UITableViewDataSource,UITableViewDelegate {
let sectionTitle = sectionTitles[indexPath.section] let sectionTitle = sectionTitles[indexPath.section]
let contact = sectionedContacts[sectionTitle]?[indexPath.row] let contact = sectionedContacts[sectionTitle]?[indexPath.row]
cell.model = contact cell.model = contact
cell.nameLabel.text = contact?.fullName cell.nameLabel.text = contact?.fullName.count ?? 0 > 0 ? contact?.fullName : "Untitled contact person"
if self.selectedContacts.contains(where: { $0.identifier == contact!.identifier }) { if self.selectedContacts.contains(where: { $0.identifier == contact!.identifier }) {
cell.selectButton.isSelected = true cell.selectButton.isSelected = true
}else { }else {
......
...@@ -159,7 +159,7 @@ extension ContactNormalIncomView : UITableViewDataSource,UITableViewDelegate { ...@@ -159,7 +159,7 @@ extension ContactNormalIncomView : UITableViewDataSource,UITableViewDelegate {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomContactAllViewTableViewCell", for: indexPath) as! CustomContactAllViewTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: "CustomContactAllViewTableViewCell", for: indexPath) as! CustomContactAllViewTableViewCell
let contact = self.dataSourceModel[indexPath.row] let contact = self.dataSourceModel[indexPath.row]
cell.model = contact cell.model = contact
cell.nameLabel.text = contact.fullName cell.nameLabel.text = contact.fullName.count > 0 ? contact.fullName : "Untitled contact person"
if self.selectedContacts.contains(where: { $0.identifier == contact.identifier }) { if self.selectedContacts.contains(where: { $0.identifier == contact.identifier }) {
cell.selectButton.isSelected = true cell.selectButton.isSelected = true
}else { }else {
......
//
// PMEmailSupportCell.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import UIKit
class PMEmailSupportCell: UITableViewCell {
static let id = "PMEmailSupportCell"
@IBOutlet weak var esLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
var data:FAQDataModel? {
didSet{
esLabel.text = data?.problem ?? ""
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="123" id="KGk-i7-Jjw" customClass="PMEmailSupportCell" customModule="PhoneManager" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="358" height="123"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="358" height="123"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4SX-Xi-udm">
<rect key="frame" x="0.0" y="0.0" width="358" height="113"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="How can I recover deleted photos or videos?" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6bs-U1-uqM">
<rect key="frame" x="16" y="16" width="286" height="81"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="24" id="KBB-uU-vBe"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
<color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="icon_left_setting_grey" translatesAutoresizingMaskIntoConstraints="NO" id="eLs-7W-DBt">
<rect key="frame" x="318" y="46.666666666666664" width="20" height="19.999999999999993"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="5pq-Lw-7Bh"/>
<constraint firstAttribute="height" constant="20" id="EcB-PY-v2P"/>
</constraints>
</imageView>
</subviews>
<color key="backgroundColor" red="0.94901960784313721" green="0.96470588235294119" blue="0.9882352941176471" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="eLs-7W-DBt" firstAttribute="centerY" secondItem="4SX-Xi-udm" secondAttribute="centerY" id="C0l-FW-4EX"/>
<constraint firstItem="6bs-U1-uqM" firstAttribute="top" secondItem="4SX-Xi-udm" secondAttribute="top" constant="16" id="GDj-00-bNe"/>
<constraint firstAttribute="trailing" secondItem="eLs-7W-DBt" secondAttribute="trailing" constant="20" id="HAG-83-qxo"/>
<constraint firstAttribute="bottom" secondItem="6bs-U1-uqM" secondAttribute="bottom" constant="16" id="aE0-zU-2xe"/>
<constraint firstItem="6bs-U1-uqM" firstAttribute="leading" secondItem="4SX-Xi-udm" secondAttribute="leading" constant="16" id="hZh-1Y-B5K"/>
<constraint firstItem="eLs-7W-DBt" firstAttribute="leading" secondItem="6bs-U1-uqM" secondAttribute="trailing" constant="16" id="nGx-nB-DAR"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="Radius">
<real key="value" value="12"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="4SX-Xi-udm" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="ClS-G3-1nM"/>
<constraint firstItem="4SX-Xi-udm" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="doE-qG-Em3"/>
<constraint firstAttribute="bottom" secondItem="4SX-Xi-udm" secondAttribute="bottom" constant="10" id="g8u-yZ-V1p"/>
<constraint firstAttribute="trailing" secondItem="4SX-Xi-udm" secondAttribute="trailing" id="iXi-hr-caF"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<color key="backgroundColor" red="0.94901960784313721" green="0.96470588235294119" blue="0.9882352941176471" alpha="1" colorSpace="calibratedRGB"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="Radius">
<real key="value" value="12"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="esLabel" destination="6bs-U1-uqM" id="o8k-8Q-cLR"/>
</connections>
<point key="canvasLocation" x="158.77862595419847" y="16.549295774647888"/>
</tableViewCell>
</objects>
<resources>
<image name="icon_left_setting_grey" width="20" height="20"/>
</resources>
</document>
//
// PMEmailSupportController.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import UIKit
import MessageUI
class PMEmailSupportController: BaseViewController {
@IBOutlet weak var emailTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
titleView.model.title = "Email support"
setup()
}
func setup() -> Void {
emailTableView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview().inset(marginLR)
make.top.equalTo(titleView.snp.bottom).offset(10)
}
emailTableView.sectionHeaderHeight = 40
if #available(iOS 15.0, *) {
emailTableView.sectionHeaderTopPadding = 0
} else {
// Fallback on earlier versions
}
emailTableView.register(UINib(nibName: PMEmailSupportCell.id, bundle: nil), forCellReuseIdentifier: PMEmailSupportCell.id)
emailTableView.showsVerticalScrollIndicator = false
let file = Bundle.main.bundleURL.appendingPathComponent("PMEmailSupportData.json")
do{
let dictData = try Data(contentsOf: file)
dataSource = try JSONDecoder().decode([FAQDataModel].self, from: dictData)
}catch{ }
}
var dataSource:[FAQDataModel] = [] {
didSet {
self.emailTableView.reloadData()
}
}
}
extension PMEmailSupportController : UITableViewDelegate,UITableViewDataSource,MFMailComposeViewControllerDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PMEmailSupportCell.id, for: indexPath) as! PMEmailSupportCell
cell.selectionStyle = .none
cell.data = dataSource[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = UILabel()
header.text = "Please select a request from the following list."
header.textColor = UIColor.colorWithHex(hexStr: "#999999")
header.font = UIFont.systemFont(ofSize: 12)
header.backgroundColor = .white
return header
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let data = dataSource[indexPath.row]
if data.problem != "Other" {
let support = PMEmailSupportDetailController()
support.data = data
self.navigationController?.pushViewController(support, animated: true)
}else{
if MFMailComposeViewController.canSendMail() {
let mail = MFMailComposeViewController()
mail.mailComposeDelegate = self
mail.setSubject("My PhoneManager Experience")
mail.setToRecipients(["ligaili1217@163.com"]) // 收件人地址
let body = String(format: "\n\n%@. iOS %@.%@\n%@", UIDevice.current.detailedModel,UIDevice.current.systemVersion,UIDevice.current.version(),UIDevice.current.identifierForVendor?.uuidString ?? "")
mail.setMessageBody(body, isHTML: false)
self.present(mail, animated: true, completion: nil)
} else {
print("无法发送邮件")
PMAlert(title: nil, messsage: "Unable to send email", action: ["Ok"])
}
}
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: (any Error)?) {
controller.dismiss(animated: true)
}
}
extension UIDevice {
var detailedModel: String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
return machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
}
func version() -> String {
let infoDictionary = Bundle.main.infoDictionary
let appVersion = infoDictionary?["CFBundleShortVersionString"] as? String ?? "" // 版本号
let buildNumber = infoDictionary?["CFBundleVersion"] as? String ?? "" // 构建号
return String(format: "App version:%@(%@)",appVersion ,buildNumber)
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PMEmailSupportController" customModule="PhoneManager" customModuleProvider="target">
<connections>
<outlet property="emailTableView" destination="MCG-EC-mOS" id="PTm-bW-gx1"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="MCG-EC-mOS">
<rect key="frame" x="15" y="80" width="363" height="691"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<connections>
<outlet property="dataSource" destination="-1" id="sPO-YK-o5T"/>
<outlet property="delegate" destination="-1" id="VjH-qj-Jd5"/>
</connections>
</tableView>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<point key="canvasLocation" x="117" y="-11"/>
</view>
</objects>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
//
// PMEmailSupportDetailController.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import UIKit
class PMEmailSupportDetailController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
setuup()
}
var data:FAQDataModel?
private func setuup() -> Void {
scroll.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview().inset(marginLR)
make.top.equalTo(titleView.snp.bottom).offset(20)
}
tl.snp.makeConstraints { make in
make.left.top.equalToSuperview()
make.width.equalToSuperview()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tl.text = data?.problem ?? ""
let attribued = addattribed()
self.view.layoutIfNeeded()
let bound = attribued.boundingRect(with: CGSizeMake(view.width - marginLR * 2 - 16 * 2, .infinity), options: .usesLineFragmentOrigin, context: nil)
textView.attributedText = attribued
textView.snp.makeConstraints { make in
make.left.right.equalTo(tl)
make.top.equalTo(tl.snp.bottom).offset(10)
make.height.equalTo(bound.height+(marginLR * 2 + 16 * 2 + 10))
}
DispatchQueue.main.async {
self.scroll.contentSize = CGSizeMake(0, CGRectGetMaxY(self.textView.frame))
}
}
private lazy var tl: UILabel = {
let l = UILabel()
l.font = UIFont.systemFont(ofSize: 14, weight: .bold)
l.textColor = UIColor.colorWithHex(hexStr: "#333333")
l.numberOfLines = 0
scroll.addSubview(l)
return l
}()
private lazy var textView: UITextView = {
let tv = UITextView()
tv.isUserInteractionEnabled = false
tv.Radius = 12
tv.backgroundColor = UIColor.colorWithHex(hexStr: "#F2F6FC")
tv.textContainerInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
scroll.addSubview(tv)
return tv
}()
private lazy var scroll: UIScrollView = {
let s = UIScrollView()
s.showsVerticalScrollIndicator = false
s.contentInsetAdjustmentBehavior = .never
view.addSubview(s)
return s
}()
private func addattribed() -> NSMutableAttributedString {
let mutableText = NSMutableAttributedString(string: data?.answer ?? "")
let param = NSMutableParagraphStyle()
param.lineSpacing = 5
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .regular),.paragraphStyle:param], range: NSRange(location: 0, length: mutableText.length))
let rangs = data?.bold ?? []
let famat = NSSet(array: rangs)
for text in famat {
if let rang = mutableText.string.range(of: text as! String) {
let startIndex = rang.lowerBound
let endIndex = rang.upperBound
let start = mutableText.string.distance(from: mutableText.string.startIndex, to: startIndex)
let end = mutableText.string.distance(from: mutableText.string.startIndex, to: endIndex)
if end < (data?.answer.count ?? 0) {
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .bold)], range: NSRange(location: start, length: end - start))
}
}
}
return mutableText
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PMEmailSupportDetailController" customModuleProvider="target">
<connections>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
</view>
</objects>
</document>
[
{
"problem":"How to Recover Deleted Photos or Videos?",
"answer":"If you accidentally delete photos or videos through PhoneManager cleanup, iOS will temporarily store them in the \"Recently Deleted\" album for 30 days (they still occupy storage space during this period). To recover: Open the Photos app on your iPhone, go to the \"Recently Deleted\" album, tap \"Select\" in the top-right corner, check the files you need, then tap \"Recover\"; for batch recovery, directly tap \"Recover All\". Note that this album contains both manually deleted files and PhoneManager-cleaned content, and the system will permanently erase them after 30 days. Act promptly to avoid data loss.",
"bold":["\"Recently Deleted\" album","30 days","Photos","\"Select\"","\"Recover All\"","both manually deleted files and PhoneManager-cleaned content","permanently erase them after 30 days"]
},
{
"problem":"Why Isn’t Storage Space Freed Up After Cleanup?",
"answer":"Due to iOS system limitations, photos/videos deleted via PhoneManager are temporarily stored in the \"Recently Deleted\" album for 30 days (they continue to occupy storage space during this period). To free up space immediately, manually empty the album: Open the Photos app on your iPhone, go to the \"Recently Deleted\" album, tap \"Select\" > \"Delete All\" in the top-right corner to permanently remove files. Note that this action will delete both manually removed content and PhoneManager-cleaned files, and data cannot be recovered. Ensure no important files remain before proceeding.",
"bold":["\"Recently Deleted\" album" , "30 days","Photos","\"Select\"" , "\"Delete All\"","both manually removed content and PhoneManager-cleaned files","data cannot be recovered"]
},
{
"problem":"How to Cancel Subscription?",
"answer":"Since subscription management and payment processes are exclusively controlled by Apple to ensure account security, cancel your PhoneManager subscription via these steps: Open iPhone Settings, tap your Apple ID profile at the top, go to Subscriptions, select PhoneManager, then tap Cancel Subscription. This will stop auto-renewal, but you can continue using the service until the current subscription period ends.",
"bold":["exclusively controlled by Apple","Apple ID profile","Subscriptions","PhoneManager","Cancel Subscription"]
},
{
"problem":"Why Can't I Allow PhoneManager to Access My Photos?",
"answer":"If the \"Allow Photo Access\" option is missing in settings, it may be due to Screen Time restrictions enabling permission controls. Adjust as follows: Open iPhone Settings, go to Screen Time > Content & Privacy Restrictions > Photos, and ensure Allow Changes is enabled. Afterward, force close and restart PhoneManager to reactivate the permission request. This action will not compromise existing photo data security—permission adjustments are solely for optimizing app functionality interactions.",
"bold":["Screen Time restrictions","iPhone Settings","Screen Time > Content & Privacy Restrictions > Photos","Allow Changes","will not compromise existing photo data security"]
},
{
"problem":"Other",
"answer":"",
"bold":[]
}
]
...@@ -43,27 +43,9 @@ class PMFAQCell: UITableViewCell { ...@@ -43,27 +43,9 @@ class PMFAQCell: UITableViewCell {
} }
private func addattribed() -> NSMutableAttributedString { private func addattribed() -> NSMutableAttributedString {
var mutableText = NSMutableAttributedString(string: data?.answer ?? "") let mutableText = NSMutableAttributedString(string: data?.answer ?? "")
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .semibold)], range: NSRange(location: 0, length: mutableText.length)) mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .regular)], range: NSRange(location: 0, length: mutableText.length))
let rangs = ["PhoneManager", let rangs = data?.bold ?? []
"face recognition",
"similar photo comparison",
"edited/favorited status",
"Best Result",
"only with iPhones running iOS 14 or later",
"App Store's subscription terms and conditions",
"Settings",
"Apple ID profile","Subscriptions",
"Cancel Subscription",
"automatic scanning and analysis",
"only on recent additions or changes","Similar",
"within seconds of each other",
"same subject/person","consistent background","Best Result",
"favorites","Other","do not fit predefined classifications","interactive swiping mechanism",
"left","right","tap any item","creation date","red checkmark icon",
"Delete","Keep List","Move to Trash","trash bin icon","swiping feature","Videos","swipe left",
"swipe right","resource-intensive","by size or creation date","smart algorithms","final approval",
"explicit approval","offline processing","no personal data or photo content","Keep All","Settings icon","Media Library","Unkeep"]
let famat = NSSet(array: rangs) let famat = NSSet(array: rangs)
for text in famat { for text in famat {
if let rang = mutableText.string.range(of: text as! String) { if let rang = mutableText.string.range(of: text as! String) {
...@@ -71,7 +53,9 @@ class PMFAQCell: UITableViewCell { ...@@ -71,7 +53,9 @@ class PMFAQCell: UITableViewCell {
let endIndex = rang.upperBound let endIndex = rang.upperBound
let start = mutableText.string.distance(from: mutableText.string.startIndex, to: startIndex) let start = mutableText.string.distance(from: mutableText.string.startIndex, to: startIndex)
let end = mutableText.string.distance(from: mutableText.string.startIndex, to: endIndex) let end = mutableText.string.distance(from: mutableText.string.startIndex, to: endIndex)
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .bold)], range: NSRange(location: start, length: end)) if end < (data?.answer.count ?? 0) {
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .bold)], range: NSRange(location: start, length: end - start))
}
} }
} }
return mutableText return mutableText
......
...@@ -71,7 +71,7 @@ extension PMFAQController : UITableViewDelegate,UITableViewDataSource { ...@@ -71,7 +71,7 @@ extension PMFAQController : UITableViewDelegate,UITableViewDataSource {
let current = openSet let current = openSet
openSet = indexPath.row openSet = indexPath.row
indexpaths = [indexPath] indexpaths = [indexPath]
if current > 0 { if current >= 0 {
indexpaths.append(IndexPath(row: current, section: 0)) indexpaths.append(IndexPath(row: current, section: 0))
} }
} }
...@@ -82,6 +82,7 @@ extension PMFAQController : UITableViewDelegate,UITableViewDataSource { ...@@ -82,6 +82,7 @@ extension PMFAQController : UITableViewDelegate,UITableViewDataSource {
struct FAQDataModel : Codable { struct FAQDataModel : Codable {
var problem:String var problem:String
var answer:String var answer:String
var bold:[String]?
init(problem: String, answer: String) { init(problem: String, answer: String) {
self.problem = problem self.problem = problem
self.answer = answer self.answer = answer
......
...@@ -313,6 +313,11 @@ class HomeInfoViewController:BaseViewController { ...@@ -313,6 +313,11 @@ class HomeInfoViewController:BaseViewController {
titleView.model.title = "" titleView.model.title = ""
showTipsVC() showTipsVC()
self.tablewView.keepAllNoDataCallBack = {
self.ids = []
self.setDefaultPage()
}
} }
......
...@@ -23,6 +23,7 @@ class PhotoDetailViewController : BaseViewController { ...@@ -23,6 +23,7 @@ class PhotoDetailViewController : BaseViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
self.view.addSubview(self.closeButton) self.view.addSubview(self.closeButton)
self.closeButton.snp.makeConstraints { make in self.closeButton.snp.makeConstraints { make in
......
...@@ -77,6 +77,9 @@ class PhotoRemoveViewController: BaseViewController { ...@@ -77,6 +77,9 @@ class PhotoRemoveViewController: BaseViewController {
// MARK: - 生命周期 // MARK: - 生命周期
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
formatter.dateStyle = .medium formatter.dateStyle = .medium
formatter.timeStyle = .none formatter.timeStyle = .none
if let type = self.mediaType { if let type = self.mediaType {
...@@ -295,7 +298,8 @@ class PhotoRemoveViewController: BaseViewController { ...@@ -295,7 +298,8 @@ class PhotoRemoveViewController: BaseViewController {
photoView.mediaType = self.mediaType photoView.mediaType = self.mediaType
photoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan))) photoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan)))
view.addSubview(photoView) view.addSubview(photoView)
photoView.frame = CGRectMake(15, statusBarHeight + 44, self.view.width - 30, self.view.height - 78 - safeHeight - statusBarHeight - 44) photoView.frame = CGRectMake(0, 0, self.view.width - 30, 509 * RScreenH())
photoView.center = self.view.center
photoViews.append(photoView) photoViews.append(photoView)
} }
...@@ -405,7 +409,6 @@ class PhotoRemoveViewController: BaseViewController { ...@@ -405,7 +409,6 @@ class PhotoRemoveViewController: BaseViewController {
if actualTranslation.x < 0 { if actualTranslation.x < 0 {
// 删除操作,先存到单利 // 删除操作,先存到单利
self.vibrate() self.vibrate()
saveDataToDBAndSigtonTrash() saveDataToDBAndSigtonTrash()
} }
...@@ -471,7 +474,8 @@ class PhotoRemoveViewController: BaseViewController { ...@@ -471,7 +474,8 @@ class PhotoRemoveViewController: BaseViewController {
private func resetViewPosition(_ view: PhotosRemoveBaseView) { private func resetViewPosition(_ view: PhotosRemoveBaseView) {
UIView.animate(withDuration: 0.3) { UIView.animate(withDuration: 0.3) {
view.transform = .identity view.transform = .identity
view.frame = CGRectMake(15, statusBarHeight + 44, self.view.width - 30, self.view.height - 78 - safeHeight - statusBarHeight - 44) view.frame = CGRectMake(0, 0, self.view.width - 30, 509 * RScreenH())
view.center = self.view.center
view.hideButtons() view.hideButtons()
} }
} }
...@@ -488,7 +492,8 @@ class PhotoRemoveViewController: BaseViewController { ...@@ -488,7 +492,8 @@ class PhotoRemoveViewController: BaseViewController {
// 创建新视图并更新内容 // 创建新视图并更新内容
let newView = PhotosRemoveBaseView() let newView = PhotosRemoveBaseView()
newView.frame = CGRectMake(15, statusBarHeight + 44, self.view.width - 30, self.view.height - 78 - safeHeight - statusBarHeight - 44) newView.frame = CGRectMake(0, 0, self.view.width - 30, 509 * RScreenH())
newView.center = self.view.center
newView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan))) newView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan)))
newView.alpha = 0 newView.alpha = 0
view.addSubview(newView) view.addSubview(newView)
...@@ -547,16 +552,6 @@ class PhotoRemoveViewController: BaseViewController { ...@@ -547,16 +552,6 @@ class PhotoRemoveViewController: BaseViewController {
} }
} }
} }
@objc func popCurrentPage(){
}
deinit { deinit {
NotificationCenter.default.removeObserver(self) NotificationCenter.default.removeObserver(self)
} }
......
//
// HomeDetailDeleteView.swift
// PhoneManager
//
// Created by edy on 2025/5/19.
//
import UIKit
class HomeDetailDeleteView: UIView {
var deleteCallBack:(()->Void) = {}
lazy var deleteButton : UIButton = {
let view = UIButton()
view.setTitle("Delete", for: UIControl.State.normal)
view.setTitleColor(.white, for: .normal)
view.clipsToBounds = true
view.layer.cornerRadius = 23
view.backgroundColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
view.addTarget(self, action: #selector(deleteButtonAction), for: .touchUpInside)
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .white
self.addSubview(self.deleteButton)
self.deleteButton.snp.makeConstraints { make in
make.top.equalToSuperview().offset(16)
make.left.equalToSuperview().offset(15)
make.right.equalToSuperview().offset(-15)
make.height.equalTo(46)
}
}
@objc func deleteButtonAction(){
self.deleteCallBack()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
...@@ -13,12 +13,16 @@ class HomeInfoView :UIView { ...@@ -13,12 +13,16 @@ class HomeInfoView :UIView {
var titleText : String? var titleText : String?
var isDragEnd : Bool = false
var type : PhotsFileType? var type : PhotsFileType?
var models:[HomeInfoTableItem] = [] var models:[HomeInfoTableItem] = []
var callBack:callBack<Any> = {text in} var callBack:callBack<Any> = {text in}
var keepAllNoDataCallBack : ()->Void = {}
var deleteCallBack:callBack<[AssetModel]> = {array in } var deleteCallBack:callBack<[AssetModel]> = {array in }
var titleShowHideCallBack:callBack<Bool> = {isShow in} var titleShowHideCallBack:callBack<Bool> = {isShow in}
...@@ -42,6 +46,7 @@ class HomeInfoView :UIView { ...@@ -42,6 +46,7 @@ class HomeInfoView :UIView {
lazy var headerView:HomeInfoTitleView = { lazy var headerView:HomeInfoTitleView = {
let sview:HomeInfoTitleView = HomeInfoTitleView(frame: CGRect(x: 0, y: 0, width: width, height: 84)) let sview:HomeInfoTitleView = HomeInfoTitleView(frame: CGRect(x: 0, y: 0, width: width, height: 84))
sview.titleLabel.text = self.titleText sview.titleLabel.text = self.titleText
sview.type = self.type
sview.filterButton.isHidden = self.type != .similar && self.type != .SimilarVideos sview.filterButton.isHidden = self.type != .similar && self.type != .SimilarVideos
return sview return sview
}() }()
...@@ -308,6 +313,7 @@ class HomeInfoView :UIView { ...@@ -308,6 +313,7 @@ class HomeInfoView :UIView {
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: deleteView.isHidden ? 12 : deleteView.height + 12 , right: 0) tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: deleteView.isHidden ? 12 : deleteView.height + 12 , right: 0)
self.nextRowButton.isHidden = !self.isShowNextRowButton() self.nextRowButton.isHidden = !self.isShowNextRowButton()
} }
} }
...@@ -315,45 +321,28 @@ class HomeInfoView :UIView { ...@@ -315,45 +321,28 @@ class HomeInfoView :UIView {
extension HomeInfoView:UITableViewDataSource,UITableViewDelegate { extension HomeInfoView:UITableViewDataSource,UITableViewDelegate {
@objc func nextRowButtonAction(){ @objc func nextRowButtonAction(){
self.tableScrollToNextRow() self.tableScrollToNextRow()
} }
// 重新设置models
func resetModels(){
var newArray : [HomeInfoTableItem] = []
for array in ids ?? [] {
var smodels:[ImageSeletedCollectionItem] = []
for id in array {
let smodel = ImageSeletedCollectionItem()
smodel.id = id
smodel.isSeleted = false
smodels.append(smodel)
}
let smodel = HomeInfoTableItem()
smodel.type = type
smodel.smodels = smodels
smodel.titleText = titleText
newArray.append(smodel)
}
self.models = newArray
}
/// 让表格自动滚动一行 /// 让表格自动滚动一行
private func tableScrollToNextRow() { private func tableScrollToNextRow() {
guard let indexPath = tableView.indexPathsForVisibleRows?.first else { return } guard let indexPath = tableView.indexPathsForVisibleRows?.first else { return }
let nextRow = indexPath.row + 1 // let nextRow = self.isDragEnd == true ? indexPath.row + 1 : indexPath.row + 2
let nextRow = indexPath.row + 2
let nextSection = indexPath.section let nextSection = indexPath.section
// 获取最后一个cell 看看是不是存在
guard let lastIndexPath = tableView.indexPathsForVisibleRows?.last else {return}
let lastNextRow = lastIndexPath.row + 1
guard lastNextRow < tableView.numberOfRows(inSection: nextSection) else {
// 滚动到最底部
tableView.scrollToRow(at: lastIndexPath, at: .bottom, animated: true)
return
}
// 检查下一行是否存在 // 检查下一行是否存在
guard nextRow < tableView.numberOfRows(inSection: nextSection) else { return } guard nextRow < tableView.numberOfRows(inSection: nextSection) else { return }
...@@ -370,6 +359,7 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate { ...@@ -370,6 +359,7 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate {
// 直接滚动到调整后的位置 // 直接滚动到调整后的位置
tableView.setContentOffset(adjustedOffset, animated: true) tableView.setContentOffset(adjustedOffset, animated: true)
self.isDragEnd = false
} }
func scrollViewDidScroll(_ scrollView: UIScrollView) { func scrollViewDidScroll(_ scrollView: UIScrollView) {
...@@ -386,6 +376,10 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate { ...@@ -386,6 +376,10 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate {
tableView.bringSubviewToFront(self.headerView) tableView.bringSubviewToFront(self.headerView)
} }
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
self.isDragEnd = true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return models.count return models.count
...@@ -394,10 +388,25 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate { ...@@ -394,10 +388,25 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: HomeInfoTableViewCell.identifier, for: indexPath) as! HomeInfoTableViewCell let cell = tableView.dequeueReusableCell(withIdentifier: HomeInfoTableViewCell.identifier, for: indexPath) as! HomeInfoTableViewCell
cell.saveKeepListFinishedCallback = { cell.saveKeepListFinishedCallback = {[weak self] index in
self.ids?.remove(at: indexPath.section) guard let self else {return}
self.resetModels() self.ids?.remove(at: index.section)
tableView.deleteRows(at: [indexPath], with: .automatic) self.models.remove(at: index.section)
DispatchQueue.main.async {
self.setTitleView()
}
// 禁用动画
UIView.performWithoutAnimation {
tableView.beginUpdates()
tableView.deleteRows(at: [index], with: .fade)
tableView.endUpdates()
}
if let data = self.ids {
if data.count <= 0 {
self.keepAllNoDataCallBack()
}
}
} }
cell.type = self.type cell.type = self.type
...@@ -439,10 +448,10 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate { ...@@ -439,10 +448,10 @@ extension HomeInfoView:UITableViewDataSource,UITableViewDelegate {
for item in orgModels { for item in orgModels {
var array = item var array = item
if startDate != nil { if startDate != nil {
array = array.filter({$0.createDate > startDate!}) array = array.filter({$0.createDate >= startDate!})
} }
if endDate != nil { if endDate != nil {
array = array.filter({$0.createDate < endDate!}) array = array.filter({$0.createDate <= endDate!})
} }
if array.count >= 2 { if array.count >= 2 {
...@@ -490,6 +499,8 @@ class HomeInfoTitleView:UIView { ...@@ -490,6 +499,8 @@ class HomeInfoTitleView:UIView {
var sortViewSubmitCallBack : (ResourceFilterBoxModel)->Void = {model in} var sortViewSubmitCallBack : (ResourceFilterBoxModel)->Void = {model in}
var type : PhotsFileType?
lazy var titleLabel:UILabel = { lazy var titleLabel:UILabel = {
let sview:UILabel = UILabel() let sview:UILabel = UILabel()
...@@ -567,7 +578,12 @@ class HomeInfoTitleView:UIView { ...@@ -567,7 +578,12 @@ class HomeInfoTitleView:UIView {
let allNumberStr = "\(allNumber)" let allNumberStr = "\(allNumber)"
let seletedCountStr = "\(seletedCount)" let seletedCountStr = "\(seletedCount)"
let fullText = allNumberStr + " photos · \(seletedCountStr) selected" var fullText = "0 photos · 0 selected"
if self.type == .SimilarVideos {
fullText = allNumberStr + " videos · \(seletedCountStr) selected"
}else {
fullText = allNumberStr + " photos · \(seletedCountStr) selected"
}
let attributedString2 = NSMutableAttributedString(string: fullText, attributes: [ let attributedString2 = NSMutableAttributedString(string: fullText, attributes: [
......
...@@ -9,7 +9,7 @@ import Foundation ...@@ -9,7 +9,7 @@ import Foundation
class HomePhotosDetailCustomHeaderView : UICollectionReusableView { class HomePhotosDetailCustomHeaderView : UICollectionReusableView {
var sortCallback : ()->Void = {} var sortViewSubmitCallBack : (ResourceFilterBoxModel)->Void = {model in}
lazy var modelTitlelabel :UILabel = { lazy var modelTitlelabel :UILabel = {
let label = UILabel() let label = UILabel()
...@@ -20,33 +20,22 @@ class HomePhotosDetailCustomHeaderView : UICollectionReusableView { ...@@ -20,33 +20,22 @@ class HomePhotosDetailCustomHeaderView : UICollectionReusableView {
return label return label
}() }()
lazy var btnView :UIView = { // 筛选按钮
let view = UIView() lazy var filterButton : UIButton = {
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1) let button = UIButton(type: .custom)
view.layer.cornerRadius = 16 button.setImage(UIImage(named: "Frame 1"), for: .normal)
view.clipsToBounds = true button.setTitle("The largest", for: .normal)
button.layer.cornerRadius = 14
let tap = UITapGestureRecognizer() button.clipsToBounds = true
tap.addTarget(self, action: #selector(sortAction)) button.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 0.1000)
view.isUserInteractionEnabled = true button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
view.addGestureRecognizer(tap) button.setTitleColor(UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1), for: .normal)
button.addTarget(self, action: #selector(filterButtonAction), for: .touchUpInside)
return view button.isHidden = false
return button
}() }()
lazy var selectImageView :UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_newest_similar")
return view
}()
lazy var selectlabel :UILabel = {
let label = UILabel()
label.text = "Largest"
label.textAlignment = .center
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
return label
}()
lazy var countLabel :UILabel = { lazy var countLabel :UILabel = {
let label = UILabel() let label = UILabel()
label.text = "0 Photos" label.text = "0 Photos"
...@@ -59,43 +48,26 @@ class HomePhotosDetailCustomHeaderView : UICollectionReusableView { ...@@ -59,43 +48,26 @@ class HomePhotosDetailCustomHeaderView : UICollectionReusableView {
private func setUI(){ private func setUI(){
self.addSubview(self.modelTitlelabel) self.addSubview(self.modelTitlelabel)
self.addSubview(self.btnView)
self.addSubview(self.countLabel) self.addSubview(self.countLabel)
self.addSubview(self.filterButton)
self.btnView.addSubview(self.selectImageView)
self.btnView.addSubview(self.selectlabel)
self.modelTitlelabel.snp.makeConstraints { make in self.modelTitlelabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(0) make.left.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(14) make.top.equalToSuperview().offset(14)
make.width.equalTo(150 * RScreenW()) make.width.equalTo(150 * RScreenW())
make.height.equalTo(28) make.height.equalTo(28)
} }
self.filterButton.snp.makeConstraints { make in
self.btnView.snp.makeConstraints { make in make.centerY.equalTo(self.modelTitlelabel.snp.centerY)
make.right.equalToSuperview().offset(0) make.right.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(12) make.height.equalTo(28)
make.width.equalTo(103 * RScreenW()) make.width.equalTo(98)
make.height.equalTo(32)
}
self.selectImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.centerY.equalToSuperview()
make.width.height.equalTo(20)
}
self.selectlabel.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-12)
make.top.equalToSuperview().offset(6)
make.width.equalTo(60 * RScreenW())
make.height.equalTo(20)
} }
self.countLabel.snp.makeConstraints { make in self.countLabel.snp.makeConstraints { make in
make.left.equalTo(0) make.left.equalTo(0)
make.right.equalTo(0) make.right.equalTo(0)
make.top.equalTo(self.btnView.snp.bottom).offset(8) make.top.equalTo(self.filterButton.snp.bottom).offset(8)
make.height.equalTo(20) make.height.equalTo(20)
} }
} }
...@@ -112,7 +84,19 @@ class HomePhotosDetailCustomHeaderView : UICollectionReusableView { ...@@ -112,7 +84,19 @@ class HomePhotosDetailCustomHeaderView : UICollectionReusableView {
setUI() setUI()
} }
@objc func sortAction(){ @objc func filterButtonAction(){
sortCallback() if let cWindow = cWindow {
let filterView : ResourceFilterBoxView = ResourceFilterBoxView.init(frame: cWindow.bounds)
// 添加毛玻璃效果
cWindow.showBlur()
cWindow.addSubview(filterView)
filterView.submitCallBack = {model in
DispatchQueue.main.async {
self.filterButton.setTitle(model.sortType.rawValue, for: .normal)
}
self.sortViewSubmitCallBack(model)
}
}
} }
} }
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import Foundation import Foundation
class HomeVideoDetailCustomHeaderView : UICollectionReusableView { class HomeVideoDetailCustomHeaderView : UICollectionReusableView {
var sortCallback : ()->Void = {} var sortViewSubmitCallBack : (ResourceFilterBoxModel)->Void = {model in}
lazy var modelTitlelabel :UILabel = { lazy var modelTitlelabel :UILabel = {
let label = UILabel() let label = UILabel()
...@@ -18,34 +18,19 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView { ...@@ -18,34 +18,19 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView {
label.font = UIFont.systemFont(ofSize: 20, weight: .bold) label.font = UIFont.systemFont(ofSize: 20, weight: .bold)
return label return label
}() }()
// 筛选按钮
lazy var btnView :UIView = { lazy var filterButton : UIButton = {
let view = UIView() let button = UIButton(type: .custom)
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1) button.setImage(UIImage(named: "Frame 1"), for: .normal)
view.layer.cornerRadius = 16 button.setTitle("The largest", for: .normal)
view.clipsToBounds = true button.layer.cornerRadius = 14
button.clipsToBounds = true
button.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 0.1000)
let tap = UITapGestureRecognizer() button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
tap.addTarget(self, action: #selector(sortAction)) button.setTitleColor(UIColor(red: 0.07, green: 0.07, blue: 0.07, alpha: 1), for: .normal)
view.isUserInteractionEnabled = true button.addTarget(self, action: #selector(filterButtonAction), for: .touchUpInside)
view.addGestureRecognizer(tap) button.isHidden = false
return button
return view
}()
lazy var selectImageView :UIImageView = {
let view = UIImageView()
view.image = UIImage(named: "ic_newest_similar")
return view
}()
lazy var selectlabel :UILabel = {
let label = UILabel()
label.text = "Largest"
label.textAlignment = .center
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
return label
}() }()
lazy var sizeLabel :UILabel = { lazy var sizeLabel :UILabel = {
let label = UILabel() let label = UILabel()
...@@ -56,72 +41,14 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView { ...@@ -56,72 +41,14 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView {
return label return label
}() }()
// lazy var tipBackView :UIView = {
// let view = UIView()
// view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
// view.layer.cornerRadius = 8
// view.clipsToBounds = true
// return view
// }()
// lazy var tipImageView :UIImageView = {
// let view = UIImageView()
// view.image = UIImage(named: "ic_cmpress_home_nor")
// return view
// }()
//
// lazy var tipLabel :UILabel = {
// let label = UILabel()
// label.text = "Video Compress"
// label.textAlignment = .left
// label.numberOfLines = 0
// label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
// return label
// }()
//
// lazy var tipDetailLabel :UILabel = {
// let label = UILabel()
// label.text = "Tap to start the process"
// label.textAlignment = .left
// label.numberOfLines = 0
// label.textColor = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1)
// label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
// return label
// }()
//
// lazy var saveSizeLabel :UILabel = {
// let label = UILabel()
// label.text = "13.5M"
// label.textAlignment = .right
// label.textColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
// label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
// return label
// }()
//
// lazy var moreImageView :UIImageView = {
// let view = UIImageView()
// view.image = UIImage(named: "icon_left_setting_grey")
// return view
// }()
private func setUI(){ private func setUI(){
self.addSubview(self.modelTitlelabel) self.addSubview(self.modelTitlelabel)
self.addSubview(self.btnView) self.addSubview(self.filterButton)
self.addSubview(self.sizeLabel) self.addSubview(self.sizeLabel)
self.btnView.addSubview(self.selectImageView)
self.btnView.addSubview(self.selectlabel)
// self.addSubview(self.tipBackView)
// self.tipBackView.addSubview(self.tipImageView)
// self.tipBackView.addSubview(self.tipLabel)
// self.tipBackView.addSubview(self.tipDetailLabel)
// self.tipBackView.addSubview(self.saveSizeLabel)
// self.tipBackView.addSubview(self.moreImageView)
self.modelTitlelabel.snp.makeConstraints { make in self.modelTitlelabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(0) make.left.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(14) make.top.equalToSuperview().offset(14)
...@@ -129,31 +56,23 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView { ...@@ -129,31 +56,23 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView {
make.height.equalTo(28) make.height.equalTo(28)
} }
self.btnView.snp.makeConstraints { make in
make.right.equalToSuperview().offset(0)
make.top.equalToSuperview().offset(12)
make.width.equalTo(103 * RScreenW())
make.height.equalTo(32)
}
self.selectImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.centerY.equalToSuperview()
make.width.height.equalTo(20)
}
self.selectlabel.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-12)
make.top.equalToSuperview().offset(6)
make.width.equalTo(60 * RScreenW())
make.height.equalTo(20)
}
self.sizeLabel.snp.makeConstraints { make in self.sizeLabel.snp.makeConstraints { make in
make.left.equalTo(0) make.left.equalTo(0)
make.right.equalTo(0) make.right.equalTo(0)
make.top.equalTo(self.btnView.snp.bottom).offset(8) make.top.equalTo(self.filterButton.snp.bottom).offset(8)
make.height.equalTo(20) make.height.equalTo(20)
} }
self.filterButton.snp.makeConstraints { make in
make.centerY.equalTo(self.modelTitlelabel.snp.centerY)
make.right.equalToSuperview().offset(0)
make.height.equalTo(28)
make.width.equalTo(98)
}
addSubview(compressionTipView) addSubview(compressionTipView)
compressionTipView.snp.makeConstraints { make in compressionTipView.snp.makeConstraints { make in
...@@ -164,47 +83,6 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView { ...@@ -164,47 +83,6 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView {
let tap = UITapGestureRecognizer(target: self, action: #selector(compressClick)) let tap = UITapGestureRecognizer(target: self, action: #selector(compressClick))
compressionTipView.addGestureRecognizer(tap) compressionTipView.addGestureRecognizer(tap)
// self.tipBackView.snp.makeConstraints { make in
// make.left.equalTo(0)
// make.right.equalTo(0)
// make.top.equalTo(self.sizeLabel.snp.bottom).offset(12)
// make.height.equalTo(70)
// }
//
// self.tipImageView.snp.makeConstraints { make in
// make.left.equalToSuperview().offset(15)
// make.centerY.equalToSuperview()
// make.width.height.equalTo(30)
//
// }
// self.tipLabel.snp.makeConstraints { make in
// make.left.equalTo(self.tipImageView.snp.right).offset(10)
// make.width.equalTo(150 * RScreenW())
// make.height.equalTo(22)
// make.top.equalToSuperview().offset(15)
// }
// self.tipDetailLabel.snp.makeConstraints { make in
// make.left.equalTo(self.tipImageView.snp.right).offset(10)
// make.width.equalTo(150 * RScreenW())
// make.height.equalTo(18)
// make.top.equalTo(self.tipLabel.snp.bottom).offset(0)
// }
//
// self.moreImageView.snp.makeConstraints { make in
// make.height.width.equalTo(20)
// make.right.equalToSuperview().offset(-15)
// make.centerY.equalToSuperview()
// }
//
// self.saveSizeLabel.snp.makeConstraints { make in
// make.centerY.equalToSuperview()
// make.right.equalTo(self.moreImageView.snp.left).offset(-10)
// make.height.equalTo(28)
// make.width.equalTo(100)
// }
} }
override init(frame: CGRect) { override init(frame: CGRect) {
...@@ -219,8 +97,20 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView { ...@@ -219,8 +97,20 @@ class HomeVideoDetailCustomHeaderView : UICollectionReusableView {
setUI() setUI()
} }
@objc func sortAction(){ @objc func filterButtonAction(){
sortCallback() if let cWindow = cWindow {
let filterView : ResourceFilterBoxView = ResourceFilterBoxView.init(frame: cWindow.bounds)
// 添加毛玻璃效果
cWindow.showBlur()
cWindow.addSubview(filterView)
filterView.submitCallBack = {model in
DispatchQueue.main.async {
self.filterButton.setTitle(model.sortType.rawValue, for: .normal)
}
self.sortViewSubmitCallBack(model)
}
}
} }
lazy var compressionTipView:VideocompressionHeadView = { lazy var compressionTipView:VideocompressionHeadView = {
......
...@@ -56,6 +56,7 @@ class PhotosRemoveBaseView: UIView { ...@@ -56,6 +56,7 @@ class PhotosRemoveBaseView: UIView {
self.imageView.isUserInteractionEnabled = true self.imageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer() let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(showDeatail)) tap.addTarget(self, action: #selector(showDeatail))
imageView.backgroundColor = .white
self.imageView.addGestureRecognizer(tap) self.imageView.addGestureRecognizer(tap)
} }
......
...@@ -118,10 +118,15 @@ class ResourceFilterBoxView : UIView { ...@@ -118,10 +118,15 @@ class ResourceFilterBoxView : UIView {
setUpUI() setUpUI()
} }
func getMonthEn(month: Int )-> String{ func getMonthEn(month: Int) -> String {
// 检查输入是否在有效范围内(1-12)
guard (1...12).contains(month) else {
return "Invalid Month" // 或抛出错误
}
let formatter = DateFormatter() let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US") formatter.locale = Locale(identifier: "en_US")
return formatter.monthSymbols[month] return formatter.monthSymbols[month - 1]
} }
override func removeFromSuperview() { override func removeFromSuperview() {
...@@ -240,6 +245,7 @@ class ResourceFilterBoxView : UIView { ...@@ -240,6 +245,7 @@ class ResourceFilterBoxView : UIView {
components.year = year components.year = year
components.month = month components.month = month
components.day = 1 // 设置为当月第一天 components.day = 1 // 设置为当月第一天
components.timeZone = TimeZone(identifier: "UTC")
// 使用公历日历 // 使用公历日历
let calendar = Calendar(identifier: .gregorian) let calendar = Calendar(identifier: .gregorian)
...@@ -260,6 +266,7 @@ class ResourceFilterBoxView : UIView { ...@@ -260,6 +266,7 @@ class ResourceFilterBoxView : UIView {
components.year = nextYear components.year = nextYear
components.month = nextMonth components.month = nextMonth
components.day = 1 components.day = 1
components.timeZone = TimeZone(identifier: "UTC")
let calendar = Calendar(identifier: .gregorian) let calendar = Calendar(identifier: .gregorian)
guard let nextMonthFirstDay = calendar.date(from: components) else { guard let nextMonthFirstDay = calendar.date(from: components) else {
...@@ -318,7 +325,6 @@ class ResourceFilterBoxView : UIView { ...@@ -318,7 +325,6 @@ class ResourceFilterBoxView : UIView {
self.startDateButton.dateButton.setTitle("From \(self.getMonthEn(month: month)) \(year)", for: .normal) self.startDateButton.dateButton.setTitle("From \(self.getMonthEn(month: month)) \(year)", for: .normal)
self.startDateButton.closeButton.isHidden = false self.startDateButton.closeButton.isHidden = false
self.startDate = self.dateFrom(year: year, month: month) self.startDate = self.dateFrom(year: year, month: month)
}else { }else {
self.endDateButton.dateButton.setTitle("To \(self.getMonthEn(month: month)) \(year)", for: .normal) self.endDateButton.dateButton.setTitle("To \(self.getMonthEn(month: month)) \(year)", for: .normal)
self.endDateButton.closeButton.isHidden = false self.endDateButton.closeButton.isHidden = false
......
...@@ -9,6 +9,8 @@ import UIKit ...@@ -9,6 +9,8 @@ import UIKit
class TrashSubView: UIView { class TrashSubView: UIView {
var type : TrashTypeEnum?
var clearTashDataCallBack : ()->Void = {} var clearTashDataCallBack : ()->Void = {}
var presentTashDetailViewClickCallBack : ()->Void = {} var presentTashDetailViewClickCallBack : ()->Void = {}
...@@ -32,7 +34,7 @@ class TrashSubView: UIView { ...@@ -32,7 +34,7 @@ class TrashSubView: UIView {
let button = UIButton(type: .custom) let button = UIButton(type: .custom)
button.setImage(UIImage(named: "ic_delete_duplicates"), for: .normal) button.setImage(UIImage(named: "ic_delete_duplicates"), for: .normal)
button.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1) button.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
button.setTitle("Empty the garbage", for: .normal) button.setTitle("Empty Trash", for: .normal)
button.setTitleColor(.white, for: .normal) button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .semibold) button.titleLabel?.font = UIFont.systemFont(ofSize: 12, weight: .semibold)
button.layer.cornerRadius = 19 button.layer.cornerRadius = 19
...@@ -43,6 +45,8 @@ class TrashSubView: UIView { ...@@ -43,6 +45,8 @@ class TrashSubView: UIView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
self.addTopShadow()
// 给当前视图添加手势 // 给当前视图添加手势
addTapGestureToSelf() addTapGestureToSelf()
......
...@@ -146,14 +146,14 @@ extension YearMonthPickerView: UIPickerViewDataSource, UIPickerViewDelegate { ...@@ -146,14 +146,14 @@ extension YearMonthPickerView: UIPickerViewDataSource, UIPickerViewDelegate {
} }
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return component == 0 ? months[row] : "\(years.reversed()[row])" return component == 0 ? months[row] : "\(years[row])"
} }
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component == 0 { if component == 0 {
selectedMonth = row selectedMonth = row
} else { } else {
selectedYear = years.reversed()[row] selectedYear = years[row]
} }
} }
...@@ -161,4 +161,13 @@ extension YearMonthPickerView: UIPickerViewDataSource, UIPickerViewDelegate { ...@@ -161,4 +161,13 @@ extension YearMonthPickerView: UIPickerViewDataSource, UIPickerViewDelegate {
return component == 0 ? self.width/2 : self.width/2 return component == 0 ? self.width/2 : self.width/2
} }
private var currentYear: Int {
return Calendar.current.component(.year, from: Date())
}
private var currentMonth: Int {
return Calendar.current.component(.month, from: Date())
}
} }
...@@ -24,7 +24,7 @@ class HomeInfoTableViewCell:UITableViewCell { ...@@ -24,7 +24,7 @@ class HomeInfoTableViewCell:UITableViewCell {
var callBack:callBack<Any> = {text in} var callBack:callBack<Any> = {text in}
var saveKeepListFinishedCallback : ()->Void = {} var saveKeepListFinishedCallback : (IndexPath)->Void = {index in}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
...@@ -119,7 +119,6 @@ class HomeInfoTableViewCell:UITableViewCell { ...@@ -119,7 +119,6 @@ class HomeInfoTableViewCell:UITableViewCell {
UIView.transition(with: collectionView!, duration: 0.3, options: .transitionCrossDissolve, animations: { UIView.transition(with: collectionView!, duration: 0.3, options: .transitionCrossDissolve, animations: {
self.collectionView?.reloadData() self.collectionView?.reloadData()
// self.reloadCollectionView()
}, completion: nil) }, completion: nil)
} }
} }
...@@ -224,7 +223,7 @@ extension HomeInfoTableViewCell:UICollectionViewDelegate,UICollectionViewDataSou ...@@ -224,7 +223,7 @@ extension HomeInfoTableViewCell:UICollectionViewDelegate,UICollectionViewDataSou
cell.keepAllCallBack = { cell.keepAllCallBack = {
//存到保留列表 //存到保留列表
saveAllDataToKeepList() saveAllDataToKeepList()
self.saveKeepListFinishedCallback() self.saveKeepListFinishedCallback(indexPath)
} }
// 存全部数据到保留列表 // 存全部数据到保留列表
func saveAllDataToKeepList(){ func saveAllDataToKeepList(){
......
...@@ -21,7 +21,8 @@ class PMLoadingHUD{ ...@@ -21,7 +21,8 @@ class PMLoadingHUD{
func show(_ title:String = "Deleting...",_ subTitle:String = "Please wait on the screen. This might take several minutes."){ func show(_ title:String = "Deleting...",_ subTitle:String = "Please wait on the screen. This might take several minutes."){
disMiss() disMiss()
DispatchQueue.main.async { DispatchQueue.main.async {
KEYWINDOW()?.addSubview(self.loadingView) cWindow?.addSubview(self.loadingView)
cWindow?.bringSubviewToFront(self.loadingView)
self.loadingView.setTitleaAndSubTitle(title: title, subTitle: subTitle) self.loadingView.setTitleaAndSubTitle(title: title, subTitle: subTitle)
self.loadingView.animationView.play() self.loadingView.animationView.play()
} }
......
...@@ -70,6 +70,7 @@ class PMShowImgCell: UICollectionViewCell { ...@@ -70,6 +70,7 @@ class PMShowImgCell: UICollectionViewCell {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
setup() setup()
backgroundColor = .clear
clipsToBounds = true clipsToBounds = true
} }
......
...@@ -51,6 +51,8 @@ class PMShowImgVideoController: BaseViewController { ...@@ -51,6 +51,8 @@ class PMShowImgVideoController: BaseViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
...@@ -92,6 +94,7 @@ class PMShowImgVideoController: BaseViewController { ...@@ -92,6 +94,7 @@ class PMShowImgVideoController: BaseViewController {
col.delegate = self; col.delegate = self;
col.dataSource = self; col.dataSource = self;
col.showsHorizontalScrollIndicator = false col.showsHorizontalScrollIndicator = false
col.backgroundColor = .clear
col.isPagingEnabled = true col.isPagingEnabled = true
col.register(PMShowImgCell.self, forCellWithReuseIdentifier: PMShowImgCellID) col.register(PMShowImgCell.self, forCellWithReuseIdentifier: PMShowImgCellID)
col.register(PMShowVideoCell.self, forCellWithReuseIdentifier: PMShowVideoCellID) col.register(PMShowVideoCell.self, forCellWithReuseIdentifier: PMShowVideoCellID)
...@@ -108,6 +111,7 @@ class PMShowImgVideoController: BaseViewController { ...@@ -108,6 +111,7 @@ class PMShowImgVideoController: BaseViewController {
let col = UICollectionView(frame: CGRect(), collectionViewLayout: flowlayout) let col = UICollectionView(frame: CGRect(), collectionViewLayout: flowlayout)
col.delegate = self; col.delegate = self;
col.dataSource = self; col.dataSource = self;
col.register(PMShowItemCell.self, forCellWithReuseIdentifier: PMShowItemCellID) col.register(PMShowItemCell.self, forCellWithReuseIdentifier: PMShowItemCellID)
col.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "UICollectionViewCell") col.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "UICollectionViewCell")
col.showsHorizontalScrollIndicator = false col.showsHorizontalScrollIndicator = false
......
...@@ -249,22 +249,28 @@ class SecretViewController: BaseViewController { ...@@ -249,22 +249,28 @@ class SecretViewController: BaseViewController {
AdvManager.shared.finisedCallBack = { AdvManager.shared.finisedCallBack = {
self.AddAction = SecretActionView() self.AddAction = SecretActionView()
self.AddAction.show(); self.AddAction.show();
self.view.showBlur()
self.AddAction.callback = { idx in self.AddAction.callback = { idx in
self.view.hideBlur()
self.AddImagePicker(idx) self.AddImagePicker(idx)
} }
} }
}else { }else {
self.AddAction = SecretActionView() self.AddAction = SecretActionView()
self.view.showBlur()
self.AddAction.show(); self.AddAction.show();
self.AddAction.callback = { idx in self.AddAction.callback = { idx in
self.view.hideBlur()
self.AddImagePicker(idx) self.AddImagePicker(idx)
} }
} }
}else { }else {
self.AddAction = SecretActionView() self.AddAction = SecretActionView()
self.view.showBlur()
self.AddAction.show(); self.AddAction.show();
self.AddAction.callback = { idx in self.AddAction.callback = { idx in
self.view.hideBlur()
self.AddImagePicker(idx) self.AddImagePicker(idx)
} }
} }
...@@ -320,6 +326,7 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo ...@@ -320,6 +326,7 @@ extension SecretViewController : UICollectionViewDelegate,UICollectionViewDataSo
cell.isSelect = selectArray.contains((indexPath.row)) cell.isSelect = selectArray.contains((indexPath.row))
cell.imageText = dataSource[indexPath.row] cell.imageText = dataSource[indexPath.row]
cell.callback = { [weak self] in cell.callback = { [weak self] in
self?.vibrate()
self?.selectImgVideo(indexPath.row) self?.selectImgVideo(indexPath.row)
} }
return cell return cell
......
...@@ -8,17 +8,21 @@ ...@@ -8,17 +8,21 @@
import UIKit import UIKit
import SnapKit import SnapKit
class SecretActionView: UIViewController { class SecretActionView: UIViewController ,UIViewControllerTransitioningDelegate {
private var selectedViewBottomConstraint: Constraint? private var selectedViewBottomConstraint: Constraint?
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
view.backgroundColor = .colorWithHex(hexStr: "#000000", alpha: 0.5) view.backgroundColor = .clear//.colorWithHex(hexStr: "#000000", alpha: 0.5)
self.transitioningDelegate = self;
setUI() setUI()
addTapAction() addTapAction()
} }
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return customDismissAnimator()
}
/// 添加背景点击消失 /// 添加背景点击消失
func addTapAction(){ func addTapAction(){
...@@ -80,6 +84,7 @@ class SecretActionView: UIViewController { ...@@ -80,6 +84,7 @@ class SecretActionView: UIViewController {
var callback:((_ idx:Int)->Void)? var callback:((_ idx:Int)->Void)?
@objc private func actionTouch(_ sender:UIButton) -> Void { @objc private func actionTouch(_ sender:UIButton) -> Void {
self.dismiss(animated: true) self.dismiss(animated: true)
guard callback != nil else { guard callback != nil else {
return return
...@@ -89,13 +94,17 @@ class SecretActionView: UIViewController { ...@@ -89,13 +94,17 @@ class SecretActionView: UIViewController {
} }
@objc private func touchDismiss(){ @objc private func touchDismiss(){
UIView.animate(withDuration: 0.2) { // UIView.animate(withDuration: 0.2) {
// 更新约束 // // 更新约束
self.selectedViewBottomConstraint?.update(offset: 1000) // self.selectedViewBottomConstraint?.update(offset: 1000)
self.view.layoutIfNeeded() // self.view.layoutIfNeeded()
}completion: { _ in // }completion: { _ in
self.dismiss(animated: true) self.dismiss(animated: true)
guard callback != nil else {
return
} }
callback!(0x12)
// }
} }
...@@ -136,7 +145,7 @@ class SecretActionView: UIViewController { ...@@ -136,7 +145,7 @@ class SecretActionView: UIViewController {
let carma = UIButton(type: .custom) let carma = UIButton(type: .custom)
carma.setImage(UIImage(named: "ic_video_secret"), for: .normal) carma.setImage(UIImage(named: "ic_video_secret"), for: .normal)
carma.backgroundColor = .colorWithHex(hexStr: "#F2F6FC") carma.backgroundColor = .colorWithHex(hexStr: "#F2F6FC")
carma.titleLabel?.font = UIFont.systemFont(ofSize: 16) carma.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
carma.contentHorizontalAlignment = .leading carma.contentHorizontalAlignment = .leading
carma.layer.cornerRadius = 12 carma.layer.cornerRadius = 12
carma.tag = 0x10; carma.tag = 0x10;
...@@ -153,7 +162,7 @@ class SecretActionView: UIViewController { ...@@ -153,7 +162,7 @@ class SecretActionView: UIViewController {
let Photo = UIButton(type: .custom) let Photo = UIButton(type: .custom)
Photo.setImage(UIImage(named: "ic_photo_secret"), for: .normal) Photo.setImage(UIImage(named: "ic_photo_secret"), for: .normal)
Photo.backgroundColor = .colorWithHex(hexStr: "#F2F6FC") Photo.backgroundColor = .colorWithHex(hexStr: "#F2F6FC")
Photo.titleLabel?.font = UIFont.systemFont(ofSize: 16) Photo.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
Photo.contentHorizontalAlignment = .leading Photo.contentHorizontalAlignment = .leading
Photo.layer.cornerRadius = 12 Photo.layer.cornerRadius = 12
Photo.tag = 0x11; Photo.tag = 0x11;
......
...@@ -46,12 +46,10 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -46,12 +46,10 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
self.titleView.titleLabel.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1) self.titleView.titleLabel.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
modelData = getSettingViewInfo() modelData = getSettingViewInfo()
self.view.addSubview(tableView) self.view.addSubview(tableView)
self.tableView.reloadData()
} }
override func viewWillDisappear(_ animated: Bool) { override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated) super.viewWillDisappear(animated)
self.tableView.reloadData()
} }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
...@@ -176,11 +174,27 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -176,11 +174,27 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
case settingLabels.RemoveAfterImport.rawValue: case settingLabels.RemoveAfterImport.rawValue:
SettingConfiguration.share.config.removeImg = !SettingConfiguration.share.config.removeImg SettingConfiguration.share.config.removeImg = !SettingConfiguration.share.config.removeImg
tableView.reloadRows(at: [indexPath], with: .none) tableView.reloadRows(at: [indexPath], with: .none)
tableView.reloadData()
vibrate() vibrate()
break break
case settingLabels.Widgets.rawValue: case settingLabels.Widgets.rawValue:
let widget = WidgetViewController() var callblock:(()->Void) = {[weak self] in
self.navigationController?.pushViewController(widget, animated: true) guard let self = self else { return }
let widget = WidgetViewController()
self.navigationController?.pushViewController(widget, animated: true)
}
if AdvManager.shared.advTimeAfterInAPP <= 0{
if IAPManager.share.isSubscribed == false {
AdvManager.shared.showInterstitialAd(vc: self)
}else{
callblock()
}
}else {
callblock()
}
AdvManager.shared.finisedCallBack = {
callblock()
}
break break
case settingLabels.FollowonInstagram.rawValue: case settingLabels.FollowonInstagram.rawValue:
guard let url = URL(string: "https://www.instagram.com/phone.manager.app/") else { return } guard let url = URL(string: "https://www.instagram.com/phone.manager.app/") else { return }
...@@ -203,12 +217,15 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -203,12 +217,15 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
case settingLabels.Vibration.rawValue: case settingLabels.Vibration.rawValue:
SettingConfiguration.share.config.vibration = !(SettingConfiguration.share.config.vibration ?? false) SettingConfiguration.share.config.vibration = !(SettingConfiguration.share.config.vibration ?? false)
tableView.reloadRows(at: [indexPath], with: .none) tableView.reloadRows(at: [indexPath], with: .none)
tableView.reloadData()
vibrate(true) vibrate(true)
break break
case settingLabels.Resumepurchase.rawValue: case settingLabels.Resumepurchase.rawValue:
break break
case settingLabels.EmailSupport.rawValue: case settingLabels.EmailSupport.rawValue:
let emailSupport = PMEmailSupportController()
self.navigationController?.pushViewController(emailSupport, animated: true)
break break
case settingLabels.FAQ.rawValue: case settingLabels.FAQ.rawValue:
...@@ -216,6 +233,8 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -216,6 +233,8 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
self.navigationController?.pushViewController(faq, animated: true) self.navigationController?.pushViewController(faq, animated: true)
break break
case settingLabels.AboutUs.rawValue: case settingLabels.AboutUs.rawValue:
let AboutUs = PMAboutUsController()
self.navigationController?.pushViewController(AboutUs, animated: true)
break break
case settingLabels.PrivacyPolicy.rawValue: case settingLabels.PrivacyPolicy.rawValue:
jumpWeb(detailModel.title) jumpWeb(detailModel.title)
...@@ -225,7 +244,6 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -225,7 +244,6 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
} }
} }
// MARK: - 隐私空间PIN // MARK: - 隐私空间PIN
private func secretspace() -> Void { private func secretspace() -> Void {
if SettingConfiguration.share.config.secret?.count ?? 0 == 4 { if SettingConfiguration.share.config.secret?.count ?? 0 == 4 {
...@@ -267,6 +285,7 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -267,6 +285,7 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
}else{ }else{
SettingConfiguration.share.config.faceId = false SettingConfiguration.share.config.faceId = false
self.tableView.reloadRows(at: [indexPath], with: .none) self.tableView.reloadRows(at: [indexPath], with: .none)
tableView.reloadData()
} }
} }
...@@ -312,14 +331,28 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -312,14 +331,28 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
} }
alert.show() alert.show()
}else{ }else{
let vc:EmailLoginController = EmailLoginController() let callblock:(()->Void) = { [weak self] in
vc.state = .home guard let self = self else { return }
self.navigationController?.pushViewController(vc, animated: true) let vc:EmailLoginController = EmailLoginController()
self.tableView.reloadData() vc.state = .home
self.navigationController?.pushViewController(vc, animated: true)
self.tableView.reloadData()
}
if AdvManager.shared.advTimeAfterInAPP <= 0{
if IAPManager.share.isSubscribed == false {
AdvManager.shared.showInterstitialAd(vc: self)
}else{
callblock()
}
}else {
callblock()
}
AdvManager.shared.finisedCallBack = {
callblock()
}
} }
} }
// MARK: - 评分 // MARK: - 评分
private func review() -> Void { private func review() -> Void {
let reviewURLString = "itms-apps://itunes.apple.com/app/id1530333201?action=write-review" let reviewURLString = "itms-apps://itunes.apple.com/app/id1530333201?action=write-review"
...@@ -333,7 +366,7 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV ...@@ -333,7 +366,7 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
// MARK: - 分享 // MARK: - 分享
private func PhoneShare() -> Void { private func PhoneShare() -> Void {
let items: [Any] = [ URL(string: "itms-apps://itunes.apple.com/app/id1530333201")! ] let items: [Any] = ["Want to organize your photo library and free up storage space? Try our app’s smart cleanup feature now!",URL(string: "https://apps.apple.com/app/id1530333201")! ]
let shareVc = UIActivityViewController( let shareVc = UIActivityViewController(
activityItems: items, activityItems: items,
applicationActivities: nil applicationActivities: nil
......
...@@ -12,13 +12,13 @@ class TrashViewController: BaseViewController { ...@@ -12,13 +12,13 @@ class TrashViewController: BaseViewController {
var dissmisCallBack:()->Void = {} var dissmisCallBack:()->Void = {}
var source:[TrashTypeEnum] = [.video,.other,.shot,.chat] var source:[TrashTypeEnum] = [.video,.other,.shot]
var contentH:CGFloat = 0 var contentH:CGFloat = 0
var contentScrollView:UIScrollView! var contentScrollView:UIScrollView!
var delBtn:UIButton! var delBtn:UIButton!
var currentType:TrashTypeEnum = .other var currentType:TrashTypeEnum = .other
let pageCount = 4 // 总页数 let pageCount = 3 // 总页数
var currentPage = 1 { var currentPage = 1 {
didSet{ didSet{
self.setDelButtonUI() self.setDelButtonUI()
...@@ -61,7 +61,7 @@ class TrashViewController: BaseViewController { ...@@ -61,7 +61,7 @@ class TrashViewController: BaseViewController {
func configUI(){ func configUI(){
view.backgroundColor = .white view.backgroundColor = .white
contentScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: ScreenW, height: contentH)) contentScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: ScreenW, height: contentH))
contentScrollView.contentSize = CGSize(width: ScreenW*4, height: view.height) contentScrollView.contentSize = CGSize(width: ScreenW * CGFloat(self.source.count), height: view.height)
contentScrollView.isPagingEnabled = true contentScrollView.isPagingEnabled = true
contentScrollView.showsHorizontalScrollIndicator = false contentScrollView.showsHorizontalScrollIndicator = false
contentScrollView.showsVerticalScrollIndicator = false contentScrollView.showsVerticalScrollIndicator = false
...@@ -98,13 +98,11 @@ class TrashViewController: BaseViewController { ...@@ -98,13 +98,11 @@ class TrashViewController: BaseViewController {
contentScrollView.addSubview(videoView) contentScrollView.addSubview(videoView)
contentScrollView.addSubview(otherView) contentScrollView.addSubview(otherView)
contentScrollView.addSubview(shotView) contentScrollView.addSubview(shotView)
contentScrollView.addSubview(chatView)
videoView.deleteButton = delBtn videoView.deleteButton = delBtn
otherView.deleteButton = delBtn otherView.deleteButton = delBtn
shotView.deleteButton = delBtn shotView.deleteButton = delBtn
chatView.deleteButton = delBtn
} }
override func viewWillLayoutSubviews() { override func viewWillLayoutSubviews() {
...@@ -114,11 +112,10 @@ class TrashViewController: BaseViewController { ...@@ -114,11 +112,10 @@ class TrashViewController: BaseViewController {
let viewHeight = self.view.bounds.height let viewHeight = self.view.bounds.height
contentH = viewHeight - 108 contentH = viewHeight - 108
contentScrollView.frame = CGRect(x: 0, y: 34, width: viewWidth, height: contentH) contentScrollView.frame = CGRect(x: 0, y: 34, width: viewWidth, height: contentH)
contentScrollView.contentSize = CGSize(width: viewWidth*4, height: contentH) contentScrollView.contentSize = CGSize(width: viewWidth * CGFloat(self.source.count), height: contentH)
videoView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: contentH) videoView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: contentH)
otherView.frame = CGRect(x: viewWidth, y: 0, width: viewWidth, height: contentH) otherView.frame = CGRect(x: viewWidth, y: 0, width: viewWidth, height: contentH)
shotView.frame = CGRect(x: viewWidth*2, y: 0, width: viewWidth, height: contentH) shotView.frame = CGRect(x: viewWidth*2, y: 0, width: viewWidth, height: contentH)
chatView.frame = CGRect(x: viewWidth*3, y: 0, width: viewWidth, height: contentH)
} }
lazy var videoView:TrashContenView = { lazy var videoView:TrashContenView = {
...@@ -139,54 +136,8 @@ class TrashViewController: BaseViewController { ...@@ -139,54 +136,8 @@ class TrashViewController: BaseViewController {
return shotView return shotView
}() }()
lazy var chatView:TrashContenView = {
let chatView = TrashContenView()
chatView.trashType = .chat
return chatView
}()
//
// lazy var collectionView:UICollectionView = {
// let layout = UICollectionViewFlowLayout()
// layout.itemSize = CGSize(width: view.width, height: view.height)
// layout.scrollDirection = .horizontal
// layout.minimumInteritemSpacing = 0
// layout.minimumLineSpacing = 0
// let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.width, height: view.height), collectionViewLayout:layout)
// collectionView.isPagingEnabled = true
// collectionView.delegate = self
// collectionView.backgroundColor = .white
// collectionView.dataSource = self
// collectionView.register(UINib(nibName: "TrashContenViewCell", bundle: nil), forCellWithReuseIdentifier: "TrashContenViewCell0")
// collectionView.register(UINib(nibName: "TrashContenViewCell", bundle: nil), forCellWithReuseIdentifier: "TrashContenViewCell1")
// collectionView.register(UINib(nibName: "TrashContenViewCell", bundle: nil), forCellWithReuseIdentifier: "TrashContenViewCell2")
// collectionView.register(UINib(nibName: "TrashContenViewCell", bundle: nil), forCellWithReuseIdentifier: "TrashContenViewCell3")
//
// return collectionView
// }()
} }
//extension TrashViewController:UICollectionViewDelegate,UICollectionViewDataSource{
//
// func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return source.count
// }
//
// func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TrashContenViewCell\(indexPath.row)", for: indexPath) as! TrashContenViewCell
// cell.trashType = source[indexPath.row]
// return cell
// }
//
//}
extension TrashViewController:UIScrollViewDelegate{ extension TrashViewController:UIScrollViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView){ func scrollViewDidScroll(_ scrollView: UIScrollView){
...@@ -233,9 +184,6 @@ extension TrashViewController:UIScrollViewDelegate{ ...@@ -233,9 +184,6 @@ extension TrashViewController:UIScrollViewDelegate{
if self.currentPage == 3 { if self.currentPage == 3 {
return (TrashTypeEnum.shot,self.shotView) return (TrashTypeEnum.shot,self.shotView)
} }
if self.currentPage == 4 {
return (TrashTypeEnum.chat,self.chatView)
}
return (TrashTypeEnum.video,self.videoView) return (TrashTypeEnum.video,self.videoView)
} }
......
...@@ -11,7 +11,6 @@ enum TrashTypeEnum : String, CaseIterable{ ...@@ -11,7 +11,6 @@ enum TrashTypeEnum : String, CaseIterable{
case video = "Video" case video = "Video"
case other = "Other" case other = "Other"
case shot = "Screenshot" case shot = "Screenshot"
case chat = "Chat"
var dbType:Int{ var dbType:Int{
switch self { switch self {
...@@ -21,8 +20,6 @@ enum TrashTypeEnum : String, CaseIterable{ ...@@ -21,8 +20,6 @@ enum TrashTypeEnum : String, CaseIterable{
return 1 return 1
case .shot: case .shot:
return 2 return 2
case .chat:
return 3
} }
} }
} }
......
...@@ -39,8 +39,6 @@ class TrashContenTitleCell: UICollectionViewCell { ...@@ -39,8 +39,6 @@ class TrashContenTitleCell: UICollectionViewCell {
scrollLine.frame = lineTwo.frame scrollLine.frame = lineTwo.frame
case .shot: case .shot:
scrollLine.frame = lineThree.frame scrollLine.frame = lineThree.frame
case .chat:
scrollLine.frame = lineFour.frame
} }
} }
} }
...@@ -130,17 +128,7 @@ class TrashContenTitleCell: UICollectionViewCell { ...@@ -130,17 +128,7 @@ class TrashContenTitleCell: UICollectionViewCell {
weakSelf.scrollLine.frame = weakSelf.lineTwo.frame weakSelf.scrollLine.frame = weakSelf.lineTwo.frame
} }
} }
case .chat:
if offset < ScreenW * 3{
UIView.animate(withDuration: 0.2) {
weakSelf.scrollLine.frame = weakSelf.lineThree.frame
}
}else{
UIView.animate(withDuration: 0.2) {
weakSelf.scrollLine.frame = weakSelf.lineFour.frame
}
}
} }
} }
} }
......
...@@ -29,7 +29,7 @@ class TrashContenView: UIView { ...@@ -29,7 +29,7 @@ class TrashContenView: UIView {
var deleteButton : UIButton? var deleteButton : UIButton?
var scrollLine:UIView! var scrollLine:UIView!
let lineW:CGFloat = (ScreenW - 62) / 4.0 let lineW:CGFloat = (ScreenW - 62) / 3.0
var dataSource:[AssetModel] = [] { var dataSource:[AssetModel] = [] {
didSet{ didSet{
...@@ -48,11 +48,6 @@ class TrashContenView: UIView { ...@@ -48,11 +48,6 @@ class TrashContenView: UIView {
} }
func getData(){ func getData(){
// dataSource = TrashDatabase.shared.queryByMediaType(trashType.dbType).compactMap({ (localIdentifier: String, assetSize: Double, createDate: Date, mediaType: Int) in
// return AssetModel.init(localIdentifier: localIdentifier, assetSize: assetSize, createDate: createDate)
// })
collectionView.reloadData() collectionView.reloadData()
} }
...@@ -81,7 +76,6 @@ class TrashContenView: UIView { ...@@ -81,7 +76,6 @@ class TrashContenView: UIView {
collectionView.backgroundColor = UIColor.colorWithHex(hexStr: "#F2F6FC") collectionView.backgroundColor = UIColor.colorWithHex(hexStr: "#F2F6FC")
collectionView.dataSource = self collectionView.dataSource = self
collectionView.register(UINib(nibName: "TrashContenAssetCell", bundle: nil), forCellWithReuseIdentifier: "TrashContenAssetCell") collectionView.register(UINib(nibName: "TrashContenAssetCell", bundle: nil), forCellWithReuseIdentifier: "TrashContenAssetCell")
// collectionView.register(UINib(nibName: "TrashContenTitleCell", bundle: nil), forCellWithReuseIdentifier: "TrashContenTitleCell")
addSubview(collectionView) addSubview(collectionView)
...@@ -134,14 +128,9 @@ class TrashContenView: UIView { ...@@ -134,14 +128,9 @@ class TrashContenView: UIView {
lineThree.backgroundColor = UIColor.colorWithHex(hexStr: "#E5E5E5") lineThree.backgroundColor = UIColor.colorWithHex(hexStr: "#E5E5E5")
topView.addSubview(lineThree) topView.addSubview(lineThree)
lineFour = UIView()
lineFour.backgroundColor = UIColor.colorWithHex(hexStr: "#E5E5E5")
topView.addSubview(lineFour)
lineOne.frame = CGRect(x: 16, y: 62, width: lineW, height: 6) lineOne.frame = CGRect(x: 16, y: 62, width: lineW, height: 6)
lineTwo.frame = CGRect(x: 10+lineOne.rightX, y: 62, width: lineW, height: 6) lineTwo.frame = CGRect(x: 10+lineOne.rightX, y: 62, width: lineW, height: 6)
lineThree.frame = CGRect(x: 10+lineTwo.rightX, y: 62, width: lineW, height: 6) lineThree.frame = CGRect(x: 10+lineTwo.rightX, y: 62, width: lineW, height: 6)
lineFour.frame = CGRect(x: 10+lineThree.rightX, y: 62, width: lineW, height: 6)
scrollLine = UIView() scrollLine = UIView()
...@@ -218,23 +207,6 @@ class TrashContenView: UIView { ...@@ -218,23 +207,6 @@ class TrashContenView: UIView {
}else{ }else{
weakSelf.scrollLine.frame = weakSelf.lineThree.frame weakSelf.scrollLine.frame = weakSelf.lineThree.frame
} }
case .chat:
if page == 4{
if offset < ScreenW * 3{
UIView.animate(withDuration: 0.2) {
weakSelf.scrollLine.frame = weakSelf.lineThree.frame
}
}else{
UIView.animate(withDuration: 0.2) {
weakSelf.scrollLine.frame = weakSelf.lineFour.frame
}
}
}else{
weakSelf.scrollLine.frame = weakSelf.lineFour.frame
}
} }
} }
} }
...@@ -245,8 +217,6 @@ class TrashContenView: UIView { ...@@ -245,8 +217,6 @@ class TrashContenView: UIView {
lineOne.cornerCut(radius: 2, corner: .allCorners) lineOne.cornerCut(radius: 2, corner: .allCorners)
lineTwo.cornerCut(radius: 2, corner: .allCorners) lineTwo.cornerCut(radius: 2, corner: .allCorners)
lineThree.cornerCut(radius: 2, corner: .allCorners) lineThree.cornerCut(radius: 2, corner: .allCorners)
lineFour.cornerCut(radius: 2, corner: .allCorners)
// collectionView.frame = self.bounds
} }
var trashType:TrashTypeEnum = .video{ var trashType:TrashTypeEnum = .video{
...@@ -258,8 +228,6 @@ class TrashContenView: UIView { ...@@ -258,8 +228,6 @@ class TrashContenView: UIView {
scrollLine.frame = lineTwo.frame scrollLine.frame = lineTwo.frame
case .shot: case .shot:
scrollLine.frame = lineThree.frame scrollLine.frame = lineThree.frame
case .chat:
scrollLine.frame = lineFour.frame
} }
getData() getData()
} }
......
...@@ -103,8 +103,6 @@ class TrashDefaultView: UIView { ...@@ -103,8 +103,6 @@ class TrashDefaultView: UIView {
case .other,.shot: case .other,.shot:
jumpToPhotosDetailPage(type: type) jumpToPhotosDetailPage(type: type)
break break
case .chat:
break
} }
} }
} }
...@@ -113,14 +111,6 @@ class TrashDefaultView: UIView { ...@@ -113,14 +111,6 @@ class TrashDefaultView: UIView {
self.responderViewController()?.dismiss(animated: true, completion: { self.responderViewController()?.dismiss(animated: true, completion: {
NotificationCenter.default.post(name: TrashDefaultView.jumpToPhotosDetailPageName, object: nil,userInfo: ["type":self.mediaType?.rawValue ?? ""]) NotificationCenter.default.post(name: TrashDefaultView.jumpToPhotosDetailPageName, object: nil,userInfo: ["type":self.mediaType?.rawValue ?? ""])
}) })
// PhotoDataManager.manager.loadFromFileSystem { model in
// let data = type == .other ? model.otherModelArray[4] : model.otherModelArray[2]
// let vc:HomePhotosDetailViewController = HomePhotosDetailViewController(model: data)
// vc.mediaType = type == .other ? .Other : PhotsFileType.screenshots
// vc.dealData()
// self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
// }
} }
func jumpToVideoDetailPage(type: TrashTypeEnum){ func jumpToVideoDetailPage(type: TrashTypeEnum){
self.responderViewController()?.dismiss(animated: true, completion: { self.responderViewController()?.dismiss(animated: true, completion: {
......
...@@ -24,7 +24,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{ ...@@ -24,7 +24,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{
var current = 0 { var current = 0 {
didSet{ didSet{
if current == 0 { if current <= 0 {
ReturnAction.isHidden = true ReturnAction.isHidden = true
}else{ }else{
ReturnAction.isHidden = false ReturnAction.isHidden = false
...@@ -34,17 +34,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{ ...@@ -34,17 +34,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{
NextActions.setTitle("Ok", for: .normal) NextActions.setTitle("Ok", for: .normal)
} }
PMWidgetPage.currentPage = current PMWidgetPage.currentPage = current
if type == 0 {
let orx = CGFloat(current) * self.PMWidgetMainScroll.width
UIView.animate(withDuration: 0.3) {
self.PMWidgetMainScroll.contentOffset = CGPointMake(orx, 0)
}
}else{
let orx = CGFloat(current) * self.PMWidgetLockScroll.width
UIView.animate(withDuration: 0.3) {
self.PMWidgetLockScroll.contentOffset = CGPointMake(orx, 0)
}
}
} }
} }
...@@ -53,9 +43,23 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{ ...@@ -53,9 +43,23 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{
PMWidgetMainScroll.isHidden = !(type == 0) PMWidgetMainScroll.isHidden = !(type == 0)
PMWidgetLockScroll.isHidden = type == 0 PMWidgetLockScroll.isHidden = type == 0
current = 0 current = 0
animation()
} }
} }
private func animation() -> Void {
if type == 0 {
let orx = CGFloat(current) * self.PMWidgetMainScroll.width
UIView.animate(withDuration: 0.3) {
self.PMWidgetMainScroll.contentOffset = CGPointMake(orx, 0)
}
}else{
let orx = CGFloat(current) * self.PMWidgetLockScroll.width
UIView.animate(withDuration: 0.3) {
self.PMWidgetLockScroll.contentOffset = CGPointMake(orx, 0)
}
}
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
...@@ -69,6 +73,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{ ...@@ -69,6 +73,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{
PMWidgetMainScroll.delegate = self; PMWidgetMainScroll.delegate = self;
PMWidgetLockScroll.delegate = self PMWidgetLockScroll.delegate = self
type = 0 type = 0
self.navigationController?.isNavigationBarHidden = true
} }
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
...@@ -84,6 +89,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{ ...@@ -84,6 +89,7 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{
private func ScrollToCurrent(_ scroll:UIScrollView) -> Void { private func ScrollToCurrent(_ scroll:UIScrollView) -> Void {
let orx = scroll.contentOffset.x / scroll.width let orx = scroll.contentOffset.x / scroll.width
PMWidgetPage.currentPage = Int(round(orx)) PMWidgetPage.currentPage = Int(round(orx))
current = Int(round(orx))
if orx == 0 { if orx == 0 {
ReturnAction.isHidden = true ReturnAction.isHidden = true
}else{ }else{
...@@ -111,11 +117,13 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{ ...@@ -111,11 +117,13 @@ class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{
@IBAction func BottomActions(_ sender: UIButton) { @IBAction func BottomActions(_ sender: UIButton) {
if sender == ReturnAction { if sender == ReturnAction {
self.current -= 1 self.current -= 1
animation()
}else{ }else{
if self.current == 4 { if self.current == 4 {
self.dismiss(animated: true) self.dismiss(animated: true)
}else{ }else{
self.current += 1 self.current += 1
animation()
} }
} }
} }
......
...@@ -13,6 +13,7 @@ class PMWidgetGuideStartController: UIViewController { ...@@ -13,6 +13,7 @@ class PMWidgetGuideStartController: UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
} }
@IBAction func StartNextAction(_ sender: Any) { @IBAction func StartNextAction(_ sender: Any) {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jx3-dI-rXt"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jx3-dI-rXt">
<rect key="frame" x="352" y="69" width="26" height="42"/> <rect key="frame" x="352" y="69" width="26" height="53"/>
<inset key="contentEdgeInsets" minX="10" minY="10" maxX="0.0" maxY="10"/> <inset key="contentEdgeInsets" minX="10" minY="10" maxX="0.0" maxY="10"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="ic_widget_XXXXXXx"/> <state key="normal" image="ic_widget_XXXXXXx"/>
...@@ -28,20 +28,29 @@ ...@@ -28,20 +28,29 @@
</connections> </connections>
</button> </button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add widgets to the home screen and the lock screen" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kbM-qf-WH2"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add widgets to the home screen and the lock screen" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kbM-qf-WH2">
<rect key="frame" x="36" y="131" width="321" height="43"/> <rect key="frame" x="36" y="142" width="321" height="43"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="43" id="cTr-dF-GVf"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/> <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
<nil key="textColor"/> <nil key="textColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jAN-Lj-ySf"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jAN-Lj-ySf">
<rect key="frame" x="23" y="194" width="347" height="43"/> <rect key="frame" x="23" y="205" width="347" height="43"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="43" id="gWB-Me-UTE"/>
</constraints>
<string key="text">Easily monitor your battery and storage space with convenient widgets, providing convenience for your home screen and lock screen!</string> <string key="text">Easily monitor your battery and storage space with convenient widgets, providing convenience for your home screen and lock screen!</string>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/> <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/> <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_widget_guideus" translatesAutoresizingMaskIntoConstraints="NO" id="Gk6-53-p7B"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_widget_guideus" translatesAutoresizingMaskIntoConstraints="NO" id="Gk6-53-p7B">
<rect key="frame" x="34" y="257" width="325" height="442"/> <rect key="frame" x="34" y="268" width="325" height="442"/>
<constraints>
<constraint firstAttribute="width" secondItem="Gk6-53-p7B" secondAttribute="height" multiplier="25:34" id="JRq-xy-nP7"/>
</constraints>
</imageView> </imageView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FzB-PE-uL0"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FzB-PE-uL0">
<rect key="frame" x="16" y="740" width="361" height="58"/> <rect key="frame" x="16" y="740" width="361" height="58"/>
...@@ -68,13 +77,13 @@ ...@@ -68,13 +77,13 @@
<constraint firstItem="jAN-Lj-ySf" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="23" id="0hg-ZZ-cgL"/> <constraint firstItem="jAN-Lj-ySf" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="23" id="0hg-ZZ-cgL"/>
<constraint firstItem="Gk6-53-p7B" firstAttribute="top" secondItem="jAN-Lj-ySf" secondAttribute="bottom" constant="20" id="5K8-RY-RRE"/> <constraint firstItem="Gk6-53-p7B" firstAttribute="top" secondItem="jAN-Lj-ySf" secondAttribute="bottom" constant="20" id="5K8-RY-RRE"/>
<constraint firstItem="jAN-Lj-ySf" firstAttribute="top" secondItem="kbM-qf-WH2" secondAttribute="bottom" constant="20" id="5cu-aJ-ud2"/> <constraint firstItem="jAN-Lj-ySf" firstAttribute="top" secondItem="kbM-qf-WH2" secondAttribute="bottom" constant="20" id="5cu-aJ-ud2"/>
<constraint firstItem="Gk6-53-p7B" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="34" id="6tN-4g-d9M"/>
<constraint firstAttribute="trailing" secondItem="jAN-Lj-ySf" secondAttribute="trailing" constant="23" id="9jt-yG-2C3"/> <constraint firstAttribute="trailing" secondItem="jAN-Lj-ySf" secondAttribute="trailing" constant="23" id="9jt-yG-2C3"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Gk6-53-p7B" secondAttribute="trailing" constant="34" id="GSF-eJ-WeK"/> <constraint firstItem="FzB-PE-uL0" firstAttribute="top" secondItem="Gk6-53-p7B" secondAttribute="bottom" constant="30" id="Ibh-ZB-Pcv"/>
<constraint firstItem="kbM-qf-WH2" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="36" id="Ie5-Fi-9zn"/> <constraint firstItem="kbM-qf-WH2" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="36" id="Ie5-Fi-9zn"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="FzB-PE-uL0" secondAttribute="trailing" constant="16" id="O1A-bz-tvz"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="FzB-PE-uL0" secondAttribute="trailing" constant="16" id="O1A-bz-tvz"/>
<constraint firstItem="FzB-PE-uL0" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="16" id="Vpm-N7-5Mh"/> <constraint firstItem="FzB-PE-uL0" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" constant="16" id="Vpm-N7-5Mh"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="FzB-PE-uL0" secondAttribute="bottom" constant="20" id="Xmg-Oj-olO"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="bottom" secondItem="FzB-PE-uL0" secondAttribute="bottom" constant="20" id="Xmg-Oj-olO"/>
<constraint firstItem="Gk6-53-p7B" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="c7j-De-NMq"/>
<constraint firstItem="kbM-qf-WH2" firstAttribute="top" secondItem="Jx3-dI-rXt" secondAttribute="bottom" constant="20" id="fkG-Qv-2W9"/> <constraint firstItem="kbM-qf-WH2" firstAttribute="top" secondItem="Jx3-dI-rXt" secondAttribute="bottom" constant="20" id="fkG-Qv-2W9"/>
<constraint firstAttribute="trailing" secondItem="kbM-qf-WH2" secondAttribute="trailing" constant="36" id="g6U-Wh-rBz"/> <constraint firstAttribute="trailing" secondItem="kbM-qf-WH2" secondAttribute="trailing" constant="36" id="g6U-Wh-rBz"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Jx3-dI-rXt" secondAttribute="trailing" constant="15" id="k0K-LP-VIv"/> <constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Jx3-dI-rXt" secondAttribute="trailing" constant="15" id="k0K-LP-VIv"/>
......
...@@ -63,7 +63,9 @@ class WidgetViewController: BaseViewController { ...@@ -63,7 +63,9 @@ class WidgetViewController: BaseViewController {
DispatchQueue.main.asyncAfter(deadline: .now()+1.5) { DispatchQueue.main.asyncAfter(deadline: .now()+1.5) {
save.dismiss(animated: true) { save.dismiss(animated: true) {
self.dismiss(animated: true) self.dismiss(animated: true)
self.jumpGuidePage() if self.isJumpExample == false {
self.jumpGuidePage()
}
} }
} }
} }
...@@ -90,15 +92,14 @@ class WidgetViewController: BaseViewController { ...@@ -90,15 +92,14 @@ class WidgetViewController: BaseViewController {
}else{ }else{
isJumpExample = true isJumpExample = true
let guide = PMWidgetGuideStartController() let guide = PMWidgetGuideStartController()
guide.modalPresentationStyle = .overFullScreen let guideM = UINavigationController(rootViewController: guide)
guideM.modalPresentationStyle = .overFullScreen
guide.callblock = {[weak self] in guide.callblock = {[weak self] in
guide.dismiss(animated: true)
guard let self = self else { return } guard let self = self else { return }
let example = PMWidgetExampleController() let example = PMWidgetExampleController()
example.modalPresentationStyle = .overFullScreen guide.navigationController?.pushViewController(example, animated: true)
self.present(example, animated: true)
} }
self.present(guide, animated: true) self.present(guideM, animated: true)
} }
} }
...@@ -207,7 +208,7 @@ class WidgetViewController: BaseViewController { ...@@ -207,7 +208,7 @@ class WidgetViewController: BaseViewController {
private lazy var setWidgetBtn: UIButton = { private lazy var setWidgetBtn: UIButton = {
let btn = UIButton(type: .custom) let btn = UIButton(type: .custom)
btn.setTitle("Set Widget", for: .normal) btn.setTitle("Set Widget", for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 16) btn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
btn.setTitleColor(.white, for: .normal) btn.setTitleColor(.white, for: .normal)
btn.addTarget(self, action: #selector(setWidgetTouch), for: .touchUpInside) btn.addTarget(self, action: #selector(setWidgetTouch), for: .touchUpInside)
view.addSubview(btn) view.addSubview(btn)
......
...@@ -172,6 +172,7 @@ extension EmailFilterController : UITableViewDelegate,UITableViewDataSource { ...@@ -172,6 +172,7 @@ extension EmailFilterController : UITableViewDelegate,UITableViewDataSource {
cell.callblock = {[weak self] select in cell.callblock = {[weak self] select in
guard let self = self else { return } guard let self = self else { return }
self.filter.date = indexPath.row self.filter.date = indexPath.row
self.vibrate()
tableView.reloadData() tableView.reloadData()
} }
cell.selectionStyle = .none cell.selectionStyle = .none
......
...@@ -29,6 +29,10 @@ class PMScaleImageView: UIView , UIScrollViewDelegate { ...@@ -29,6 +29,10 @@ class PMScaleImageView: UIView , UIScrollViewDelegate {
size.width = self.width size.width = self.width
size.height = size.height * (self.width / (self.icon?.size.width ?? 1)) size.height = size.height * (self.width / (self.icon?.size.width ?? 1))
} }
if size.height > self.height {
size.height = self.height
size.width = size.width * (self.height / (self.icon?.size.height ?? 1))
}
self.showImg.snp.remakeConstraints({ make in self.showImg.snp.remakeConstraints({ make in
make.left.equalToSuperview().offset((self.width - size.width)/2.0 ) make.left.equalToSuperview().offset((self.width - size.width)/2.0 )
make.top.equalToSuperview().offset((self.height - size.height)/2.0 ) make.top.equalToSuperview().offset((self.height - size.height)/2.0 )
......
...@@ -57,7 +57,80 @@ extension UILabel { ...@@ -57,7 +57,80 @@ extension UILabel {
} }
} }
var handleTextTapKey = "handleTextTapKey"
var ClickLabelTextsJey = "ClickLabelTextsJey"
extension UILabel { extension UILabel {
private var handleTextTap:((String)->Void)? {
set {
objc_setAssociatedObject(self, &handleTextTapKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
}
get {
return objc_getAssociatedObject(self, &handleTextTapKey) as? ((String) -> Void)
}
}
private var ClickLabelTexts:[String]? {
set {
objc_setAssociatedObject(self, &ClickLabelTextsJey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
get {
return objc_getAssociatedObject(self, &ClickLabelTextsJey) as? [String]
}
}
public func AddTapped(_ ClickStrs:[String],handle:@escaping((String)->Void)) -> Void {
if ClickLabelTexts?.count ?? 0 > 0 {
return
}
let tap = UITapGestureRecognizer(target: self, action: #selector(labelTapped(_:)))
self.addGestureRecognizer(tap)
self.isUserInteractionEnabled = true
ClickLabelTexts = ClickStrs
handleTextTap = handle
}
func frameForStringRange(_ range: NSRange) -> CGRect? {
guard let attributedText = attributedText else { return nil }
let textStorage = NSTextStorage(attributedString: attributedText)
let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: bounds.size)
textContainer.lineFragmentPadding = 0
layoutManager.addTextContainer(textContainer)
var glyphRange = NSRange()
layoutManager.characterRange(
forGlyphRange: range,
actualGlyphRange: &glyphRange
)
return layoutManager.boundingRect(
forGlyphRange: glyphRange,
in: textContainer
)
}
@objc private func labelTapped(_ gesture: UITapGestureRecognizer) {
self.layoutIfNeeded()
// 判断点击范围
for text in (ClickLabelTexts ?? []) {
if let range = self.text?.range(of: text) {
let nsRange = NSRange(range, in: self.text ?? "")
guard var subStringFrame = self.frameForStringRange(nsRange) else { return }
let locationInLabel = gesture.location(in: self)
if CGRectContainsPoint(subStringFrame, locationInLabel) {
handleTextTap?(text)
}
}
}
}
func isTapLocationInTextRange(_ gesture: UITapGestureRecognizer, range: NSRange) -> Bool { func isTapLocationInTextRange(_ gesture: UITapGestureRecognizer, range: NSRange) -> Bool {
let layoutManager = NSLayoutManager() let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: .zero) let textContainer = NSTextContainer(size: .zero)
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
import Foundation import Foundation
import AudioToolbox import AudioToolbox
import CoreHaptics
extension Int { extension Int {
...@@ -122,15 +124,15 @@ extension CGFloat { ...@@ -122,15 +124,15 @@ extension CGFloat {
extension NSObject { extension NSObject {
public func vibrate(_ all:Bool? = false) -> Void { public func vibrate(_ all:Bool? = nil) -> Void {
if all != nil { if all != nil {
DispatchQueue.main.async { DispatchQueue.main.async {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) HapticManager.share.triggerHapticFeedback()
} }
}else{ }else{
if SettingConfiguration.share.config.vibration ?? false { if SettingConfiguration.share.config.vibration ?? false {
DispatchQueue.main.async { DispatchQueue.main.async {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate)) HapticManager.share.triggerHapticFeedback()
} }
} }
} }
...@@ -153,3 +155,38 @@ extension UISwitch { ...@@ -153,3 +155,38 @@ extension UISwitch {
} }
} }
class HapticManager {
static let share = HapticManager()
private var engine: CHHapticEngine?
init() {
setupHapticEngine()
}
func setupHapticEngine() {
guard CHHapticEngine.capabilitiesForHardware().supportsHaptics else { return }
do {
engine = try CHHapticEngine()
try engine?.start()
generator.prepare()
} catch {
print("引擎初始化失败: \(error)")
}
}
private lazy var generator: UIImpactFeedbackGenerator = {
let genter = UIImpactFeedbackGenerator(style: .medium)
genter.prepare()
return genter
}()
// 触发震动反馈
func triggerHapticFeedback() {
generator.impactOccurred()
}
}
...@@ -16,6 +16,9 @@ class PMFaceIDManger: NSObject { ...@@ -16,6 +16,9 @@ class PMFaceIDManger: NSObject {
} }
class func request() -> Bool { class func request() -> Bool {
if isAvailable() == false {
return false
}
let context = LAContext() let context = LAContext()
return context.biometricType == .faceID return context.biometricType == .faceID
} }
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
<string>684306808588-cl093f79dogls1a608bh8oclk3ia0rig.apps.googleusercontent.com</string> <string>684306808588-cl093f79dogls1a608bh8oclk3ia0rig.apps.googleusercontent.com</string>
<key>LSApplicationQueriesSchemes</key> <key>LSApplicationQueriesSchemes</key>
<array> <array>
<string>wechat</string>
<string>weixin</string>
<string>google</string> <string>google</string>
<string>googlemail</string> <string>googlemail</string>
<string>googlegmail</string> <string>googlegmail</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment