Commit 92491362 authored by yqz's avatar yqz

设置及二级界面

parent 775781a3
......@@ -184,8 +184,10 @@ extension CompressController:WaterfallMutiSectionDelegate,UICollectionViewDataSo
// 这里临时管理一个当前选择的资源
if choose == true && !self.selectedModel.contains(model) {
self.selectedModel.append(model)
self.vibrate()
}
if choose == false && self.selectedModel.contains(model){
self.vibrate()
if let index = selectedModel.firstIndex(of: model) {
selectedModel.remove(at: index)
}
......
......@@ -234,6 +234,7 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
setButtonTitleByType(type: .low)
self.vibrate()
}
self.mediumQualityView.callBack = {[weak self] type in
......@@ -246,6 +247,7 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
setButtonTitleByType(type: .mid)
self.vibrate()
}
self.highQualityView.callBack = {[weak self] type in
......@@ -258,6 +260,7 @@ class CompressQualityController : BaseViewController{
self.mediumQualityView.selectedImageView.image = UIImage(named: "ic_sel_com")
self.highQualityView.selectedImageView.image = UIImage(named: "ic_unsel_com")
setButtonTitleByType(type: .high)
self.vibrate()
}
......
......@@ -153,7 +153,7 @@ extension ContactAllView : UITableViewDataSource,UITableViewDelegate {
}else{
self.selectedContacts.removeAll(where: { $0.identifier == model.identifier })
}
self.vibrate()
DispatchQueue.main.async {
// 判断button是否显示
if self.selectedContacts.count > 0 {
......
......@@ -130,6 +130,7 @@ extension ContactDupNormalView : UITableViewDelegate,UITableViewDataSource{
cell.model = self.dataSourceModel[indexPath.section][indexPath.row]
cell.cellSelectCallCack = {[weak self]index,choose in
guard let self else {return}
self.vibrate()
if choose {
self.saveSelectModel(index: index)
}else {
......
......@@ -167,6 +167,7 @@ extension ContactNormalIncomView : UITableViewDataSource,UITableViewDelegate {
}
cell.buttonSelectCallBack = {[weak self] model,selected in
guard let self else {return}
self.vibrate()
if selected {
self.selectedContacts.append(model)
}else{
......
......@@ -9,15 +9,73 @@ import UIKit
class PMFAQCell: UITableViewCell {
static let id = "PMFAQCell"
var callblock:(()->Void) = {}
@IBOutlet weak var PMFAQOpen: UIButton!
@IBOutlet weak var problem: UILabel!
@IBOutlet weak var anwser: UILabel!
var isOpen:Bool = false
@IBOutlet weak var topContraint: NSLayoutConstraint!
@IBAction func OpenActions(_ sender: Any) {
callblock()
}
var data:FAQDataModel? {
didSet{
problem.text = data?.problem
if isOpen {
self.topContraint.constant = 16;
PMFAQOpen.isSelected = true
anwser.attributedText = addattribed()
}else{
self.topContraint.constant = 0;
PMFAQOpen.isSelected = false
anwser.attributedText = nil
}
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
private func addattribed() -> NSMutableAttributedString {
var mutableText = NSMutableAttributedString(string: data?.answer ?? "")
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .semibold)], range: NSRange(location: 0, length: mutableText.length))
let rangs = ["PhoneManager",
"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)
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)
mutableText.addAttributes([NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14, weight: .bold)], range: NSRange(location: start, length: end))
}
}
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">
<?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>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
<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" id="KGk-i7-Jjw" customClass="PMFAQCell" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="117" id="KGk-i7-Jjw" customClass="PMFAQCell" customModule="PhoneManager" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="394" height="117"/>
<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="320" height="43"/>
<rect key="frame" x="0.0" y="0.0" width="394" height="117"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LI7-ek-n5r">
<rect key="frame" x="0.0" y="0.0" width="394" height="102"/>
<subviews>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aR1-rL-mMz">
<rect key="frame" x="24" y="26" width="28" height="28"/>
<constraints>
<constraint firstAttribute="height" constant="28" id="K94-s3-vct"/>
<constraint firstAttribute="width" constant="28" id="wah-5C-OTg"/>
</constraints>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="ic_hints_faq-+"/>
<state key="selected" image="ic_hints_faq-"/>
<connections>
<action selector="OpenActions:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="QBR-6R-L8q"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Why don't l have free space on myphone after the cleaning process?" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FV7-Dy-QOC">
<rect key="frame" x="64" y="25.666666666666664" width="306" height="28.666666666666664"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="12"/>
<color key="textColor" red="0.066666666666666666" green="0.066666666666666666" blue="0.066666666666666666" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5Ww-Bj-ymx">
<rect key="frame" x="24" y="54" width="346" height="25"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" id="ZKt-Ht-FOb"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<color key="textColor" red="0.066666666666666666" green="0.066666666666666666" blue="0.066666666666666666" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.94901960784313721" green="0.96470588235294119" blue="0.9882352941176471" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstItem="5Ww-Bj-ymx" firstAttribute="leading" secondItem="aR1-rL-mMz" secondAttribute="leading" id="Pfx-40-F4C"/>
<constraint firstAttribute="trailing" secondItem="FV7-Dy-QOC" secondAttribute="trailing" constant="24" id="R8i-5I-WGq"/>
<constraint firstItem="5Ww-Bj-ymx" firstAttribute="trailing" secondItem="FV7-Dy-QOC" secondAttribute="trailing" id="UBE-xe-efw"/>
<constraint firstItem="aR1-rL-mMz" firstAttribute="leading" secondItem="LI7-ek-n5r" secondAttribute="leading" constant="24" id="Ufh-Ts-jrV"/>
<constraint firstItem="5Ww-Bj-ymx" firstAttribute="top" secondItem="aR1-rL-mMz" secondAttribute="bottom" id="d17-JK-Uky"/>
<constraint firstItem="FV7-Dy-QOC" firstAttribute="centerY" secondItem="aR1-rL-mMz" secondAttribute="centerY" id="daf-Yq-Hwf"/>
<constraint firstAttribute="bottom" secondItem="5Ww-Bj-ymx" secondAttribute="bottom" constant="23" id="ewW-dW-1bR"/>
<constraint firstItem="FV7-Dy-QOC" firstAttribute="leading" secondItem="aR1-rL-mMz" secondAttribute="trailing" constant="12" id="pDR-fl-MNx"/>
<constraint firstItem="aR1-rL-mMz" firstAttribute="top" secondItem="LI7-ek-n5r" secondAttribute="top" constant="26" id="x74-ey-2Qq"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="Radius">
<real key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="LI7-ek-n5r" secondAttribute="bottom" constant="15" id="MN0-Mh-jHR"/>
<constraint firstAttribute="trailing" secondItem="LI7-ek-n5r" secondAttribute="trailing" id="WWh-Ey-LIp"/>
<constraint firstItem="LI7-ek-n5r" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="cte-Ua-YEn"/>
<constraint firstItem="LI7-ek-n5r" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="nYi-NM-JQZ"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<connections>
<outlet property="PMFAQOpen" destination="aR1-rL-mMz" id="uDp-gy-zMD"/>
<outlet property="anwser" destination="5Ww-Bj-ymx" id="S5P-P6-m9V"/>
<outlet property="problem" destination="FV7-Dy-QOC" id="w8n-e3-MRz"/>
<outlet property="topContraint" destination="d17-JK-Uky" id="BWK-zy-B8a"/>
</connections>
<point key="canvasLocation" x="186.25954198473281" y="14.43661971830986"/>
</tableViewCell>
</objects>
<resources>
<image name="ic_hints_faq-" width="28" height="28"/>
<image name="ic_hints_faq-+" width="28" height="28"/>
</resources>
</document>
//
// Untitled.swift
// PhoneManager
//
// Created by edy on 2025/5/16.
//
[
{
"problem":"Why isn't storage space freed up after cleaning my phone?",
"answer":"The cleaning process follows iOS system design: deleted photos/videos are temporarily moved to the Recently Deleted album (retained for 30 days) and still occupy storage. To permanently free up space, open the Photos app on your iPhone, navigate to the Recently Deleted album, select items you wish to remove, and tap Delete. Note that this action irreversibly erases files from your device, so confirm you no longer need them before proceeding."
},
{
"problem":"How Do I Recover Deleted Photos/Videos?",
"answer":"Deleted photos/videos are temporarily preserved in the Recently Deleted album for 30 days (aligned with iOS Photos app protocols), allowing recovery if removed accidentally. To restore them, open the Photos app, navigate to the Recently Deleted album, tap Select (top-right corner), choose the files to retrieve, and tap Recover. For bulk restoration, use Recover All after selecting all items. Note that this album retains content deleted both manually and via cleanup tools. After 30 days, iOS automatically removes these files permanently, so ensure timely action."
},
{
"problem":"Does PhoneManager Guarantee That My Photos Will Not Be Uploaded Anywhere? ",
"answer":"PhoneManager operates entirely offline and requires no internet connection, ensuring your photos are never uploaded to external servers. All scanning, analysis, and PhoneManager processes occur locally on your device. The app only requests access to your photo library to evaluate attributes like edits, favorites, or facial recognition data for organizing purposes. No photo content or metadata is shared externally—the. The sole reports generated are anonymous technical logs (e.g., app performance issues) that contain no personal or image-related information. Your privacy remains protected throughout the process."
},
{
"problem":"How Does PhoneManager Choose the Best Photos?",
"answer":"PhoneManager employs advanced algorithms incorporating face recognition, similar photo comparison, and evaluation of edited/favorited status to analyze your gallery. Based on these criteria, it dynamically flags one photo in a group as the Best Result. While the selection prioritizes technical quality and metadata insights, we strongly recommend reviewing these suggestions to ensure they align with your personal preferences, as human judgment may differ from algorithmic evaluations"
},
{
"problem":"Can I Use PhoneManager on All My Other Apple Devices?",
"answer":"PhoneManager is currently compatible only with iPhones running iOS 14 or later. The number of devices covered under your subscription/license is governed by the App Store's subscription terms and conditions. Support for additional Apple devices (e.g., iPads, Macs) is unavailable at this time."
},
{
"problem":"How Can I Cancel My Subscription?",
"answer":"To cancel your PhoneManager subscription, follow Apple's standard subscription management process: Open Settings on your iPhone, tap your Apple ID profile at the top, select Subscriptions, then choose PhoneManager. Tap the Cancel Subscription button at the bottom of the screen. Note that this action stops automatic renewal but preserves access until the end of your current billing cycle."
},
{
"problem":"How Do I Scan the Photos in My Photos Library?",
"answer":"PhoneManager initiates automatic scanning and analysis of your photo library upon first launch. For large collections, this process may require significant time and device resources. Please allow the scan to complete uninterrupted—results will display once finished. Subsequent scans optimize efficiency by focusing only on recent additions or changes, leveraging cached data from the initial scan. While first-time usage demands patience, future interactions will be faster and resource-light."
},
{
"problem":"What Is Categorized as “Similar”?",
"answer":"The “Similar” category groups photos captured within seconds of each other, featuring the same subject/person in a consistent background with minor variations (e.g., poses, angles). For instance, multiple shots of someone posing differently in front of a landmark. To simplify cleanup, PhoneManager uses advanced algorithms analyzing factors like clarity and composition to flag one photo as the Best Result and suggests removing others. Photos marked as favorites are automatically excluded from selection. Before confirming cleanup, review suggested groups to ensure alignment with your preferences."
},
{
"problem":"What Is Categorized as \"Other\"?",
"answer":"The “Other” category includes photos that do not fit predefined classifications (e.g., duplicates, similar shots). Unlike automated suggestions in other groups, PhoneManager refrains from labeling items here as \"good\" or \"bad.\" Instead, it employs an interactive swiping mechanism—swipe left to mark photos for deletion or right to retain them—giving you full control over curation. Prioritize reviewing this category manually to ensure no unintended files are removed."
},
{
"problem":"How Can I Review All Photos in a Certain Category?",
"answer":"To review photos within a category, tap any item to enlarge it for closer inspection. In the “Similar” category, photos are grouped into sets organized by creation date—scroll vertically to browse all sets and tap one to examine its contents. For subcategories without grouped sets, scroll freely through individual photos and tap to view details. Use this process to thoroughly evaluate suggestions before finalizing cleanup decisions."
},
{
"problem":"How Can I Remove Unwanted Photos?",
"answer":"PhoneManager automatically flags suggested photos for deletion with a red checkmark icon based on algorithmic analysis. To proceed, select the marked items and tap Delete—but ensure any photos you wish to retain are moved to your Keep List first. For manual review in the “Similar” category, open a grouped set, inspect the app’s Best Result recommendation, and tap Move to Trash to approve deletions. To override suggestions, unmark photos you want to keep (or add them to your Keep List), re-mark unwanted items, then finalize by tapping the trash bin icon and confirming Delete. Always verify selections, as deletions are permanent."
},
{
"problem":"How Do I Use the Swiping Feature?",
"answer":"The swiping feature in PhoneManager provides an efficient way to review photos in the Videos and Other categories. Simply swipe left on a photo to mark it for removal or swipe right to add it to your Keep List. This intuitive gesture-based system streamlines the cleanup process while ensuring you retain full control over final decisions."
},
{
"problem":"Can I Clean My Videos Using PhoneManager?",
"answer":"Yes, PhoneManager supports video cleanup by organizing all videos under the Videos category. While similarity-based sorting for videos is resource-intensive, you can manually sort them by size or creation date and use the swipe-left gesture to mark items for deletion or swipe-right to retain them in your Keep List. This streamlined approach balances technical constraints with user control, allowing efficient curation of large video libraries."
},
{
"problem":"Should I Review All the Photos PhoneManager Scanned?",
"answer":"While PhoneManager employs smart algorithms to group photos and suggest Best Result recommendations, we strongly advise reviewing all flagged items before deletion. The app streamlines organization and prioritizes accuracy, but personal preferences may differ from algorithmic logic. Retain full control by verifying selections—your final approval ensures no essential photos are inadvertently removed."
},
{
"problem":"Is PhoneManager Safe? How Can I Trust PhoneManager?",
"answer":"PhoneManager prioritizes safety and user control: All cleanup actions require explicit approval, and no files are deleted without your final confirmation. The app operates with offline processing (no photo uploads) and uses permissions solely to analyze local metadata (e.g., edits, favorites) for suggestions. While its algorithms streamline decisions, your manual review ensures alignment with personal preferences. Additionally, no personal data or photo content is shared externally—only anonymous technical logs are generated for app optimization. Trust is built through transparency and your retained authority over every deletion."
},
{
"problem":"How Do I Add Photos to My Keep List?",
"answer":"To add photos/videos to your Keep List, open a grouped set in the “Similar” category and tap the Keep All button (lower-left corner) to save the entire collection. For individual items in the Videos or “Other” categories, simply swipe right to add them to your Keep List. To review or edit saved content, access your Keep List through the Settings icon (upper-right corner of the Media Library). If you wish to remove items, select the files within the Keep List and tap Unkeep (upper-right corner) to return them to the scan results. All changes take effect immediately, ensuring seamless control over your curated collection."
},
]
......@@ -7,23 +7,83 @@
import UIKit
class PMFAQController: UIViewController {
class PMFAQController: BaseViewController {
@IBOutlet weak var TableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.TableView.delegate = self
self.TableView.dataSource = self
self.TableView.showsVerticalScrollIndicator = false
self.TableView.showsHorizontalScrollIndicator = false
self.titleView.model.title = "FAQ"
self.TableView.register(UINib(nibName: PMFAQCell.id, bundle: nil), forCellReuseIdentifier: PMFAQCell.id)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let file = Bundle.main.bundleURL.appendingPathComponent("PMFAQData.json")
do{
let dictData = try Data(contentsOf: file)
dataSource = try JSONDecoder().decode([FAQDataModel].self, from: dictData)
}catch{ }
self.TableView.snp.makeConstraints { make in
make.left.right.equalToSuperview().inset(15)
make.bottom.equalToSuperview()
make.top.equalTo(self.titleView.snp.bottom).offset(10)
}
}
@IBAction func BackToAction(_ sender: Any) {
self.navigationController?.popViewController(animated: true)
}
var openSet = -1
var dataSource:[FAQDataModel] = [] {
didSet {
self.TableView.reloadData()
}
}
}
/*
// MARK: - Navigation
extension PMFAQController : UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PMFAQCell.id, for: indexPath) as! PMFAQCell
cell.isOpen = openSet == indexPath.row
cell.data = dataSource[indexPath.row]
cell.selectionStyle = .none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var indexpaths:[IndexPath] = []
if openSet == indexPath.row {
openSet = -1
indexpaths = [indexPath]
}else{
let current = openSet
openSet = indexPath.row
indexpaths = [indexPath]
if current > 0 {
indexpaths.append(IndexPath(row: current, section: 0))
}
}
tableView.reloadRows(at: indexpaths, with: .automatic)
}
*/
}
struct FAQDataModel : Codable {
var problem:String
var answer:String
init(problem: String, answer: String) {
self.problem = problem
self.answer = answer
}
}
<?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">
<?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>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
<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="PMFAQController" customModuleProvider="target">
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PMFAQController" customModule="PhoneManager" customModuleProvider="target">
<connections>
<outlet property="TableView" destination="q9T-FF-R37" id="xaI-v2-Arc"/>
<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"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<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="q9T-FF-R37">
<rect key="frame" x="15" y="127" width="363" height="691"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<connections>
<outlet property="dataSource" destination="-1" id="7C4-p0-iYH"/>
<outlet property="delegate" destination="-1" id="vwG-gm-Uru"/>
</connections>
</tableView>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<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>
......@@ -7,23 +7,28 @@
import UIKit
class PMHintsController: UIViewController {
class PMHintsController: BaseViewController , UIScrollViewDelegate {
@IBOutlet weak var PMHintsPage: UIPageControl!
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
PMHintsPage.numberOfPages = 5
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
ScrollToCurrent(scrollView)
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if decelerate {
ScrollToCurrent(scrollView)
}
}
private func ScrollToCurrent(_ scroll:UIScrollView) -> Void {
let orx = scroll.contentOffset.x / scroll.width
PMHintsPage.currentPage = Int(round(orx))
}
*/
}
......@@ -369,6 +369,7 @@ extension HomePhotosDetailViewController:WaterfallMutiSectionDelegate,UICollecti
}else{
self.selectedModel.removeAll { $0.localIdentifier == self.resourceData[order].localIdentifier }
}
self.vibrate()
DispatchQueue.main.async {
if self.selectedModel.count > 0 {
self.deleteButton.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
......
......@@ -390,10 +390,12 @@ class PhotoRemoveViewController: BaseViewController {
// 保存垃圾桶数据到数据库
saveDataToTrashDB()
// 保留操作
self.vibrate()
saveDataToSigtonKeepList()
}
if actualTranslation.x < 0 {
// 删除操作,先存到单利
self.vibrate()
saveDataToSigtonTrash()
}
} else {
......
......@@ -244,7 +244,7 @@ extension HomeInfoTableViewCell:UICollectionViewDelegate,UICollectionViewDataSou
cell.callBack = {[weak self] _ in
guard let self else {return}
vibrate()
self.checkSeletedAll()
self.callBack("changgeSeleted")
......
......@@ -142,6 +142,7 @@ extension MaintaiDetailViewController:UITableViewDelegate,UITableViewDataSource{
cell.source = viewModel.souces[indexPath.row]
cell.selectCallBack = {[weak self] selects in
guard let weakSelf = self else { return }
weakSelf.vibrate()
if let sIndex = selectIndex{
//已经有选中状态
Print("已经有选中数据",sIndex)
......
......@@ -118,6 +118,7 @@ extension MaintainViewListController:UICollectionViewDataSource,UICollectionView
cell.reloadData(viewModel.souces[indexPath.row], isSelect:isSelect)
cell.selectBlock = {[weak self] in
guard let weakSelf = self else { return }
weakSelf.vibrate()
weakSelf.dealPickAssetModel(row: indexPath.row,isSelect: isSelect)
weakSelf.collectionView.reloadData()
}
......
......@@ -493,7 +493,7 @@ class HomePayView:UIView {
@objc func switchValueChanged(_ sender: UISwitch) {
type = sender.isOn ? 0 : 1
self.vibrate()
}
@objc func restoreTouch() -> Void {
......
......@@ -68,6 +68,7 @@ class DelSuccessViewController: UIViewController {
}
@IBAction func closeClick(_ sender: Any) {
vibrate()
self.dismiss(animated: true)
}
......
......@@ -159,6 +159,7 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == bottItems {
self.vibrate()
if selectSet.contains(indexPath.row) {
self.homeDataSource?[indexPath.row].isSeleted = false
selectSet.remove(indexPath.row)
......@@ -207,6 +208,7 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
cell.isCurrent = selectSet.contains(indexPath.row)
cell.callblock = {[weak self] in
guard let self = self else { return }
self.vibrate()
if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row)
......@@ -226,6 +228,7 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
cell.reload()
cell.callblock = {[weak self] in
guard let self = self else { return }
self.vibrate()
if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row)
......@@ -259,6 +262,7 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
cell.bestResultButton.isHidden = indexPath.row != 0
cell.callblock = {[weak self] in
guard let self = self else { return }
self.vibrate()
if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row)
......@@ -302,6 +306,7 @@ extension PMShowImgVideoController : UICollectionViewDelegate,UICollectionViewDa
cell.bestResultButton.isHidden = indexPath.row != 0
cell.callblock = {[weak self] in
guard let self = self else { return }
self.vibrate()
if self.selectSet.contains(indexPath.row){
self.homeDataSource?[indexPath.row].isSeleted = false
self.selectSet.remove(indexPath.row)
......
......@@ -134,12 +134,14 @@ class SecretSetViewController: BaseViewController, UITextFieldDelegate {
}else{
// UserDefaults.standard.set(Secret, forKey: SecretViewController.psKey)
SettingConfiguration.share.config.secret = Secret
UserDefaults.standard.set("1", forKey: "SecretFirstShow")
let alert = UIAlertController(title: nil, message: "Your space is locked", preferredStyle: .alert)
self.present(alert, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
alert.dismiss(animated: true) {
self.Callback(true)
self.PMClose()
_ = PMFaceIDManger.request()
}
}
}
......
......@@ -419,7 +419,9 @@ extension SecretViewController : UIImagePickerControllerDelegate , UINavigationC
}
assetdels.append(set.phAsset!)
}
SecretPhotoManager.share.deleteAssets(assetdels)
if SettingConfiguration.share.config.removeImg {
SecretPhotoManager.share.deleteAssets(assetdels)
}
}else{
guard let d = data as? Data else { return }
if idx == 0 { // image
......
......@@ -62,7 +62,34 @@ struct RowInfoModel{
func getSettingViewInfo() -> [SettingModel] {
if SettingConfiguration.share.config.secret?.count ?? 0 != 4 {
return [
SettingModel(sectionTitle: "",rowInfo: [RowInfoModel(imageName: "",title: "")]),
SettingModel(sectionTitle: "E-mail",rowInfo: [RowInfoModel(imageName: "icon_set_secret_Email_l", title: "Log in")]),
SettingModel(sectionTitle: "Secret space",rowInfo: [RowInfoModel(imageName: "icon_set_secret_lock",title: "Use PIN" , isSwitch:true),
RowInfoModel(imageName: "icon_set_secret_Del",title: "Remove After Import",isSwitch:true)]),
SettingModel(sectionTitle: "Practical tools",rowInfo: [RowInfoModel(imageName: "icon_set_secret_Email_l", title: "Widgets")]),
SettingModel(sectionTitle: "Stay in touch",rowInfo: [RowInfoModel(imageName: "icon_set_secret_ins_setting", title: "Follow on Instagram"),
RowInfoModel(imageName: "icon_set_secret_rate_setting", title: "Rate Us"),
RowInfoModel(imageName: "icon_set_secret_share_setting", title: "Share Us"),]),
SettingModel(sectionTitle: "Other",rowInfo: [RowInfoModel(imageName: "icon_set_secret_Hint", title: "Hint"),
RowInfoModel(imageName: "icon_set_secret_keep", title: "Keep List"),
RowInfoModel(imageName: "icon_set_secret__vibration_setting", title: "Vibration",isSwitch:true)]),
SettingModel(sectionTitle: "Support",rowInfo: [RowInfoModel(imageName: "icon_set_secret_restore", title: "Resume purchase"),
RowInfoModel(imageName: "icon_set_secret_Email_support", title: "Email Support"),
RowInfoModel(imageName: "icon_set_secret_FAQ", title: "FAQ"),
RowInfoModel(imageName: "icon_set_secret_about_us", title: "About Us"),
RowInfoModel(imageName: "icon_set_secret_Privacy", title: "Privacy Policy"),]),]
} else {
if PMFaceIDManger.isAvailable() {
return [
SettingModel(sectionTitle: "",rowInfo: [RowInfoModel(imageName: "",title: "")]),
......@@ -71,6 +98,8 @@ func getSettingViewInfo() -> [SettingModel] {
SettingModel(sectionTitle: "Secret space",rowInfo: [RowInfoModel(imageName: "icon_set_secret_lock",title: "Use PIN" , isSwitch:true),
RowInfoModel(imageName: "icon_set_secret_Face",title: "Use Face ID",isSwitch:true),
RowInfoModel(imageName: "icon_set_secret_ChangePin",title: "Change PIN"),
RowInfoModel(imageName: "icon_set_secret_Del",title: "Remove After Import",isSwitch:true)]),
......@@ -90,7 +119,8 @@ func getSettingViewInfo() -> [SettingModel] {
RowInfoModel(imageName: "icon_set_secret_Email_support", title: "Email Support"),
RowInfoModel(imageName: "icon_set_secret_FAQ", title: "FAQ"),
RowInfoModel(imageName: "icon_set_secret_about_us", title: "About Us"),
RowInfoModel(imageName: "icon_set_secret_Privacy", title: "Privacy Policy"),]),]
RowInfoModel(imageName: "icon_set_secret_Privacy", title: "Privacy Policy"),]),
]
}else{
return [
SettingModel(sectionTitle: "",rowInfo: [RowInfoModel(imageName: "",title: "")]),
......@@ -99,7 +129,7 @@ func getSettingViewInfo() -> [SettingModel] {
SettingModel(sectionTitle: "Secret space",rowInfo: [RowInfoModel(imageName: "icon_set_secret_lock",title: "Use PIN" , isSwitch:true),
RowInfoModel(imageName: "icon_set_secret_Face",title: "Use Face ID",isSwitch:true),
RowInfoModel(imageName: "icon_set_secret_ChangePin",title: "Change PIN"),
RowInfoModel(imageName: "icon_set_secret_Del",title: "Remove After Import",isSwitch:true)]),
......@@ -122,37 +152,6 @@ func getSettingViewInfo() -> [SettingModel] {
RowInfoModel(imageName: "icon_set_secret_Privacy", title: "Privacy Policy"),]),]
}
}
return [
SettingModel(sectionTitle: "",rowInfo: [RowInfoModel(imageName: "",title: "")]),
SettingModel(sectionTitle: "E-mail",rowInfo: [RowInfoModel(imageName: "icon_set_secret_Email_l", title: "Log in")]),
SettingModel(sectionTitle: "Secret space",rowInfo: [RowInfoModel(imageName: "icon_set_secret_lock",title: "Use PIN" , isSwitch:true),
RowInfoModel(imageName: "icon_set_secret_Face",title: "Use Face ID",isSwitch:true),
RowInfoModel(imageName: "icon_set_secret_ChangePin",title: "Change PIN"),
RowInfoModel(imageName: "icon_set_secret_Del",title: "Remove After Import",isSwitch:true)]),
SettingModel(sectionTitle: "Practical tools",rowInfo: [RowInfoModel(imageName: "icon_set_secret_Email_l", title: "Widgets")]),
SettingModel(sectionTitle: "Stay in touch",rowInfo: [RowInfoModel(imageName: "icon_set_secret_ins_setting", title: "Follow on Instagram"),
RowInfoModel(imageName: "icon_set_secret_rate_setting", title: "Rate Us"),
RowInfoModel(imageName: "icon_set_secret_share_setting", title: "Share Us"),]),
SettingModel(sectionTitle: "Other",rowInfo: [RowInfoModel(imageName: "icon_set_secret_Hint", title: "Hint"),
RowInfoModel(imageName: "icon_set_secret_keep", title: "Keep List"),
RowInfoModel(imageName: "icon_set_secret__vibration_setting", title: "Vibration",isSwitch:true)]),
SettingModel(sectionTitle: "Support",rowInfo: [RowInfoModel(imageName: "icon_set_secret_restore", title: "Resume purchase"),
RowInfoModel(imageName: "icon_set_secret_Email_support", title: "Email Support"),
RowInfoModel(imageName: "icon_set_secret_FAQ", title: "FAQ"),
RowInfoModel(imageName: "icon_set_secret_about_us", title: "About Us"),
RowInfoModel(imageName: "icon_set_secret_Privacy", title: "Privacy Policy"),]),
]
}
class SettingConfiguration: NSObject {
......
......@@ -34,7 +34,7 @@ class SettingNormalCell : UITableViewCell {
lazy var fLabel : UILabel = {
let label = UILabel();
label.text = "ceshi"
label.font = UIFont(name: "PingFang SC-Bold", size: 14)
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.textAlignment = .left
return label
......
......@@ -55,7 +55,7 @@ class SettingSwitchCell : UITableViewCell {
lazy var fLabel : UILabel = {
let label = UILabel();
label.text = "ceshi"
label.font = UIFont(name: "PingFang SC-Bold", size: 14)
label.font = UIFont.systemFont(ofSize: 14, weight: .bold)
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.textAlignment = .left
return label
......
......@@ -163,10 +163,12 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
emailLoginSignOut()
break
case settingLabels.UsePIN.rawValue:
vibrate()
secretspace()
break
case settingLabels.UseFaceID.rawValue:
SetFaceID()
vibrate()
SetFaceID(indexPath)
break
case settingLabels.ChangePIN.rawValue:
changePIN()
......@@ -174,12 +176,15 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
case settingLabels.RemoveAfterImport.rawValue:
SettingConfiguration.share.config.removeImg = !SettingConfiguration.share.config.removeImg
tableView.reloadRows(at: [indexPath], with: .none)
vibrate()
break
case settingLabels.Widgets.rawValue:
let widget = WidgetViewController()
self.navigationController?.pushViewController(widget, animated: true)
break
case settingLabels.FollowonInstagram.rawValue:
guard let url = URL(string: "https://www.instagram.com/phone.manager.app/") else { return }
UIApplication.shared.open(url)
break
case settingLabels.RateUs.rawValue:
self.review()
......@@ -188,6 +193,8 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
self.PhoneShare()
break
case settingLabels.Hint.rawValue:
let hint = PMHintsController()
self.navigationController?.pushViewController(hint, animated: true)
break
case settingLabels.KeepList.rawValue:
let vc = MaintainViewListController()
......@@ -196,8 +203,8 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
case settingLabels.Vibration.rawValue:
SettingConfiguration.share.config.vibration = !(SettingConfiguration.share.config.vibration ?? false)
tableView.reloadRows(at: [indexPath], with: .none)
vibrate(true)
break
case settingLabels.Resumepurchase.rawValue:
break
......@@ -205,6 +212,8 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
break
case settingLabels.FAQ.rawValue:
let faq = PMFAQController()
self.navigationController?.pushViewController(faq, animated: true)
break
case settingLabels.AboutUs.rawValue:
break
......@@ -245,7 +254,7 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
}
// MARK: - 面容
private func SetFaceID() -> Void {
private func SetFaceID(_ indexPath:IndexPath) -> Void {
if SettingConfiguration.share.config.faceId == false {
if PMFaceIDManger.request() {
PMFaceIDManger.authenticateWithFaceID(reason: "Unlock privacy space") {[weak self] success, error in
......@@ -257,6 +266,7 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
}
}else{
SettingConfiguration.share.config.faceId = false
self.tableView.reloadRows(at: [indexPath], with: .none)
}
}
......@@ -292,9 +302,10 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
alert.callblock = { idx in
self.view.hideBlur()
if idx == 1 {
PMEmailManager.shareManager.signOut { success in
PMEmailManager.shareManager.signOut {[weak self] success in
if success {
EmailFilterManager.share.signOut()
self?.tableView.reloadData()
}
}
}
......@@ -304,6 +315,7 @@ class SettingViewController : BaseViewController , UITableViewDelegate, UITableV
let vc:EmailLoginController = EmailLoginController()
vc.state = .home
self.navigationController?.pushViewController(vc, animated: true)
self.tableView.reloadData()
}
}
......
......@@ -7,23 +7,120 @@
import UIKit
class PMWidgetExampleController: UIViewController {
class PMWidgetExampleController: UIViewController ,UIScrollViewDelegate{
@IBOutlet weak var PMWidgetMainBtn: UIButton!
@IBOutlet weak var PMWidgetLockBtn: UIButton!
@IBOutlet weak var PMWidgetMainScroll: UIScrollView!
@IBOutlet weak var PMWidgetLockScroll: UIScrollView!
@IBOutlet weak var PMWidgetPage: UIPageControl!
@IBOutlet weak var ReturnAction: UIButton!
@IBOutlet weak var NextActions: UIButton!
var current = 0 {
didSet{
if current == 0 {
ReturnAction.isHidden = true
}else{
ReturnAction.isHidden = false
}
NextActions.setTitle("Next", for: .normal)
if current == 4 {
NextActions.setTitle("Ok", for: .normal)
}
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)
}
}
}
}
var type = 0 {
didSet{
PMWidgetMainScroll.isHidden = !(type == 0)
PMWidgetLockScroll.isHidden = type == 0
current = 0
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
PMWidgetMainBtn.isSelected = true
PMWidgetMainBtn.setBackgroundImage(UIImage.Clear(.white), for: .normal)
PMWidgetMainBtn.setBackgroundImage(UIImage.Clear(UIColor.colorWithHex(hexStr: "#0082FF")), for: .selected)
PMWidgetLockBtn.setBackgroundImage(UIImage.Clear(.white), for: .normal)
PMWidgetLockBtn.setBackgroundImage(UIImage.Clear(UIColor.colorWithHex(hexStr: "#0082FF")), for: .selected)
PMWidgetPage.numberOfPages = 5
PMWidgetMainScroll.delegate = self;
PMWidgetLockScroll.delegate = self
type = 0
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
ScrollToCurrent(scrollView)
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if decelerate {
ScrollToCurrent(scrollView)
}
}
private func ScrollToCurrent(_ scroll:UIScrollView) -> Void {
let orx = scroll.contentOffset.x / scroll.width
PMWidgetPage.currentPage = Int(round(orx))
if orx == 0 {
ReturnAction.isHidden = true
}else{
ReturnAction.isHidden = false
}
NextActions.setTitle("Next", for: .normal)
if orx == 4 {
NextActions.setTitle("Ok", for: .normal)
}
}
@IBAction func PMWidgetActions(_ sender: UIButton) {
if sender.isSelected == false {
if sender == PMWidgetMainBtn {
PMWidgetLockBtn.isSelected = false
type = 0
}else{
PMWidgetMainBtn.isSelected = false
type = 1
}
sender.isSelected = true
}
}
@IBAction func BottomActions(_ sender: UIButton) {
if sender == ReturnAction {
self.current -= 1
}else{
if self.current == 4 {
self.dismiss(animated: true)
}else{
self.current += 1
}
}
}
@IBAction func PMClose(_ sender: Any) {
self.dismiss(animated: true)
}
*/
}
......@@ -9,21 +9,17 @@ import UIKit
class PMWidgetGuideStartController: UIViewController {
var callblock:(()->Void) = {}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
@IBAction func StartNextAction(_ sender: Any) {
callblock()
}
@IBAction func PMClose(_ sender: Any) {
self.dismiss(animated: true)
}
*/
}
<?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">
<?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>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
<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" customClass="PMWidgetGuideStartController" customModuleProvider="target">
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="PMWidgetGuideStartController" customModule="PhoneManager" 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"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<subviews>
<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"/>
<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"/>
<state key="normal" image="ic_widget_XXXXXXx"/>
<connections>
<action selector="PMClose:" destination="-1" eventType="touchUpInside" id="tNM-zg-9hj"/>
</connections>
</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">
<rect key="frame" x="36" y="131" width="321" height="43"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</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">
<rect key="frame" x="23" y="194" width="347" height="43"/>
<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"/>
<color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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"/>
</imageView>
<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"/>
<color key="backgroundColor" red="0.0" green="0.50980392156862742" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="58" id="H0t-sX-uiu"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Start using"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="Radius">
<real key="value" value="29"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="StartNextAction:" destination="-1" eventType="touchUpInside" id="IEs-GE-8pA"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" red="0.90588235294117647" green="0.94509803921568625" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<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="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 firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Gk6-53-p7B" secondAttribute="trailing" constant="34" id="GSF-eJ-WeK"/>
<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="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="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 firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="Jx3-dI-rXt" secondAttribute="trailing" constant="15" id="k0K-LP-VIv"/>
<constraint firstItem="Jx3-dI-rXt" firstAttribute="top" secondItem="fnl-2z-Ty3" secondAttribute="top" constant="10" id="vg9-KR-dTG"/>
</constraints>
<point key="canvasLocation" x="131" y="-12"/>
</view>
</objects>
<resources>
<image name="ic_widget_XXXXXXx" width="16" height="16"/>
<image name="ic_widget_guideus" width="306" height="442"/>
</resources>
</document>
......@@ -33,6 +33,14 @@ class WidgetViewController: BaseViewController {
super.viewDidLoad()
view.backgroundColor = .white
setUI()
let infoBut = UIButton(type: .custom)
infoBut.setImage(UIImage(named: "ic_widget_InfoRight"), for: .normal)
infoBut.addTarget(self, action: #selector(infoRightAction), for: .touchUpInside)
titleView.addSubview(infoBut)
infoBut.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-15)
make.centerY.equalTo(titleView.backBtn.centerY)
}
}
override func viewWillAppear(_ animated: Bool) {
......@@ -46,7 +54,52 @@ class WidgetViewController: BaseViewController {
var widgetIdx = 0
widgetIdx = widgets.rawValue * 10 + widgetMode
widgetAppgourp.share.PushWidgetData(widgetIdx, battery: Int(battery), storage: Int(storage))
PMAlert(messsage: "Set Widget Successfully")
let save = EmailSaveController()
save.state = .success
save.modalTransitionStyle = .crossDissolve
save.modalPresentationStyle = .overFullScreen
self.present(save, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now()+1.5) {
save.dismiss(animated: true) {
self.dismiss(animated: true)
self.jumpGuidePage()
}
}
}
var isJumpExample:Bool {
set {
UserDefaults.standard.set(newValue, forKey: "widgetStartIn")
UserDefaults.standard.synchronize()
}
get {
return UserDefaults.standard.bool(forKey: "widgetStartIn")
}
}
@objc private func infoRightAction() -> Void {
jumpGuidePage()
}
func jumpGuidePage() -> Void {
if isJumpExample {
let example = PMWidgetExampleController()
example.modalPresentationStyle = .overFullScreen
self.present(example, animated: true)
}else{
isJumpExample = true
let guide = PMWidgetGuideStartController()
guide.modalPresentationStyle = .overFullScreen
guide.callblock = {[weak self] in
guide.dismiss(animated: true)
guard let self = self else { return }
let example = PMWidgetExampleController()
example.modalPresentationStyle = .overFullScreen
self.present(example, animated: true)
}
self.present(guide, animated: true)
}
}
func setUI() -> Void {
......
......@@ -39,6 +39,7 @@ class EmailFilterFAVORITECell: UITableViewCell {
@IBAction func selectActions(_ sender: UISwitch) {
// sender.isOn = !sender.isOn
self.vibrate()
callblock(sender.isOn)
}
......
......@@ -21,6 +21,7 @@ class EmailFilterKeywordCell: UITableViewCell {
}
@IBAction func switchValueChange(_ sender: UISwitch) {
self.vibrate()
callblock("switch",sender.isOn)
}
......
......@@ -12,6 +12,7 @@ class EmailSaveController: UIViewController {
enum SuccessfromState {
case keyword
case signout
case success
}
var state:SuccessfromState = .keyword
......@@ -32,6 +33,9 @@ class EmailSaveController: UIViewController {
case .signout:
messageBox.text = "Exit successfully"
messageBox.textColor = .black
case .success:
messageBox.text = "complete"
messageBox.textColor = .black
}
}
......
......@@ -192,6 +192,7 @@ extension EmailCleanListView : UITableViewDataSource,UITableViewDelegate {
cell.callblock = {[weak self] in
guard let self = self else { return }
self.selectSet(indexPath)
self.vibrate()
tableView.reloadData()
}
return cell
......
......@@ -247,6 +247,7 @@ extension EmailContentView :UITableViewDelegate,UITableViewDataSource{
}
cell.callblock = {[weak self] in
guard let self = self else { return }
self.vibrate()
self.selectAll(indexPath)
tableView.reloadData()
}
......
......@@ -1208,6 +1208,7 @@ class SecretPhotoManager: NSObject, PhotoPickerControllerDelegate , CameraContro
callback!(-1,result.photoAssets)
}
func deleteAssets(_ assets:[PHAsset] = []) -> Void {
if assets.count > 0 {
PMLoadingHUD.share.show()
......
......@@ -6,6 +6,7 @@
//
import Foundation
import AudioToolbox
extension Int {
......@@ -119,3 +120,36 @@ extension CGFloat {
}
}
extension NSObject {
public func vibrate(_ all:Bool? = false) -> Void {
if all != nil {
DispatchQueue.main.async {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
}
}else{
if SettingConfiguration.share.config.vibration ?? false {
DispatchQueue.main.async {
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
}
}
}
}
}
extension UISwitch {
@IBInspectable var isVibration:Bool {
set{
self.addTarget(self, action: #selector(valueChangeVibration), for: .valueChanged)
}
get{
return false
}
}
@objc func valueChangeVibration() -> Void {
self.vibrate(true)
}
}
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