2016-10-28 8 views
0

オリジナルのviewControllerのピッカービューに車のブランドを追加する目的でボタンを押した後にポップオーバーセグを表示するので、そのピッカーのビューで追加されたばかりの新しいブランド、新車のブランドを選択することができますsussesfulyデータベースに追加されますが、実際にはポップオーバーが解除された後、ピッカービューを更新できません。何も起こっていません。すでにreloadAllComponents in viewWillAppear, viewDidLoad, viewDidAppearを追加しようとしていますが、何も起こりませんでした。swift 3でポップオーバーを解除した後、元のviewControllerでピッカービューを更新するにはどうすればよいですか?

親切に以下の画像を見て:

ポップオーバー:

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

を追加しました。 – vaibhav

+0

私は私の電話の上にいるので、私と一緒に裸です。あなたは、ポップされたViewControllerのためのデリゲートを作成する必要があります。したがって、ポップオーバーを表示する前に、プレゼンテーションビューコントローラーとしてポップオーバーのデリゲートを設定します。あなたがポップオーバーを却下する前に、あなたは新しいオブジェクトを保存します。マネージオブジェクトコンテキストのfinishPendingChanges(maybe)メソッドを呼び出して、必ず確認してください。 2つのmanagedObjectContextがある場合は、必ずそれらを同期してください。そして、プレゼンテーションビューコントローラで実装されているデリゲートメソッドを呼び出します。このメソッドはデータを更新し、ピッカーをリロードします – DatForis

+0

私は既にpopover viewControllerに配列のインスタンスを作成して値を更新しようとしていますが、動作していません。元のviewControllerの値をどこで更新するのかはわかりませんpopover segueのモデルと同期していると思われますが、@vaibhav –

答えて

0

いくつかのテストの結果、キーが巻き戻されていることが判明しました。ユーザーが元のセグに戻った後にアクションを実行することができるため、巻き戻しセグの解消の戦略を変更します。

私は追加の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で

stroyboardで

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 
} 

だけでCtrlキーを押しながらボタンを終了するドラッグ+とidentifiereフィールドをedditingによりアンワインドセグエを追加チェックt彼の次の画像:

enter image description here

enter image description here

そしてpickerViewは、新しいレジストリを更新し、選択すべきはちょうどあなたが新しいブランドを追加するときだけpickerView` `のデータソース配列を更新

関連する問題