2017-07-28 4 views
2

私は、ネットワークアップデートの結果をUITableViewCellのボタンにクロージャとして渡す方法を探しています。オンタブクロージャを実行した後、結果をUITableViewCellのボタンに渡しますか?

私は製品であり、いくつかのUITableViewCellsを持っています。これらのセルには、「カートに追加」ボタンがあります。私は、セットアップボタンのセル内のタッチハンドラを、私のUITableViewCell cellforRowAtIndexPath方法でbuttonTap閉鎖を設定し、そのハンドラが呼び出されたとき、buttonTap閉鎖を実行します。私はメインコントローラ上に存在するカートオブジェクトを更新してカートを処理します。彼らは彼らのカートに多くの項目を追加することができるかどう

カートの更新アクションの結果はtrueを返します。それに応じてボタンを更新します。私は代理人に対処する必要がないので、カートのロジック自体をセルから遠く離れた場所に置くことができるので、このアプローチが好きです。セルは、ボタンを有効/無効/読み込み/等にする方法を知っています。

/// Buttom tap callback callback. 
public typealias Selection =() -> Bool 

class MealTableViewCell: UITableViewCell { 
    var buttonTap: Selection? 

    // Runs when tapping the button 
    func didTapAdd() { 
     if let buttonBlock = buttonTap { 
      self.button.isLoading = true 

      // Simulate loading 
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { 
       self.button.enabled = buttonBlock() 
       self.button.isLoading = false 
      } 

     } 
    } 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = .... (fetch cell) 

    cell.buttonTap = { 
     // returns true if the user can add more items to their cart 
     return self.cart.update(product: product, quantity: 1) 
    } 
} 

私の質問は、現在、APIコールがないローカルです。私は現在、アイテムを追加したり削除したりするネットワークコールを使って、カートをAPI主導のものに切り替える予定です。つまり、今は非同期呼び出しであるので、私はもはや返すことができません私のcart.update(product:,quantity:)メソッドから、まったく返す、または返すことができます。

だから、私は、メソッドのシグネチャが

self.cart.update(product: product, quantity: 1, success: { canAddMore in 
    // API call succeeded 
}, failure: { error in 
    // fall failed 
}) 

質問することをリライトのような何かを行うことができますがどのように私はtableViewCellにcanAddMoreを渡すことができるということですか?私はSelectionがPARAMとしてブール値を取るブロック内に取ることの意味を再定義する場合、それが唯一のブロックはセル自体上で実行されたときに渡されるように、私は、コントローラからのそれのparamを渡すことはできません。

がどのように私は本当に任意の値にすることができ

cell.buttonTap = { 
    cell.buttonTap = { 
    self.cart.update(product: product, quantity: 1), success: { canAddMore in 
     // !!!! What can I call here to pass canAddMore to the cell. 
    }, failure: { error in 
    } 
    } 
} 

canAddMoreような何かを行うことができ、BOOLはちょうどこの一例です。私の大きな目標は、セルのロードとボタンの知識をコントローラー自体に結合することを避けることです。私がデリゲートを使用する場合、私は双方向のデリゲートでセルをコントローラの代理人にしなければならないでしょう。私は実際に閉鎖の結果をセルに戻すことが可能であることは肯定的ではないが、私はそこに存在することを望んでいる!

EDIT:それは、もともとその閉鎖による閉鎖と呼ばれる細胞(または任意のオブジェクト)に戻ってデータを渡すためにすべての可能性である場合、私は本当に答えるしようとしている大きな問題があります。テーブルビューでデータを変更するには、何百万もの方法がありますが、それは私が取り組もうとしている主なものです。

IもcanAddMore状態を格納する避けるために「見て」います(例えば、その製品の残量)に電力テーブルビューをメインの製品 '配列です。初期状態はそこに設定され、/ productsエンドポイントから返されますが、その後、在庫はカートのAPIアクションによって返されます。

+0

などhow(各製品)に「canAddMore」状態がありますか?それともショッピングカート全体の「canAddMore」状態ですか? – DonMag

+0

各製品について。製品の数量が残っている場合は、カートの 'updateItem'メソッドがロジックを処理します。 – chrismanderson

+0

OK - 回答を追加する(回答はあまりにも多いが、コメントにはあまりにも多い)... – DonMag

答えて

1

私はあなたがあなたがやりたいと思うものをやりたいとは思わない:)

一言で言えば、代わりにクロージャと呼ばれるセルに「口答え」しようとしているの、あなたはおそらくしたいですProductsデータ配列の各製品の「canAddMore」状態を追跡し、状態が変化したときにテーブル行を更新します。そう...ユーザーは、あなたが戻ってタップ(良く見えるものは何でも、ボタンをグレーアウトし、またはスピナーを表示)

  • コールを処理していることを示すために、その行の視覚的なフィードバックを与える
  • 「カートに追加」をタップ

    • 閉じるto add to cart APIコール
    • API呼び出しが返ってくると、ローカル商品データを更新して「canAddMore」状態を表示します
    • ボタンを更新するためにテーブル内の行をリロードします(アクティブ、非アクティブ、タイトルを変更するなど)

    とにかく似たような操作をする必要があるため、ユーザーがスクロールしてセルを再利用すると、各行のボタンが更新されます。

  • +0

    これは確かに良いスタートです。ローディング状態は私のスティックです。セル全体をリロードすると、読み込みアニメーションが少しばかげてしまうことがあります。私はcanAddMore状態(または数量または製品配列上のwhataveyou)の格納を避けることも検討していました。私は最初の数量を製品から入手できますが、カートに追加した後は、カートAPIの回答自体で処理します。しかし、悪い考えかもしれない:) – chrismanderson

    +0

    それは避けられないと思う。状態を保存する必要があります:/ – Christoph

    1

    通常、コールバックでセルの内容をtableView.reloadRows(at: [indexPath], with: true)に更新します。指定したセルにfunc tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCellが呼び出されます。これがメインキューで行われなければならないことを忘れないでください。

    関連する問題