Skip to content

Commit ab87421

Browse files
author
DevelopLab
committed
1.Add SettingsViewController.swift
2.Fix launcher screen
1 parent 20a8d40 commit ab87421

9 files changed

Lines changed: 432 additions & 8 deletions

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ include $(THEOS)/makefiles/common.mk
77

88
APPLICATION_NAME = RebootTools
99

10-
RebootTools_FILES = AppDelegate.swift RootViewController.swift DeviceController.m
10+
RebootTools_FILES = AppDelegate.swift RootViewController.swift SettingsViewController.swift DeviceController.m
1111
RebootTools_FRAMEWORKS = UIKit CoreGraphics
1212
RebootTools_RESOURCES = Resources/Assets.xcassets
1313
$(APPLICATION_NAME)_SWIFT_BRIDGING_HEADER += $(APPLICATION_NAME)-Bridging-Header.h

PlistManagerUtils.swift

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import Foundation
2+
3+
class PlistManagerUtils {
4+
5+
// 单例实例
6+
static let shared = PlistManager(plistName: "userSettings")
7+
8+
private var plistFileURL: URL
9+
private var preferences: [String: Any]
10+
private var cachedChanges: [String: Any] = [:]
11+
private var isDirty = false
12+
13+
// 初始化 PlistManager,指定 plist 文件名
14+
private init(plistName: String) {
15+
// 获取沙盒中的 Preferences 目录路径
16+
let preferencesDirectory = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!
17+
self.plistFileURL = preferencesDirectory.appendingPathComponent("Preferences/\(plistName).plist")
18+
19+
// 如果 plist 文件不存在,则创建一个空的文件
20+
if !FileManager.default.fileExists(atPath: plistFileURL.path) {
21+
preferences = [:]
22+
save()
23+
} else {
24+
preferences = loadPreferences()
25+
}
26+
}
27+
28+
// 加载 plist 文件中的数据
29+
private func loadPreferences() -> [String: Any] {
30+
guard let data = try? Data(contentsOf: plistFileURL),
31+
let preferences = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any] else {
32+
return [:]
33+
}
34+
return preferences
35+
}
36+
37+
// 保存数据到 plist 文件
38+
private func save() {
39+
do {
40+
let data = try PropertyListSerialization.data(fromPropertyList: preferences, format: .xml, options: 0)
41+
try data.write(to: plistFileURL)
42+
} catch {
43+
print("Error saving preferences to plist: \(error.localizedDescription)")
44+
}
45+
}
46+
47+
// 获取指定 key 对应的 Int 值
48+
func getInt(forKey key: String, defaultValue: Int) -> Int {
49+
return preferences[key] as? Int ?? defaultValue
50+
}
51+
52+
// 获取指定 key 对应的 Bool 值
53+
func getBool(forKey key: String, defaultValue: Bool) -> Bool {
54+
return preferences[key] as? Bool ?? defaultValue
55+
}
56+
57+
// 获取指定 key 对应的 String 值
58+
func getString(forKey key: String, defaultValue: String) -> String {
59+
return preferences[key] as? String ?? defaultValue
60+
}
61+
62+
// 获取指定 key 对应的 Float 值
63+
func getFloat(forKey key: String, defaultValue: Float) -> Float {
64+
return preferences[key] as? Float ?? defaultValue
65+
}
66+
67+
// 获取指定 key 对应的 Double 值
68+
func getDouble(forKey key: String, defaultValue: Double) -> Double {
69+
return preferences[key] as? Double ?? defaultValue
70+
}
71+
72+
// 获取指定 key 对应的 Data 值
73+
func getData(forKey key: String, defaultValue: Data) -> Data {
74+
return preferences[key] as? Data ?? defaultValue
75+
}
76+
77+
// 获取指定 key 对应的 URL 值
78+
func getURL(forKey key: String, defaultValue: URL) -> URL {
79+
return preferences[key] as? URL ?? defaultValue
80+
}
81+
82+
// 获取指定 key 对应的 Array 值
83+
func getArray(forKey key: String, defaultValue: [Any]) -> [Any] {
84+
return preferences[key] as? [Any] ?? defaultValue
85+
}
86+
87+
// 获取指定 key 对应的 Dictionary 值
88+
func getDictionary(forKey key: String, defaultValue: [String: Any]) -> [String: Any] {
89+
return preferences[key] as? [String: Any] ?? defaultValue
90+
}
91+
92+
// 设置 Int 值
93+
func setInt(key: String, value: Int) {
94+
cachedChanges[key] = value
95+
isDirty = true
96+
}
97+
98+
// 设置 Bool 值
99+
func setBool(key: String, value: Bool) {
100+
cachedChanges[key] = value
101+
isDirty = true
102+
}
103+
104+
// 设置 String 值
105+
func setString(key: String, value: String) {
106+
cachedChanges[key] = value
107+
isDirty = true
108+
}
109+
110+
// 设置 Float 值
111+
func setFloat(key: String, value: Float) {
112+
cachedChanges[key] = value
113+
isDirty = true
114+
}
115+
116+
// 设置 Double 值
117+
func setDouble(key: String, value: Double) {
118+
cachedChanges[key] = value
119+
isDirty = true
120+
}
121+
122+
// 设置 Data 值
123+
func setData(key: String, value: Data) {
124+
cachedChanges[key] = value
125+
isDirty = true
126+
}
127+
128+
// 设置 URL 值
129+
func setURL(key: String, value: URL) {
130+
cachedChanges[key] = value
131+
isDirty = true
132+
}
133+
134+
// 设置 Array 值
135+
func setArray(key: String, value: [Any]) {
136+
cachedChanges[key] = value
137+
isDirty = true
138+
}
139+
140+
// 设置 Dictionary 值
141+
func setDictionary(key: String, value: [String: Any]) {
142+
cachedChanges[key] = value
143+
isDirty = true
144+
}
145+
146+
// 删除指定 key 的数据
147+
func remove(forKey key: String) {
148+
cachedChanges[key] = nil
149+
isDirty = true
150+
}
151+
152+
// 清除 plist 文件(删除整个文件)
153+
func clear() {
154+
do {
155+
try FileManager.default.removeItem(at: plistFileURL)
156+
preferences = [:]
157+
} catch {
158+
print("Error clearing plist file: \(error.localizedDescription)")
159+
}
160+
}
161+
162+
// 将更改保存到 plist
163+
func apply() {
164+
// 只有在有修改的情况下才进行保存
165+
if isDirty {
166+
// 将所有更改合并到 preferences 中,覆盖掉已存在的相同键
167+
for (key, value) in cachedChanges {
168+
preferences[key] = value
169+
}
170+
171+
// 执行保存操作
172+
save()
173+
174+
// 重置缓存和脏标记
175+
cachedChanges.removeAll()
176+
isDirty = false
177+
}
178+
}
179+
}

