2017-10-24 18 views
2

私は簡単なカスタムコンバータアプリを開発中です。 問題は、(華氏から摂氏、オンスからキログラムまでの)各変換(!)変換ごとに別々のビューコントローラを作成して、どのように1つのコンバータビューコントローラしか再利用できないか知りたいのですがバックグラウンドで計算が行われましたか?Swift:View Controllerを再利用する方法

これは私がこれまでにやっていることです:

  • mainVC(各コンバータViewControllerをするためのボタンが含まれています)
  • (今10)ユーザーが
  • mathlibに操作を行うことができ、各変換するコンバータのVC。各計算式に異なる機能を迅速に表示する

各コンバータVCには、名前ラベル(たとえば、オンスからキログラム)、数字パッド、および入出力ラベルが含まれています。ユーザーが数字をタッチすると、MathLib.swiftの正しい数式でオンザフライで変換が行われます。私はちょうどリターンで対応する数式を使用します。 (!)今、私はちょうど1コンバータのVCを持つと、右の式がmathlibにに使用されているmainVCに押されたボタンの名前に依存している何をしたいのか

static func stoneToKilo(stone: Double) -> Double { 
     let kilo = stone/0.15747 
     return kilo 
    } 

:これは、式の一例ですラベルが正しい変換タイプに変更されます。

  1. すべてのボタンは1つのVCを指している必要があります。今、ボタンが押され、View Controllerが提示されると、どのボタンからユーザが来るかをチェックすることができますか?例えば、ボタン名やタグ?

  2. MathLib.swiftで正しい数式を使用したり、名前ラベルを変更するには、ボタン名やタグを知っていますか?私はスイッチケースを使用する必要がありますか?もしそうなら:どのように使用するボタンを確認するスイッチケースを設定し、右の数学関数をポイントし、名前ラベルを変更することができますか?要するに

:ちょうど1つのVCを使用して、どのボタンこのVCにユーザーをもたらし、その後、VC上のラベルのようにいくつかのことを変更して、右の機能を使用する(スイッチケース?)何かを使用してチェックしますlibrary.swiftファイル。

これは私にとっては非常に難しく、もしあなたが私を助けてくれたら、これを感謝します。

+0

