我的应用程序中有两个视图控制器。在第一个视图中,我显示核心数据对象。我有带有UILabel的自定义UIView来做到这一点。在第二个视图中,我有操作来添加新的核心数据对象。两者都嵌入UINavigationController中,其中第一个视图是根视图控制器。添加对象时,我想使用户回到根视图,但是它必须包含新数据。
我试图使用.popToRootViewController()操作,但是当我返回时,我的数据没有更新。我拥有与启动应用程序时相同的数据。
SecondViewController中的代码
private func saveCaffeineData(coffeeName: String, coffeeSelectedSize: String, coffeeCaffeineAmount: Double, coffeeshop: String, date: Date) {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "CaffeineData", in: managedContext)!
let caffeineData = NSManagedObject(entity: entity, insertInto: managedContext)
caffeineData.setValuesForKeys(["coffeeName" : coffeeName, "coffeeSize" : coffeeSelectedSize, "caffeineAmount" : coffeeCaffeineAmount, "coffeeShop" : coffeeshop, "date" : date])
do {
try managedContext.save()
allCaffeineData.append(caffeineData)
navigationController?.popToRootViewController(animated: true)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
FirstViewController中的代码
lazy var todaySummaryView: TodaySummaryView = {
let todaySummaryView = TodaySummaryView(todayCoffeeAmount: countTodayCaffeineAmount(), caffeineState: getCaffeineUserState()!)
todaySummaryView.translatesAutoresizingMaskIntoConstraints = false
todaySummaryView.backgroundColor = .white
todaySummaryView.layer.cornerRadius = 10
return todaySummaryView
}()
private func setupLayout() {
title = "Dashboard"
if caffeineData.count == 0 {
view.addSubview(nothingView)
view.addSubview(addDataButton)
addDataButton.addTarget(self, action: #selector(addCaffeine), for: .touchUpInside)
NSLayoutConstraint.activate([
nothingView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
nothingView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
nothingView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
nothingView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
addDataButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
addDataButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
addDataButton.heightAnchor.constraint(equalToConstant: 50),
addDataButton.widthAnchor.constraint(equalToConstant: 300)
])
} else {
view.addSubview(dashboardScrollView)
view.addSubview(addDataButton)
addDataButton.addTarget(self, action: #selector(addCaffeine), for: .touchUpInside)
dashboardScrollView.addSubview(dashboardScrollViewContentView)
dashboardScrollViewContentView.addSubview(todaySummaryView)
NSLayoutConstraint.activate([
dashboardScrollView.topAnchor.constraint(equalTo: view.topAnchor),
dashboardScrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
dashboardScrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
dashboardScrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
dashboardScrollViewContentView.topAnchor.constraint(equalTo: dashboardScrollView.topAnchor),
dashboardScrollViewContentView.leadingAnchor.constraint(equalTo: dashboardScrollView.leadingAnchor),
dashboardScrollViewContentView.trailingAnchor.constraint(equalTo: dashboardScrollView.trailingAnchor),
dashboardScrollViewContentView.bottomAnchor.constraint(equalTo: dashboardScrollView.bottomAnchor),
dashboardScrollViewContentView.centerXAnchor.constraint(equalTo: dashboardScrollView.centerXAnchor),
todaySummaryView.topAnchor.constraint(equalTo: dashboardScrollViewContentView.topAnchor, constant: 20),
todaySummaryView.centerXAnchor.constraint(equalTo: dashboardScrollViewContentView.centerXAnchor),
todaySummaryView.leadingAnchor.constraint(equalTo: dashboardScrollViewContentView.leadingAnchor, constant: 15),
todaySummaryView.trailingAnchor.constraint(equalTo: dashboardScrollViewContentView.trailingAnchor, constant: -15),
addDataButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
addDataButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
addDataButton.heightAnchor.constraint(equalToConstant: 50),
addDataButton.widthAnchor.constraint(equalToConstant: 300)
])
}
}
@objc private func addCaffeine() {
let destinationViewController = SelectCoffeeTableViewController()
navigationController?.pushViewController(destinationViewController, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "CaffeineData")
do {
caffeineData = try managedContext.fetch(fetchRequest)
setupLayout()
} catch let error as NSError {
print("Something goes wrong! \(error.description)")
}
}
private func countTodayCaffeineAmount() -> Float {
var caffeineAmount = Float()
let calendar = Calendar.current
let todayDate = Date()
let todayDay = calendar.component(.day, from: todayDate)
let todayMonth = calendar.component(.month, from: todayDate)
let todayYear = calendar.component(.year, from: todayDate)
for caffeineRow in caffeineData {
let caffeineDay = calendar.component(.day, from: caffeineRow.value(forKey: "date") as! Date)
let caffeineMonth = calendar.component(.month, from: caffeineRow.value(forKey: "date") as! Date)
let caffeineYear = calendar.component(.year, from: caffeineRow.value(forKey: "date") as! Date)
if (todayDay == caffeineDay && todayMonth == caffeineMonth && todayYear == caffeineYear) {
caffeineAmount += caffeineRow.value(forKey: "caffeineAmount") as! Float
}
}
return caffeineAmount
}
private func getCaffeineUserState() -> CaffeineState? {
var caffeineState: CaffeineState
let caffeineAmount = countTodayCaffeineAmount()
switch caffeineAmount {
case 0..<200:
caffeineState = .normal
case 200..<300:
caffeineState = .warning
case 300...:
caffeineState = .dangerous
default:
return nil
}
return caffeineState
CustomView中的代码
//
// TodaySummaryView.swift
// Caffeinee
//
// Created by Piotr Sirek on 11/06/2019.
// Copyright © 2019 Piotr Sirek. All rights reserved.
//
import UIKit
class TodaySummaryView: UIView {
var todayCoffeeAmount: Float = 0.0
var caffeineState: CaffeineState = CaffeineState.normal
lazy var todayLabel: UILabel = {
let todayLabel = UILabel()
todayLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
todayLabel.text = "Today"
todayLabel.textColor = .white
todayLabel.textAlignment = .center
todayLabel.translatesAutoresizingMaskIntoConstraints = false
return todayLabel
}()
lazy var todayLabelView: UIView = {
let todayLabelView = UIView(frame: CGRect(x: 0, y: 0, width: 74, height: 28))
todayLabelView.layer.cornerRadius = 5
todayLabelView.translatesAutoresizingMaskIntoConstraints = false
return todayLabelView
}()
lazy var todayStateLabel: UILabel = {
let todayStateLabel = UILabel()
todayStateLabel.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
todayStateLabel.textColor = .black
todayStateLabel.textAlignment = .left
todayStateLabel.translatesAutoresizingMaskIntoConstraints = false
todayStateLabel.numberOfLines = 0
return todayStateLabel
}()
lazy var caffeineAmountLabel: UILabel = {
let caffeineAmountLabel = UILabel()
caffeineAmountLabel.font = UIFont.systemFont(ofSize: 45, weight: .heavy)
caffeineAmountLabel.textAlignment = .left
caffeineAmountLabel.translatesAutoresizingMaskIntoConstraints = false
caffeineAmountLabel.text = "142"
return caffeineAmountLabel
}()
lazy var caffeineUnitLabel: UILabel = {
let caffeineUnitLabel = UILabel()
caffeineUnitLabel.font = UIFont.systemFont(ofSize: 18, weight: .heavy)
caffeineUnitLabel.textAlignment = .left
caffeineUnitLabel.translatesAutoresizingMaskIntoConstraints = false
caffeineUnitLabel.text = "mg"
return caffeineUnitLabel
}()
private func setupView() {
self.addSubview(todayLabelView)
self.addSubview(todayStateLabel)
self.addSubview(caffeineAmountLabel)
self.addSubview(caffeineUnitLabel)
todayLabelView.addSubview(todayLabel)
NSLayoutConstraint.activate([
todayLabelView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor, constant: 15),
todayLabelView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: 15),
todayLabelView.heightAnchor.constraint(equalToConstant: 28),
todayLabelView.widthAnchor.constraint(equalToConstant: 74),
todayLabel.centerXAnchor.constraint(equalTo: todayLabelView.centerXAnchor),
todayLabel.centerYAnchor.constraint(equalTo: todayLabelView.centerYAnchor),
todayLabel.heightAnchor.constraint(equalToConstant: 26),
todayLabel.widthAnchor.constraint(equalToConstant: 70),
todayStateLabel.topAnchor.constraint(equalTo: todayLabelView.bottomAnchor, constant: 20),
todayStateLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: 15),
todayStateLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor, constant: -15),
todayStateLabel.centerXAnchor.constraint(equalTo: layoutMarginsGuide.centerXAnchor),
caffeineAmountLabel.topAnchor.constraint(equalTo: todayStateLabel.bottomAnchor, constant: 15),
caffeineAmountLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor, constant: 15),
caffeineAmountLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor, constant: -15),
caffeineUnitLabel.leadingAnchor.constraint(equalTo: caffeineAmountLabel.trailingAnchor, constant: 0),
caffeineUnitLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor, constant: -20)
])
}
private func presentState(todayCoffeeAmount: Float, caffeineState: CaffeineState) {
caffeineAmountLabel.text = "\(todayCoffeeAmount)"
switch caffeineState {
case .normal:
todayLabelView.backgroundColor = UIColor(red:0.24, green:0.63, blue:0.98, alpha:1.0)
todayStateLabel.text = "Your caffeine level is quiet good today. Keep it up!"
case .warning:
todayLabelView.backgroundColor = UIColor(red:0.96, green:0.68, blue:0.42, alpha:1.0)
todayStateLabel.text = "Your caffeine now is near your daily limit. Be carefull!"
case .dangerous:
todayLabelView.backgroundColor = UIColor(red:1.00, green:0.31, blue:0.31, alpha:1.0)
todayStateLabel.text = "Your caffeine level is over your daily limit. Don’t drink any coffee for rest of the day."
}
}
override class var requiresConstraintBasedLayout: Bool {
return true
}
override var intrinsicContentSize: CGSize {
return CGSize(width: 340, height: 200)
}
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
init(todayCoffeeAmount: Float, caffeineState: CaffeineState) {
super.init(frame: CGRect())
setupView()
presentState(todayCoffeeAmount: todayCoffeeAmount, caffeineState: caffeineState)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
答案 0 :(得分:0)
您需要实现委托协议,或使用通知来更新第一个控制器。 这是一个如何使用委托的示例:
protocol SecondViewControllerDelegate: class {
func caffeineDataSaved(controller: SecondViewController)
}
class SecondViewController: UIViewController {
weak var delegate: SecondViewControllerDelegate?
private func saveCaffeineData(coffeeName: String, coffeeSelectedSize: String, coffeeCaffeineAmount: Double, coffeeshop: String, date: Date) {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "CaffeineData", in: managedContext)!
let caffeineData = NSManagedObject(entity: entity, insertInto: managedContext)
caffeineData.setValuesForKeys(["coffeeName" : coffeeName, "coffeeSize" : coffeeSelectedSize, "caffeineAmount" : coffeeCaffeineAmount, "coffeeShop" : coffeeshop, "date" : date])
do {
try managedContext.save()
allCaffeineData.append(caffeineData)
self.delegate?.caffeineDataSaved(controller: self)
navigationController?.popToRootViewController(animated: true)
} catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)")
}
}
}
首先,在FirstViewController
类中,将FirstViewController
声明为SecondViewController
的委托。您可以在ViewDidLoad
或实例化SecondViewController的任何地方执行此操作:
self.secondController.delegate = self
现在,在FirstViewController
中,您需要实现委托方法:
func caffeineDataSaved(controller: SecondViewController) {
//Update your view.
}