Resources/Info.plist

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<key>CFBundleDisplayName</key>
4444
<string>RebootTools</string>
4545
<key>UILaunchStoryboardName</key>
46-
<string>Launch Screen.storyboard</string>
46+
<string>LaunchScreen</string>
4747
<key>LSMinimumSystemVersion</key>
4848
<string>14.0</string>
4949
<key>CFBundleIcons</key>
@@ -81,5 +81,7 @@
8181
</dict>
8282
<key>LSApplicationCategoryType</key>
8383
<string>public.app-category.utilities</string>
84+
<key>CFBundleShortVersionString</key>
85+
<string>1.1</string>
8486
</dict>
8587
</plist>

Resources/en.lproj/Localizable.strings

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,17 @@
33
"Need_Install_With_TrollStore_text" = "Requires TrollStore installation";
44
"Reboot_Device_text" = "Reboot Device";
55
"Respring_text" = "Respring";
6-
"Show_Alert_Before_Starting_text" = "Show alert before starting";
6+
"Settings_text" = "Settings";
7+
"Done_text" = "Done";
8+
"General_text" = "General";
9+
"Timer_text" = "Timer";
10+
"About_text" = "About";
11+
"Enable_Function_text" = "Enable function";
12+
"Home_Screen_Quick_Actions_text" = "Home Screen quick actions";
13+
"Display_Root_Permission_text" = "Show root permission has been obtained text";
14+
"Enable_text" = "Enable";
15+
"Time_text" = "Time";
16+
"Action_text" = "Action";
17+
"Show_Alert_Before_Starting_text" = "Show alert before starting";
18+
"Version_text" = "Version";
19+
"Unknown_text" = "Unknown";

