2016-09-02 22 views
1

私は、テキストフィールドの1つがクリックされたときに製品のリストを子供(警告ダイアログ)にポップアップ表示するアクティビティを作成しましたが、リストの1つのアイテムをクリックすると、アラートは却下された。子から親ビューコントローラへデータを渡す方法は?すぐに

ユーザーは、データを渡すために、コールバック機能を実装することが可能ないくつかの方法があります

import UIKit 

class ViewPopUpProduct: UIViewController { 

@IBOutlet var tableView: UITableView! 

var productDescription = ["Product 1","Product 2","Product 3"] 
var productID = ["prdct1","prdct2","prdct3"] 


// Global Variables 
struct Product { 
    static var ProductID = String() 
    static var ProductDescription = String() 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.showAnimate() 
    self.view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.4) 

    // Do any additional setup after loading the view. 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

@IBAction func cancelPopUp(sender: AnyObject) { 
    self.removeAnimate() 
} 


func showAnimate() 
{ 
    self.view.transform = CGAffineTransformMakeScale(1.3, 1.3) 
    self.view.alpha = 0.0; 
    UIView.animateWithDuration(0.25, animations: { 
     self.view.alpha = 1.0 
     self.view.transform = CGAffineTransformMakeScale(1.0, 1.0) 
    }); 
} 

func removeAnimate() 
{ 
    UIView.animateWithDuration(0.25, animations: { 
     self.view.transform = CGAffineTransformMakeScale(1.3, 1.3) 
     self.view.alpha = 0.0; 
     }, completion:{(finished : Bool) in 
      if (finished) 
      { 
       self.view.removeFromSuperview() 
      } 
    }); 
} 

//Mark - Table View 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return self.productID.count 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = self.tableView.dequeueReusableCellWithIdentifier("cell",forIndexPath: indexPath) as! ProductViewCell 

    cell.productLabel.text = productDescription[indexPath.row] 

    return cell 
} 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    tableView.deselectRowAtIndexPath(indexPath, animated: true) 

    Product.ProductID = String(productID[indexPath.row]) 
    Product.ProductDescription = String(productDescription[indexPath.row]) 

    self.removeAnimate() 

} 

} 
+1

あなたが表示したコードとアラートのタイプを追加できますか? –

+1

あなたが行っていることについて私たちに適切なアイデアを与える、あなたが実装したいくつかのコードで質問を更新してみてください。それに基づいてあなたに最高の答えを提案します。 – Tuhin

+0

unexpectedNil私はすでに質問を更新しています –

答えて

1

あなたがここにデリゲート

は非常に、非常に簡単な説明、ノーBSで/プロトコルを使用することができます。また、あなたはこのような何かを行うことができNSNotificationCenter

を使用することができます https://www.youtube.com/watch?v=guSYMPaXLaw

またはあなたの状況で:

"送信者"ビューコントローラが行うでしょう

let nc = NSNotificationCenter.defaultCenter() 
nc.postNotificationName("printValue", object: nil, userInfo: ["value" : "Pass Me this string"]) 

受信者ビューコントローラは通知を聞くことができます。

let nc = NSNotificationCenter.defaultCenter() 
nc.addObserver(self, selector: #selector(printValue), name: "printValue", object: nil) 

func printValue(notification:NSNotification) { 
    let userInfo:Dictionary<String,String> = notification.userInfo as! Dictionary<String,String> 
    let item = userInfo["value"]! as String 

    print(item,self) 
} 
+1

ありがとうございますが、問題は私がセグを使用していないことです 子ビューを読み込み、アイテムのテーブルをクリックすると、選択したアイテムを取得し、子ビュー を破棄し、テキストフィールドにグラブデータを表示します。 –

+0

「NSNotification」は、関連するView Controllerにとって最悪で最も高価な方法です。プロトコル/デリゲートははるかに優れています(コールバックは最先端のものです)。 – vadian

+0

ありがとうございます! –

4

項目の上でクリックしたときに、これは親ビュー

import Foundation 
import UIKit 

class ViewAward: UIViewController{ 

@IBOutlet var tfMCN: UITextField! 
@IBOutlet var tfAmount: UITextField! 
@IBOutlet var tfProduct: UITextField! 
@IBOutlet var tfTotal: UITextField! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let rightAddBarButtonItem:UIBarButtonItem = UIBarButtonItem(title: "Send", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(ViewAward.searchTapped)) 

    self.navigationItem.setRightBarButtonItems([rightAddBarButtonItem], animated: true) 

    let state = String(ViewPopUpProduct.Product.ProductDescription) 
    print("My view state:"+state) 

    self.tfProduct.text = state 
    tfProduct.addTarget(self, action: #selector(ViewAward.productTapped), forControlEvents: UIControlEvents.TouchDown) 

} 

func searchTapped(sender:UIButton) { 

    let alertController = UIAlertController(
     title: "Award", 
     message:"Award successfully posted!", 
     preferredStyle: UIAlertControllerStyle.Alert) 
    alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil)) 

    self.presentViewController(alertController, animated: true, completion: nil) 
} 

func productTapped(textfield: UITextField){ 

    //tfProduct.endEditing(true) 
    tfProduct.resignFirstResponder() 

    let popOverVC = UIStoryboard(name:"Main",bundle:nil).instantiateViewControllerWithIdentifier("sbPopUpID") as! ViewPopUpProduct 

    self.addChildViewController(popOverVC) 

    popOverVC.view.frame = self.view.frame 

    self.view.addSubview(popOverVC.view) 

    popOverVC.didMoveToParentViewController(self) 

} 
} 