あなたがあなたのためにあなたのコンバージョンを行うことができるので、あなたは[NSMeasurement](https://developer.apple.com/documentation/foundation/nsmeasurement)フレームワークを見ることから始まるでしょう。単一のView Controllerを持つことができ、すべてのボタンがVC上の適切な入力と出力の単位プロパティを設定するだけです。 – Paulw11

答えて

-1

変換を行うビューコントローラにデリゲートを渡す必要があります。これは、使用する機能を実装しています。ビューコントローラをプッシュまたはプレゼンテーションする前にインスタンス化するときは、デリゲートを挿入します。

プロトコルメソッドを使用するプロトコルを定義し、そのプロトコルメソッドをデリゲートが拡張機能を介して実装できるようにします。デリゲートは、コンバージョンタイプを選択できるViewControllerでもかまいません。

変換タイプで列挙型を定義し、それを新しいビューコントローラに渡すこともできます。ビューコントローラでは、型を切り替えて、適切なデリゲートメソッドを実行してください。あなたの先のビューコントローラで

enum ConversionType: Int { 
    case fahrenheitToCelsius 
    // other cases 
} 

protocol ConversionDelegate { 
    func convertToCelsius(fromFahrenheitDegrees fDegrees: Double) → Double 
    // other protocol functions 
} 

// Other protocols here 

class SelectionViewController: UIViewController { 
    // your usual stuff like viewDidLoad 

    func presentConversionViewController(forConversion type: ConversionType) { 
     let destinationVC = ... // instantiate your VC from storyboard here 
     destinationVC.delegate = self 
     destinationVC.conversionType = type 
     // present/push your VC 
} 

extension SelectionViewController: ConversionDelegate { 
    func convertToCelsius(fromFahrenheitDegrees fDegrees: Double) → Double { 
     // you Math.lib func here 
     return (fDegrees - 32)/1.8 // example 
    } 
    // implement the other functions 
} 

class DestinationViewController: UIViewController { 
    var delegate: ConversionDelegate! 
    var type: ConversionType! 

    // your usual stuff like viewDidLoad 

    @IBAction func calculateButtonPressed(_ sender: UIButton) { 
     switch type { 
      case .fahrenheitToCelsius: 
      // read the input value from somewhere like a UITextField 
      // most likely you will have to convert a String to Double in the example 
      let result = delegate.convertToCelsius(fromFahrenheitDegrees: yourInputValue) 
      // output the result to some label or whatever you like 
     } 
    } 
} 
+0

変換ごとに別々のプロトコルを使用するのはなぜですか?プロトコルの潜在的な価値は、それぞれが同じプロトコルに従う複数の異なるコンバータオブジェクトを持つことにあるようです。しかし、特にアプリケーションの他の部分が変換コードを必要としない場合は、不必要に複雑に思えます。 – Caleb

+0

申し訳ありませんが、思慮深く混乱してしまったので、答えを更新しました。 – erikmartens

2

あなたは正しい軌道に乗っています。

名前やタグで言われたように、どのボタンがクリックされたのかを知ることができました(私は、あなたのアプリを別の言語、つまりローカリゼーションで利用できるようにしたいと考えています)。

メインビューコントローラには、入力とボタンのみが表示され、どの変換が使用されているかを知るための画面のタイトルになります。

計算(ビジネスロジック)に関して、変換と呼ばれる1つの引数を取るプロトコルを定義することをお勧めします。これは、ユーザーが変換したい値である1つの引数をとります。その後、

protocol Converter { 
    func convert(_ value : Double) -> Double 
} 

と作られているの変換がある限り多くのクラスを作成し、私は単なる一例を取ると、できるだけシンプルに保つ、キロメートルに変換メートルを考えてみましょう。

1)インスタンス化:

あなたがなり、あなたのハンドラで、キロメートルと呼ばれる最初の画面からボタンをタップしたときのが

class DistanceConverter : Converter { 
    func convert(_ value : Double) -> Double { 
     return value/1000.0 
    } 
} 

今コンバータープロトコルを実装する必要がありDistanceConverterそれを呼びましょうDistanceConverterのインスタンスです。

2)MainViewControllerのインスタンスをインストールします。手順1で作成したDistanceConverterインスタンスを与えます。

3)mainViewControllerのDistanceConverterの参照をiVarとして保持します。

ここで重要な点は、ConverterのタイプのiVarに保持することです。そのため、作成するConverterプロトコルを実装するすべてのクラスのインスタンスを保持できます。ボタン、あなたが別のものを作成するために、ステップ3で今

などを作っmainViewControllerのIVARに変換するメソッドを呼び出すmainViewControllerの「変換」のハンドラで

4)コンバータ、のは、華氏に摂氏を扱うTemperatureConverterは、新しいクラスを作成しましょう:あなたが最初の画面上のボタンtemeratureをタップすると

class TemperatureConverter : Converter { 
    func convert(_ value : Double) -> Double { 
     // return the calculation, 
    } 
} 

は: 1)DistanceConverterのインスタンスをインスタンス化します。 とし、残りのステップをこれまでと同じように繰り返します(残りのステップはすべて簡単にリファクタリングできます)。

これは箱から取り出した戦略パターンなので、それについて読むことをお勧めします。

+0

あなたの答えをありがとう。私は質問のカップルを持っています。 1.プロトコルとクラスを別の高速ファイル(MathLib.swiftなど)に入れることはできますか? 2.私が理解していないことは、インスタンス/ハンドラーのことです。これまでは、ConverterVCをMainVCに接続し、スイッチを使ってボタンのタグを確認し、それに応じてラベル(など)を変更しました。コンバータのボタンを押すと、別のswitch文を使用してタグを再度確認し、MathLib.swiftの関連する数式関数を使用します。これは以前よりもはるかに簡単ですが、あなたの提案はもっと短くなっていると思います! – RjC

+0

ハンドラはIBActionの実装を意味します。 私が説明したことは必ずしもそれを行うより短い方法ではなく、これはあなたの主な焦点ではないはずです。時間の経過とともに維持しやすいコードを書くことに焦点を当てるべきです。 Switch文は長期的には悪いので、多態性を使用することで回避できます。良い仕事を続けてください:) – TheFuquan

関連する問題