2017-11-14 28 views
-1

私の現在のプロジェクトでは、1つのビューにタイマーを実装しました。 次のビューにつながるボタンをクリックすると、前のビューの最後に表示された時間が表示されます。View Controllerから別のView Controllerに時間を転送するにはどうすればいいですか?

これは私の現在のコードです:

import UIKit 

class ViewController2: UIViewController, UITableViewDataSource, UITableViewDelegate { 


@IBOutlet weak var myTableView: UITableView! 

@IBOutlet weak var labelMinute: UILabel! 
@IBOutlet weak var labelHour: UILabel! 
@IBOutlet weak var labelSecond: UILabel! 

weak var timer: Timer? 
var startTime: Double = 0 
var time: Double = 0 
var elapsed: Double = 0 
var status: Bool = false 

var psgTextField: UITextField? 
var emTextField: UITextField? 


public var passengers2 = [""] 

public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return passengers2.count 
} 


public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell2 = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell2") 
    cell2.textLabel?.text = passengers2[indexPath.row] 

    return (cell2) 
} 

@objc func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){ 

    if editingStyle == UITableViewCellEditingStyle.delete { 

     let alertController = UIAlertController(title: "Do you really want to leave?", 
               message: nil, 
               preferredStyle: .alert) 


     alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) 

     alertController.addAction(UIAlertAction(title: "Leave", style: .default, handler: { action in self.passengers2.remove(at: indexPath.row) 
      self.myTableView.deleteRows(at: [indexPath], with: .automatic) 
     })) 

     self.present(alertController, animated: true) 


    } 
} 



override func viewDidLoad() { 
    super.viewDidLoad() 

    startTime = Date().timeIntervalSinceReferenceDate - elapsed 
    timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true) 

    status = true 

} 

@objc func updateCounter() { 

    // Calculate total time since timer started in seconds 
    time = Date().timeIntervalSinceReferenceDate - startTime 

    // Calculate minutes 
    let minutes = UInt8(time/60.0) 
    time -= (TimeInterval(minutes) * 60) 

    // Calculate seconds 
    let hours = UInt8(time/3600) 
    time -= TimeInterval(hours) 

    let seconds = UInt8(time) 
    time -= TimeInterval(seconds) 

    // Format time vars with leading zero 
    let strMinutes = String(format: "%02d", minutes) 
    let strHour = String(format: "%02d", hours) 
    let strSecond = String(format: "%02d", seconds) 

    // Add time vars to relevant labels 
    labelMinute.text = strMinutes 
    labelHour.text = strHour 
    labelSecond.text = strSecond 

} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    let thirdController = segue.destination as! ViewController3 
    thirdController.timeHour.text = labelHour.text 

    let fourthController = segue.destination as! ViewController3 
    fourthController.timeMinute.text = labelMinute.text 
} 
} 

最後の「オーバーライド」機能がなければ、私の最初のビュー上のタイマーが完璧に動作しますが、何らかの理由で、それは私の上のラベルには時間を転送しません。 2番目のビュー( "timeHour"、 "timeMinute")。

XcodeではエラーThread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)が返されますが、インターネットで見つかったケースは私のものとは異なります。

誰かが問題の原因を知っていますか?

答えて

1

が私の考えです: 1.正しくセグエあなたのセットアップをしましたか? 2. segueを使用してデータを渡すと、データを渡して、ビューイベントで確実に処理する必要があります。

いくつかのサンプルコードは、次のようになります。あなたは、ビューコントローラを受信する一方で、

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     // Get the new view controller using segue.destinationViewController. 
     // Pass the selected object to the new view controller. 

     if (segue.identifier == "YourSegueIdentifier") { 
      let destinationVC = segue.destination as! YourSegueViewController; 

      destinationVC.passedData = "some-data-to-pass"; 
     } 
    } 

あなたのviewDidLoad関数にそれを扱う、例えば

var passedData: String!; 

func viewDidLoad() { 
    self.txtName.text = passedData; 
} 
+0

こんにちはパラマイ、私はかなり私のセグが正しいことを、少なくとも最後のオーバーライド機能なしで、私は何の問題もなく2番目のビューに行くことができると確信しています、時間は単に動作しません。私はあなたのコードを一瞬で試してみるでしょうが、これ以上のバックアップではないので、アプリは最悪の場合にはクラッシュしません。私はプログラミングで非常に新しいですが、まだたくさんのことを学ぶ必要があります – Robin

+0

あなたのセグが正しいと確信している場合は、上記のようにUIアクセスコードを削除してみてください。 –

+0

そうですね、私はあなたの例でそれを提案していましたが、今はうまくいきます。どうもありがとう! – Robin

0

私の推測では、宛先ビューコントローラのアウトレットは、アクセスしようとするとまだ接続されていないと考えられます。コードの既存の行の下

thirdController.loadViewIfNeeded() 

:このコード行を追加してみてください。ここ

let thirdController = segue.destination as! ViewController3 
+0

ダニエルちょっと、申し訳ありませんが、私は本当にあなたのアイデアを得ていません。私はすでに "let thirdController"を持っており、それを2回宣言することはできません。 – Robin

+0

こんにちはRobin、上記の最初の行は、2番目の行を追加する場所を示しています。 :) 'thirdControllerという行だけを追加してください。loadViewIfNeeded() 'を既存の行の下に置きます。' let thirdController = segue.destination as! ViewController3'。私は彼の答えをより明確にするために更新しました –

+0

それは悪いアドバイスです。最初は、デスティネーションビューコントローラのアウトレットに触れてはいけません。 – matt

2

まず(これではありません本当の問題ですが、私はとにかくそれを言う必要があります)、あなたのコードは感嘆符で詰まっています。それらのいずれかがクラッシュする可能性があります。感嘆符は使用しないでください! (そのように)labelHournilとなります。あなたのlabelMinuteは、nilです。あなたのsegueの宛先はViewController3ではないかもしれません。すべてのコードは非常に危険です!感嘆符を使用するのではなく、それらのすべてを安全にチェックする必要があります。

しかし、本当の問題は、この行です:

thirdController.timeHour.text = // ... 

はあなたのthirdControllerはまだそのビューをロードしていないので、それはまだtimeHourラベルを持っていません。

あなたのタイミングはすべてオフです。しかしさらに悪いことに、その行の精神全体は間違っています。 決しては別のView Controllerのインターフェイスを妨害する必要があります。 ViewController3にはのプロパティが必要です.ViewController3はその値をviewDidLoadで取得し、自身のインターフェイスを設定することができます。

+0

こんにちは、私はあなたの助言がパラマのものとほとんど同じだと思っています。 – Robin

関連する問題