Resources/zh-Hans.lproj/Localizable.strings

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,17 @@
33
"Need_Install_With_TrollStore_text" = "需要使用TrollStore安装";
44
"Reboot_Device_text" = "重启设备";
55
"Respring_text" = "注销";
6-
"Show_Alert_Before_Starting_text" = "开始操作前显示提醒";
6+
"Settings_text" = "设置";
7+
"Done_text" = "完成";
8+
"General_text" = "通用";
9+
"Timer_text" = "计时器";
10+
"About_text" = "关于";
11+
"Enable_Function_text" = "启用的功能";
12+
"Home_Screen_Quick_Actions_text" = "图标快捷方式";
13+
"Display_Root_Permission_text" = "显示已获得Root授权提示";
14+
"Enable_text" = "启用";
15+
"Time_text" = "时间";
16+
"Action_text" = "执行的操作";
17+
"Show_Alert_Before_Starting_text" = "开始操作前显示提醒";
18+
"Version_text" = "版本";
19+
"Unknown_text" = "未知";

RootViewController.swift

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class RootViewController: UIViewController {
3131
checkPermissionLabel.translatesAutoresizingMaskIntoConstraints = false
3232
checkPermissionLabel.textAlignment = .center // 设置文本居中
3333

34-
var enable = self.checkInstallPermission()
34+
let enable = self.checkInstallPermission()
3535

3636
if(enable) {
3737
checkPermissionLabel.text = NSLocalizedString("Install_With_TrollStore_text", comment: "")
@@ -68,14 +68,22 @@ class RootViewController: UIViewController {
6868
respringButton.isEnabled = enable // 无权限的时候不允许点击
6969

7070
// 添加设置项
71-
let settingButton = UIButton(type: .system)
71+
let settingsButton = UIButton(type: .system)
72+
settingsButton.setTitle(NSLocalizedString("Settings_text", comment: ""), for: .normal)
73+
settingsButton.translatesAutoresizingMaskIntoConstraints = false
74+
settingsButton.addTarget(self, action: #selector(onClickSettingsButton), for: .touchUpInside)
75+
// 设置图标
76+
let settingsButtonIcon = UIImage(systemName: "gearshape")
77+
settingsButton.setImage(settingsButtonIcon, for: .normal)
78+
// 调整图标和文本之间的间距
79+
settingsButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: -5, bottom: 0, right: 0)
7280

7381
// 向View中添加控件
7482
self.view.addSubview(iconImageView)
7583
self.view.addSubview(checkPermissionLabel)
7684
self.view.addSubview(rebootButton)
7785
self.view.addSubview(respringButton)
78-
86+
self.view.addSubview(settingsButton)
7987

8088
// AutoLayout
8189
NSLayoutConstraint.activate([
@@ -99,7 +107,13 @@ class RootViewController: UIViewController {
99107
respringButton.heightAnchor.constraint(equalToConstant: 50),
100108
respringButton.topAnchor.constraint(equalTo: rebootButton.bottomAnchor, constant: 20),
101109
respringButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 50), // 左侧边距
102-
respringButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -50) // 右侧边距
110+
respringButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -50), // 右侧边距
111+
112+
settingsButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor), // 水平居中
113+
settingsButton.heightAnchor.constraint(equalToConstant: 50),
114+
settingsButton.topAnchor.constraint(equalTo: respringButton.bottomAnchor, constant: 30),
115+
settingsButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 50), // 左侧边距
116+
settingsButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -50) // 右侧边距
103117
])
104118
}
105119

@@ -118,6 +132,27 @@ class RootViewController: UIViewController {
118132
let deviceController = DeviceController()
119133
deviceController.respring()
120134
}
135+
136+
@objc func onClickSettingsButton() {
137+
let settingsViewController = SettingsViewController()
138+
// 嵌入到导航控制器
139+
let navController = UINavigationController(rootViewController: settingsViewController)
140+
// 设置导航栏完成按钮
141+
let doneButton = UIBarButtonItem(title: NSLocalizedString("Done_text", comment: ""), style: .done, target: self, action: #selector(onClickDoneButton))
142+
settingsViewController.navigationItem.rightBarButtonItem = doneButton
143+
// 设置模态视图的显示样式
144+
navController.modalPresentationStyle = .pageSheet
145+
navController.modalTransitionStyle = .coverVertical
146+
147+
// 显示带导航栏的 SettingsViewController
148+
present(navController, animated: true, completion: nil)
149+
150+
}
151+
152+
@objc func onClickDoneButton() {
153+
// 关闭模态视图
154+
dismiss(animated: true, completion: nil)
155+
}
121156
}
122157

123158
extension UIColor {

SettingsUtils.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
class SettingsUtils {
3+
static let shared = SettingsUtils()
4+
5+
private init() {}
6+
7+
var isDarkMode: Bool {
8+
get {
9+
return UserDefaults.standard.bool(forKey: "isDarkMode")
10+
}
11+
set {
12+
UserDefaults.standard.set(newValue, forKey: "isDarkMode")
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)