按下按钮后,我将显示一个弹出窗口,目的是将汽车品牌添加到原始 viewController
中的选择器 View 中,以便用户可以返回并选择刚刚添加的新品牌该选择器 View ,新车品牌已成功添加到数据库中,但我无法更新选择器 View ,实际上在弹出窗口关闭后,什么也没有发生,我已经尝试在 viewWillAppear、viewDidLoad、viewDidAppear 中添加一个 reloadAllComponents
reloadAllComponents code> 但什么也没发生,有人可以帮助我吗?
请看下面的图片:
弹出框:
按钮继续:
我的代码:
原始 View Controller
import UIKit
import CoreData
class VehicleAddViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate, UIPopoverPresentationControllerDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
// MARK: - Model
var managedObjectContext: NSManagedObjectContext? = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext
// MARK: - Properties
private final var pickerBrandData: [String]?
private final var pickerBrandResult: String? = nil
override func viewDidLoad() {
super.viewDidLoad()
self.Brand.delegate = self
self.Brand.dataSource = self
}
// MARK: - Outlets
@IBOutlet weak var Brand: UIPickerView
//MARK: Data Sources
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch pickerView.tag {
case 1:
if pickerBrandData == nil {
return 0
} else {
return pickerBrandData!.count
}
default:
return 0
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch pickerView.tag {
case 1:
return pickerBrandData?[row]
default:
return nil
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
switch pickerView.tag {
case 1:
pickerBrandResult = pickerBrandData?[row]
default:
break
}
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
switch segue.identifier! {
case "Quick Brand Add Segue":
let DestViewController = segue.destination as? QuickBrandAddViewController
let ReceiveViewController = DestViewController?.contentViewController
if let PopOverD = ReceiveViewController?.popoverPresentationController {
let minimunSize = ReceiveViewController?.view.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
ReceiveViewController?.preferredContentSize = CGSize(width: (minimunSize?.width)!, height: (minimunSize?.height)!)
PopOverD.delegate = self
DestViewController?.newSetOfBrands = pickerBrandData
}
break
default:
break
}
// Pass the selected object to the new view controller.
}
}
extension UIViewController {
var contentViewController: UIViewController {
if let navcon = self as? UINavigationController {
return navcon.visibleViewController!
} else {
return self
}
}
}
弹出 View Controller
import UIKit
import CoreData
class QuickBrandAddViewController: UIViewController, UITextFieldDelegate {
// MARK: - Model
var managedObjectContext: NSManagedObjectContext? = (UIApplication.shared.delegate as? AppDelegate)?.managedObjectContext
var newSetOfBrands: [String]?
// MARK: - Properties
private final var activeTextField: UITextField?
// MARK: - Lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
self.Brand.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Outlets
@IBOutlet weak var Brand: UITextField!
// MARK: - Delegate
func textFieldDidBeginEditing(_ textField: UITextField) {
activeTextField = textField
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if activeTextField != nil {
updateDatabase(description: (activeTextField!.text)!)
}
managedObjectContext?.performAndWait {
self.newSetOfBrands = Car_Brand.fetchBrand(inManagedObjectContext: self.managedObjectContext!)!
}
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: {
self.activeTextField?.resignFirstResponder()
self.view.endEditing(true)
}, completion: nil)
presentingViewController?.dismiss(animated: true, completion: nil)
return false
}
// MARK: - Methods
private func updateDatabase(description: String) {
managedObjectContext?.perform {
_ = Car_Brand.insertNew(brandDescription: description, inManagedObjectContext: self.managedObjectContext!)
do {
try self.managedObjectContext?.save()
} catch let error {
print ("Core Data Error: \(error)")
}
}
printDatabesesStatistics()
}
private func printDatabesesStatistics() {
managedObjectContext?.perform() {
do {
let brandCount = try self.managedObjectContext!.count(for: NSFetchRequest(entityName: "Car_Brand"))
print (brandCount)
} catch let error {
print ("Core Data Error: \(error)")
}
}
}
}
CoreDataClass.swift
import Foundation
import CoreData
public class Car_Brand: NSManagedObject {
class func insertNew (brandDescription: String, inManagedObjectContext context: NSManagedObjectContext) -> Car_Brand? {
let request: NSFetchRequest<Car_Brand> = Car_Brand.fetchRequest()
request.predicate = NSPredicate (format: "brand = %@", brandDescription)
if let brand = (try? context.fetch(request))?.first {
return brand
} else if let brand = NSEntityDescription.insertNewObject(forEntityName: "Car_Brand", into: context) as? Car_Brand {
brand.brand = brandDescription
return brand
}
return nil
}
class func fetchBrand (inManagedObjectContext context: NSManagedObjectContext) -> [String]? {
let request: NSFetchRequest<Car_Brand> = Car_Brand.fetchRequest()
request.propertiesToFetch = ["brand"]
request.sortDescriptors = [NSSortDescriptor(key: "brand", ascending: true)]
if let preBrandList = try? context.fetch(request) as [Car_Brand] {
var brandList: [String] = []
for preBrandList in preBrandList {
brandList.append(preBrandList.brand!)
}
return brandList
} else {
return nil
}
}
}
CoreDataProperties.swift
import Foundation
import CoreData
extension Car_Brand {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Car_Brand> {
return NSFetchRequest<Car_Brand>(entityName: "Car_Brand");
}
@NSManaged public var brand: String?
@NSManaged public var id_brand: NSSet?
@NSManaged public var id_model: NSSet?
}
// MARK: Generated accessors for id_brand
extension Car_Brand {
@objc(addId_brandObject:)
@NSManaged public func addToId_brand(_ value: Vehicle)
@objc(removeId_brandObject:)
@NSManaged public func removeFromId_brand(_ value: Vehicle)
@objc(addId_brand:)
@NSManaged public func addToId_brand(_ values: NSSet)
@objc(removeId_brand:)
@NSManaged public func removeFromId_brand(_ values: NSSet)
}
// MARK: Generated accessors for id_model
extension Car_Brand {
@objc(addId_modelObject:)
@NSManaged public func addToId_model(_ value: Model)
@objc(removeId_modelObject:)
@NSManaged public func removeFromId_model(_ value: Model)
@objc(addId_model:)
@NSManaged public func addToId_model(_ values: NSSet)
@objc(removeId_model:)
@NSManaged public func removeFromId_model(_ values: NSSet)
}
最佳答案
经过多次测试,我发现关键是 unwind segue,这样用户回到原来的 segue 后就可以执行操作,所以我将 unwind segue 的 justmiss 策略更改为这样:
在原来的viewController中我添加:
// MARK: - Navigation
@IBAction func updateBrandPicker(segue: UIStoryboardSegue) {
_ = navigationController?.popViewController(animated: true)
var rowPosition = 0;
let previousPickerBrandData = pickerBrandData
// Fetch the new list of Brands
managedObjectContext?.perform {
self.pickerBrandData = Car_Brand.fetchBrand(inManagedObjectContext: self.managedObjectContext!)!
self.Brand.reloadAllComponents()
// Obtain new brand
let newSetBrands: Set = Set(self.pickerBrandData!)
var differencePickerBrandData: Set = Set(newSetBrands)
differencePickerBrandData.subtract(previousPickerBrandData!)
let theNewBrand = Array(differencePickerBrandData)
// Select the new brand in the pickerView
if theNewBrand.count > 0 {
for brandName in self.pickerBrandData! {
if brandName == theNewBrand[0] {
self.Brand.selectRow(rowPosition, inComponent: 0, animated: true)
break
}
rowPosition += 1
}
}
}
}
在弹出 View Controller 中我添加:
override func viewWillDisappear(_ animated: Bool) {
if Brand != nil {
updateDatabase(description: (Brand!.text)!)
}
self.performSegue(withIdentifier: "updateBrandPicker", sender: Any?.self)
}
// MARK: - Actions
@IBAction func Save(_ sender: UIBarButtonItem) {
presentingViewController?.dismiss(animated: true, completion: nil)
}
// MARK: - Delegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: {
self.Brand?.resignFirstResponder()
self.view.endEditing(true)
}, completion: nil)
presentingViewController?.dismiss(animated: true, completion: nil)
return false
}
在 Storyboard中,只需通过按住 Ctrl 键并拖动到“退出”按钮来添加展开转场,然后编辑标识符字段,检查下一个图像:
pickerView 应该更新并选择刚刚添加的新注册表
关于swift - 在 swift 3 中关闭弹出窗口后,如何更新原始 viewController 中的选择器 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40306841/