2016-10-28 1 views
0

Я показываю popover segue после нажатия кнопки, чтобы добавить марку автомобиля к моему обзору выбора в оригинале viewController, чтобы пользователь мог вернуться и выбрать новый бренд, только что добавленный в этом выборе, новый бренд автомобиля добавляется в базу данных sussesfuly, но я не могу обновить представление picker, фактически после того, как popover уволен, ничего не произошло, я уже пытаюсь добавить reloadAllComponents in viewWillAppear, viewDidLoad, viewDidAppear, но ничего не произошло, кто-то может мне помочь?Как обновить представление сборщика в исходном viewController после отклонения popover в swift 3?

Пожалуйста, посмотрите на изображение ниже:

поповер:

enter image description here

Кнопка переход:

enter image description here

мой код:

OriginalViewController

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 
     } 
    } 
} 

поповер ViewController

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) 

} 
+0

Просто обновить источник данных массив 'pickerView' при добавлении нового бренда. – vaibhav

+0

Я нахожусь на моем телефоне так голый со мной. Вам нужно создать делегат для всплывающего диспетчера представлений. Поэтому перед тем, как вы покажете popover, вы установите делегат popover в качестве контроллера представления представления. И прежде чем вы отпустите popover, что вы делаете, вы сохраняете новый объект. Обязательно вызовите метод finishPendingChanges (возможно) в контексте управляемого объекта, чтобы убедиться. Если у вас есть два managedObjectContexts, убедитесь, что вы их синхронизируете. Затем вы вызываете метод делегата, который реализуется в представлении контроллера представления.Метод будет обновлять данные и перезагружать сборщик – DatForis

+0

Я уже пытаюсь создать экземпляр массива в popor viewController и обновить значение, но не работает, и я не знаю, где обновить значение в исходном viewController, потому что он предположительно должен быть синхронизирован с моделью popover segue, но не работает ни @vaibhav –

ответ

0

После нескольких тестов я обнаружил, что ключ разворачивается, таким образом можно выполнить действие после того, как пользователь вернется в исходный сегмент, поэтому я изменяю стратегию просто увольнения для размотки segue следующим образом:

в оригинальной 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 
      } 
     } 
    } 
} 

в пироге ViewController добавить:

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 
} 

в stroyboard просто добавить разматывание SEGUE с помощью Ctrl + перетаскивания кнопки для выхода и edditing поля identifiere проверить t он в следующий раз изображения:

enter image description here

enter image description here

а также pickerView следует обновить и выбрать новый реестр только добавил

Смежные вопросы