、これです。

  • ポスト通知
  • しかし、私は最善の方法であるデリゲートを使用することをお勧めしますが、ポストの通知でもある道が、私をブロックコールバックを使用して

    • 委任
    • 好むことを望まない。

    +0

    コードを教えてもらえますか?私は既にグローバル変数を割り当てていますが、子フィールドが解除されていないときにビューがリロードされたときにテキストフィールドの値を更新します。 –

    4

    私は通常、この目的でクロージャを使用します。はるかに簡単かつ代表者よりも少ない冗長:

    class MainViewController: UIViewController { 
    
        func showChildViewController() { 
         guard let vc = storyboard?.instantiateViewControllerWithIdentifier("ChildViewController") as? ChildViewController else { 
          return 
         } 
         vc.didSelectItem = { [weak self](item) in 
          if let vc = self { 
           // Do something with the item. 
          } 
         } 
         presentViewController(vc, animated: true, completion: nil) 
        } 
    
    } 
    
    class ChildViewController: UIViewController { 
    
        var didSelectItem: ((item: Item) -> Void)? 
    
        @IBAction func buttonPressed() { 
         didSelectItem?(item: <#your item goes here#>) 
        } 
    
    } 
    
    +0

    は、私は子供を表示するために、これを使用し productTapped(テキストフィールド:UITextFieldの)FUNC 'コード' { //tfProduct.endEditing(true) tfProduct.resignFirstResponder() せpopOverVC = UIStoryboard(名称: "メイン" 、バンドル:なし).instantiateViewControllerWithIdentifier( "sbPopUpID")as! ViewPopUpProduct self.addChildViewController(popOverVC) popOverVC.view.frame = self.view.frame self.view.addSubview(popOverVC.view) popOverVC.didMoveToParentViewController(自己) } 'コード' –

    +0

    @JosephVincentMagtalas私はあなたにそれを達成するための一般的な考えを与えました。あなた自身のニーズに自分の答えを適応させてください。 –

    +0

    どこからのアイテムですか? 'var didSelectItem:((item:Item) - > Void)の ? ' アプリを開発しています。 ありがとう –

    2
    1. 私の最初の好みはより速く、より完璧なカスタム委任する必要があります。 (コールバックとしてクロージャを使用することができるなら、それは完璧でなければなりません。コードを少し使って説明するために代理人を選んでください)

    2. あなたが対処しなければならないことがたくさんあるのでNSNotificationCenterをできるだけ避けてくださいこれを使用すると、代理人よりも少し遅くなります。あなたは簡単にバグに遭うかもしれません。

    ここに私のコードです。

    1. Child ViewController Setup。

    // TrendingProductPageViewController.swift 
        // buddyiOSApp 
        // 
        // Created by Tuhin Samui on 5/21/16. 
        // Copyright © 2016 Buddy. All rights reserved. 
        // 
    
        import UIKit 
    
        protocol TrendingProductsCustomDelegate: class { //Setting up a Custom delegate for this class. I am using `class` here to make it weak. 
         func sendDataBackToHomePageViewController(categoryToRefresh: String?) //This function will send the data back to origin viewcontroller. 
        } 
    
    
        class TrendingProductPageViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NetworkReachabilityDelegate { 
    
         @IBOutlet weak var productListTableView: UITableView! //Having a tableview outlet here from storyboard itself. BTW not going to explain with tableView delegate and datasource, Sorry..:(
    
         weak var customDelegateForDataReturn: TrendingProductsCustomDelegate? //Please use weak reference for this to manage the memory issue. 
    
    
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
          let rowNumberFromTable: Int = indexPath.row //Getting the index of the selected cell. 
          let dataToSendBack = moreMenuTableData[rowNumberFromTable] as! String //This is an array which contains the data for the tableview. Getting the exact data which is selected on the table. 
          customDelegateForDataReturn?.sendDataBackToHomePageViewController?(dataToSendBack) //Now sending the selected data back to parent viewController using the custom delegate which I made before.     presentingViewController?.dismissViewControllerAnimated(true, completion: nil) //Dismissing the viewController here. 
        } 
    

    2。親ViewControllerコードはこちら。

    class HomePageViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, TrendingProductsCustomDelegate, UINavigationControllerDelegate{ //Adding the protocol here as `TrendingProductsCustomDelegate` 
    
    @IBAction func topTrendingProductsBtnAction(sender: UIButton) { //Normal IBAction of UIButton as you are using. 
         let trendingProductsPageForAnimation = storyboard!.instantiateViewControllerWithIdentifier("showTrendingProductpage") as! TrendingProductPageViewController //You can understand this right. Same as yours. 
         trendingProductsPageForAnimation.customDelegateForDataReturn = self //Setting up the custom delegate for this class which I have written on the presenting class. 
         trendingProductsPageForAnimation.modalPresentationStyle = UIModalPresentationStyle.FullScreen 
         presentViewController(trendingProductsPageForAnimation, animated: true, completion: nil) //Same as yours. 
        } 
    
    
    func sendDataBackToHomePageViewController(categoryToRefresh: String?) { //Custom delegate function which was defined inside child class to get the data and do the other stuffs. 
         if categoryToRefresh != nil { 
          print("Got the data is \(categoryToRefresh)") 
         } 
        } 
    
    } 
    

    希望しました。ご迷惑をおかけして申し訳ありません。

    +0

    私はそれを試してみます –

    関連する問題