如何将UISlider的值从SettingsVC传递到ViewController页面?
解决番茄钟应用中滑块值从SettingsVC传递到ViewController的问题
问题根源
你在ViewController的controll()方法里直接创建了SettingsVC()的新实例,这个实例和你之前弹出的设置页面实例完全无关,所以获取到的是滑块的默认值,不是用户调整后的数值。同时你没有在两个页面之间建立值传递的通道。
方案一:使用闭包(推荐,实现简单)
1. 修改SettingsVC,添加闭包属性
在SettingsVC里定义一个闭包,用于用户点击Done时传递滑块值:
import UIKit class SettingsVC: UIViewController { //MARK: - Sliders var focusTimeSlider = UISlider() let shortBreakTimeSlider = UISlider() let longBreakTimeSlider = UISlider() // 添加闭包属性,用于传递设置值 var onSettingsSaved: ((Int, Int, Int) -> Void)? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground title = "Settings" addCloseButton() // 调用添加按钮方法,确保Done按钮显示 } //MARK: - Done Button func addCloseButton(){ let button = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(onClose)) navigationItem.rightBarButtonItem = button } @objc func onClose(){ let focusTime = Int(focusTimeSlider.value) let shortBreakTime = Int(shortBreakTimeSlider.value) let longBreakTime = Int(longBreakTimeSlider.value) // 调用闭包传递值 onSettingsSaved?(focusTime, shortBreakTime, longBreakTime) self.dismiss(animated: true, completion: nil) print("Focus Time : \(focusTime)") print("Short Break Time : \(shortBreakTime)") print("Long Break Time : \(longBreakTime)") } // 滑块相关代码保持不变 //MARK: - Slider Actions func layoutFocusTimeSlider(){ focusTimeSlider.addTarget(self, action: #selector(focusSliderValueChanged(sender:)), for: .valueChanged) } @objc func focusSliderValueChanged(sender: UISlider){ focusTimeSliderValueLabel.text = String(Int(focusTimeSlider.value)) } func layoutShortBreakTimeSlider(){ shortBreakTimeSlider.addTarget(self, action: #selector(shortSliderValueChanged), for: .valueChanged) } @objc func shortSliderValueChanged(){ shortBreakTimeSliderValueLabel.text = String(Int(shortBreakTimeSlider.value)) } func layoutLongBreakTimeSlider(){ longBreakTimeSlider.addTarget(self, action: #selector(longSliderValueChanged), for: .valueChanged) } @objc func longSliderValueChanged(){ longBreakTimeSliderValueLabel.text = String(Int(longBreakTimeSlider.value)) } }
2. 修改ViewController,设置闭包并更新UI
弹出SettingsVC时设置闭包,接收传递回来的值并更新页面显示:
import UIKit class ViewController: UIViewController { let actionButton = SFActionButton() var minutesLabel = SFTimeLabel(text: "25") let secondsLabel = SFTimeLabel(text: "00") // 可以新增属性保存设置值 private var savedFocusTime = 25 override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground // 读取本地保存的设置,初始化页面 let savedTime = UserDefaults.standard.integer(forKey: "FocusTime") if savedTime != 0 { savedFocusTime = savedTime minutesLabel.text = String(savedFocusTime) } } @objc func controll(){ print("Saved Focus Time : \(savedFocusTime)") } @objc func settingsAction(){ let rootVC = SettingsVC() // 设置闭包接收值 rootVC.onSettingsSaved = { [weak self] focusTime, shortBreak, longBreak in guard let self = self else { return } // 更新主页面显示 self.savedFocusTime = focusTime self.minutesLabel.text = String(focusTime) // 保存到本地,下次启动保留设置 UserDefaults.standard.set(focusTime, forKey: "FocusTime") UserDefaults.standard.set(shortBreak, forKey: "ShortBreakTime") UserDefaults.standard.set(longBreak, forKey: "LongBreakTime") } let navVC = UINavigationController(rootViewController: rootVC) navVC.modalPresentationStyle = .fullScreen self.present(navVC, animated: true, completion: nil) } }
额外提示
- 确保
SettingsVC里的addCloseButton()在viewDidLoad中被调用,否则Done按钮不会显示。 - 使用
UserDefaults保存设置值,可以让用户调整的时长在应用重启后依然保留。
内容的提问来源于stack exchange,提问作者user15200527
相关产品推荐
相关产品推荐

