28955


言語はswift です。

複数のクラス間でのデータの受け渡し方法がわかりません。  
例えばクラス名 A,Bの二つがあったとして

[code]

    class A{
    var a = "値"
    }
    class B{
    }
    
[/code]

そしてクラスAで a = "値" と入れたものを  
クラスBで使いたいのですがその方法がわかりません。  
自分で調べて見る限り移譲の分野なのかな？と思ったのですが、、、

<追加>

クラスeditの imageView.image をクラスviewControllerで使う方法がわかりません。

[code]

    import UIKit
    
    var data = [String]()
    
    
    class edit: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
    
        @IBAction func tap(sender: UITapGestureRecognizer) {
            if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){
                let photo:UIImagePickerController = UIImagePickerController()
                photo.delegate = self
                photo.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
                self.presentViewController(photo,animated: true,completion: nil)
            }
    
        }        
        @IBOutlet weak var imageView: UIImageView!
    
        //画像が選択された時
        func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    
            if info[UIImagePickerControllerOriginalImage] != nil{
                imageView.image = info[UIImagePickerControllerOriginalImage] as? UIImage
    
            }
    
            picker.dismissViewControllerAnimated(true,completion:nil) 
       }   
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
        @IBOutlet weak var textField: UITextField!
    
    //Saveボタン
        @IBAction func save(sender: AnyObject) {
    
    
            data.append(textField.text!)
            textField.text = ""
    
    
    
            NSUserDefaults.standardUserDefaults().setObject(data, forKey: "pass")
            self.navigationController?.popViewControllerAnimated(true)
        }
    
    }
    
[/code]

* * *
[code]

    import UIKit
    
    class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
        @IBOutlet weak var table: UITableView!
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            if NSUserDefaults.standardUserDefaults().objectForKey("pass") != nil{
                data = NSUserDefaults.standardUserDefaults().objectForKey("pass") as! [String]
            }
    
        }
    
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return data.count
        }
    
        //日付取得
        func cat()->String{
            let month = NSDate()
            let year = NSDateFormatter()
            year.dateFormat = "y'年'M'月'd'日'"
            year.locale = NSLocale(localeIdentifier: "ja_JP")
            let str = year.stringFromDate(month)
    
            return str
    
        }
    
        func tableView(tableView:UITableView,cellForRowAtIndexPath indexPath:NSIndexPath)->UITableViewCell{
            let cell = tableView.dequeueReusableCellWithIdentifier("mycell",forIndexPath:indexPath) as! Custom
            cell.titleLabel?.text = cat()
            cell.subtitle?.text = data[indexPath.row]
    
            return cell
        }
        override func viewDidAppear(animated: Bool){
            table.reloadData()
        }
    
    }
    
[/code]

<追加>  
クラスViewControllerとクラスeditはstoryboardのviewControllerに一つずつ、つけていて  
クラスViewControllerのviewControllerからsegueで繋いでいます。  
よろしくお願いします。


CC BY-SA 3.0
2016-09-17T09:56:04.437
28949
2016-09-17T14:04:34.853
2016-09-17T12:08:34.170
18539
18539
question
swift
swift クラス間での値の受け渡し


明記されていませんが、データを受け渡すのは`UIImagePickerController`で「画像が選択された時」と言うことにしておきます。

iOSの画面遷移で、確実に遷移元と遷移先の両方のViewControllerインスタンスにアクセスできるのは、`prepareForSegue(_:sender:)`の中なのですが、それだけですと上記の「画像が選択された時」には呼んでくれないので、それとdelegateパターンを併用することになるでしょう。

具体的には:

  1. XcodeのStoryboardエディタ(Interface Builder)上で該当画面遷移のsegueに名前(identifier)をつけておく。  
→この回答では、EditSegueという名前をつけたことにします。

  2. delegateが実装する必要のあるメソッドをprotocolを使って定義しておく。
[code]     @objc protocol EditViewControllerDelegate {

        func editViewController(editViewController: EditViewController, didPickUpImage image: UIImage)
    }
    
[/code]

※`edit`のままでは読みづらくてコード例を書く気にもならなかったので、この回答中では`EditViewController`というクラス名にしてあります。必要に応じてあなたのアプリのクラス名に置き換えて読んでください。ちなみにプロジェクト内のどのファイルに書いてもかまいません。

  3. `ViewController`に`EditViewControllerDelegate`を実装する。
[code]     class ViewController:
UIViewController,UITableViewDelegate,UITableViewDataSource,
EditViewControllerDelegate {

        //...
    
        //EditViewControllerDelegateの実装
        func editViewController(editViewController: EditViewController, didPickUpImage image: UIImage) {
            //受け取った`image`を使う処理...
        }
    
        //...(次の`prepareForSegue(_:sender:)`もこのクラス内です
    }
    
[/code]

  4. `ViewController`に`prepareForSegue(_:sender:)`を実装する。
[code]         override func prepareForSegue(segue: UIStoryboardSegue, sender:
AnyObject?) {

    
            if segue.identifier == "EditSegue" {
                //segue.destinationViewControllerには、EditViewControllerのインスタンスが入っているはずなので`as!`で強制キャスト
                let destination = segue.destinationViewController as! EditViewController
                //EditViewControllerのdelegateを自分(ViewController)にする
                destination.delegate = self
            }
        }
    
[/code]

  5. `EditViewController`にdelegateを保持するインスタンスプロパティを追加する。
[code]     class EditViewController:
UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate
{

    
        //Reference cycleを避けるため、delegateはweakにすることが多い
        weak var delegate: EditViewControllerDelegate?
    
        //...
    }
    
[/code]

  6. `EditViewController`内の適切な場所で、`delegate`のメソッドを呼び出す。
[code]         //画像が選択された時

        func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
    
            if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
                imageView.image = image
                //delegateには、ViewControllerのインスタンスが入っているはずなので、そのインスタンスのメソッドを呼び出す
                delegate?.editViewController(self, didPickUpImage: image)
            }
    
            picker.dismissViewControllerAnimated(true,completion:nil)
        }
    
[/code]

上記のような手順で、`ViewController`内に定義したdelegateメソッド中で、`EditViewController`から渡された情報を受け取れる、と言うことになります。かなり複雑に見えるかもしれませんが、「編集用の子画面で編集したデータを親画面に渡す」と言う場合には多用されるパターンですので、慣れてしまってください。

また、delegateのメソッドが呼ばれるタイミングではUIの更新がうまくいかないこともあるので、そこら辺に対応するコードの追加が必要になる可能性も高いです。

問題文からよく読み取れなかった部分は推測で補っているので、他にもあれこれ修正しないと使えない(場合によっては根本的に違う方法にする必要がある…)かもしれませんが、あなたのアプリにあてはまるように修正しながら試してみてください。


CC BY-SA 3.0
2016-09-17T14:04:34.853
28955
2016-09-17T14:04:34.853
13972
28949
answer