iOS开发:UISwitch状态跨控制器传递、金额正负处理及导航栏显余额
问题1:传递UISwitch状态并处理金额正负
咱们可以通过属性传递的方式把UISwitch的状态传到NewOwedDetailViewController,具体步骤如下:
- 给
NewOwedDetailViewController新增一个布尔属性,用来标记欠款方向:
class NewOwedDetailViewController: UIViewController { // true = 他人欠我(金额为正),false = 我欠他人(金额为负) var isOwedByOthers: Bool = true // 你原有的其他代码... }
- 在触发跳转的视图控制器(比如联系人列表/详情页)里,把UISwitch的状态赋值给这个属性:
假设你用segue跳转,在prepare(for:sender:)里处理:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "toNewOwedDetail" { let destVC = segue.destination as! NewOwedDetailViewController // 假设你的UISwitch叫oweTypeSwitch destVC.isOwedByOthers = oweTypeSwitch.isOn // 别忘了传递已有的person对象 destVC.person = selectedPerson } }
- 在保存欠款记录时,根据这个属性处理金额正负:
比如你有一个保存按钮的点击事件,逻辑可以这么写:
@IBAction func saveRecord(_ sender: UIButton) { guard let amountText = amountTextField.text, let rawAmount = Double(amountText) else { // 处理金额输入无效的情况,比如弹个提示 return } // 根据switch状态计算最终金额 let finalAmount = isOwedByOthers ? rawAmount : -rawAmount // 处理新建/编辑逻辑 if let existingOwe = owe { // 编辑模式:更新现有记录 existingOwe.amount = finalAmount existingOwe.title = titleTextField.text existingOwe.location = locationTextField.text existingOwe.date = datePicker.date } else { // 新建模式:创建新的Owe对象 let newOwe = Owe(context: yourPersistentContainer.viewContext) newOwe.amount = finalAmount newOwe.title = titleTextField.text newOwe.location = locationTextField.text newOwe.date = datePicker.date newOwe.person = person } // 保存到数据库(假设用Core Data) do { try yourPersistentContainer.viewContext.save() navigationController?.popViewController(animated: true) } catch { print("保存失败:\(error.localizedDescription)") } }
如果是编辑现有记录,记得在viewDidLoad里初始化switch状态:
override func viewDidLoad() { super.viewDidLoad() // 你原有的代理设置等代码... // 编辑模式下,根据已有金额设置switch和输入框 if let existingOwe = owe { isOwedByOthers = existingOwe.amount > 0 amountTextField.text = String(abs(existingOwe.amount)) } }
问题2:导航栏标题显示联系人余额
核心是先计算该联系人的所有欠款总和,再把这个值设置为导航标题,步骤如下:
- 在显示联系人详情的视图控制器(比如
PeopleDetailViewController)里,写一个计算余额的方法:
假设你用Core Data,People和Owe是一对多关系(person?.ows是该联系人的所有欠款记录):
class PeopleDetailViewController: UIViewController { var person: People? private func computeTotalBalance() -> Double { guard let owes = person?.ows as? Set<Owe> else { return 0 } // 累加所有欠款记录的金额(正为他人欠我,负为我欠他人) return owes.reduce(0) { total, owe in total + owe.amount } } }
- 设置导航标题,并且在视图出现时刷新(因为从
NewOwedDetailViewController返回后,余额可能变化):
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) updateNavigationTitle() } private func updateNavigationTitle() { let balance = computeTotalBalance() // 格式化余额显示,让用户一眼看懂 let titleText: String if balance > 0 { titleText = String(format: "余额: +¥%.2f", balance) } else if balance < 0 { titleText = String(format: "余额: -¥%.2f", abs(balance)) } else { titleText = "余额: ¥0.00" } navigationItem.title = titleText }
- 确保欠款更新后标题能自动刷新:
如果用popViewController返回,viewWillAppear会自动触发,标题就会刷新。如果是其他跳转方式,也可以用通知来触发刷新:
在NewOwedDetailViewController保存成功后发送通知:
// 保存成功后 NotificationCenter.default.post(name: NSNotification.Name("BalanceDidUpdate"), object: nil)
然后在PeopleDetailViewController里监听:
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(updateNavigationTitle), name: NSNotification.Name("BalanceDidUpdate"), object: nil) } // 记得在销毁时移除监听 deinit { NotificationCenter.default.removeObserver(self) }
内容的提问来源于stack exchange,提问作者John Shah
相关产品推荐
相关产品推荐

