2016-12-24 8 views
-1

このコードは自分のものではなく、私はyoutubeビデオに従っていますlinked heretictactoeのスイッチ・プレイヤー

私は次のコードに問題があり、特定の部分と問題に絞っています。

import UIKit 

class ViewController: UIViewController { 

var activePlayer = 1 // cross 
var gameState = [0,0,0,0,0,0,0,0,0] 

@IBAction func action(_ sender: AnyObject) 
{ 
    if (gameState[sender.tag] == 0) 
    { 
     gameState[sender.tag] = activePlayer 

     if (activePlayer == 1) 
     { 
      sender.setImage(UIImage(named: "Cross.png"), for: UIControlState()) 
      activePlayer = 2 
     } 
     else 
     { 
      sender.setImage(UIImage(named: "Nought.png"), for: UIControlState()) 
      activePlayer = 1 
     } 
    } 

} 

主な問題は、私はgameState [sender.tag]の部分を理解していないということです。ここ

まず第一にコードがあります。私がプログラムを実行すると、私が持っているボタンを最初にクリックしても何もせず、次のクリックでcross.pngが必要になります。 最初の十字が配置された後、クリックすると何も生成されません。十字架は変わらず、空白のボタンも十字架やいたずらに変わることはありません。

ビデオチュートリアルでは、[sender.tag]の最後にgamestate [sender.tag-1]の末尾に "-1"を追加するように指示しますが、これを行うとエラーが発生しますプログラムが実行されたときにボタン上に表示されます。したがって、私はその部分を削除し、プログラムは実行されますが、前述の状況が発生します。

コミュニティカレッジのC++コースの紹介を終え、趣味としてSwift 3を学習しているので、この状況を簡単に説明できる基本的な情報が不足している可能性があります。

この状況の可能性を私の無知だけに基づいていることを前提にしていただき、ありがとうございます。私は送信者タグや他のものについて数日間は役に立たないことを学びました。私はこの状況から学ぶことができ、どんな情報にも感謝することを願っています!

+1

私はビデオを見ませんでした。しかし、コードから判断すると、*タグ*(1 ... 9)をストーリーボードエディタのすべてのボタンに割り当てる必要があります。 –

+0

チュートリアルはそのステップを経なかったし、彼のためにはうまくいくが、彼が追加する "-1"は配列が0から始まるので配列と一致するということを言及する。ボタンに何かを自動的に割り当てるオプションがありますが、ボタンにタグを割り当てたことはありませんので、それをやり直す方法を見て、これまでに発見したことがあればうまくいくかのように見えます。情報ありがとうございました。 –

+0

ボタンにタグを追加した後は完全に機能します。ビデオはそのステップを踏んだことはありません... Xcodeには、新しく作成されたボタンにタグを自動的に割り当てる何らかのオプションがありますか? 配列セットと一致させるためにsender.tagの最後に "-1"を追加しなければなりませんでしたが、今は完全に機能します。情報をいただきありがとうございます。 –

答えて

0

マーティンR.コメントのOPの問題に答えました(UIButtonタグは初期化されていません)。私は、タグを少し参考にしたいと思っています。

iOS/OS Xプログラミングのタグは、単にビューに割り当てられた整数識別子です。あなたが使うかどうかはあなた次第です。未設定のタグはデフォルトで0になります。

UIControlおよびそれらのすべてのサブクラス(UIButtonを含む)は、ターゲットアクションデザインパターンを使用します。このパターンは、ユーザーがコントロールとやり取りするときに特定のオブジェクト(ターゲット)に対して呼び出されるメソッド(アクション)をコントロールに割り当てることによって機能します。コントロールがサポートする各タイプのインタラクションに対して、異なるアクションメソッドを割り当てることができます(たとえば、ボタンのタッチダウンアクションをタッチアップアクションと区別することができます)。

アクションメソッドが呼び出されると、最初のパラメータとして、インタラクションが発生したUIControlインスタンスが返されます。このパラメータは、慣習的にはsenderと呼ばれています(コントロールが何らかの対話が発生したという通知を送信しているので意味があります)。

ここで、タック - タック - トゥーグリッドの9つのUIButtonを考えてみましょう。すべてのボタンは同じオンタップの動作をしているので、View Controller上で同じアクションメソッドを呼び出すようにすると便利です。 OPの質問では、アクションメソッドは文字通りaction(_ sender:)と呼ばれる関数です(これはsquareTapped(_ sender: UIButton)などより記述的なものが良いでしょうが、私は脱出します)。

ボタンがすべて同じアクションメソッドを呼び出すわけではない場合は、upperLeftCornerTapped()upperMiddleTapped()などのような悪夢に対抗しなければならず、そのすべてが同じことをします。それは設計とメンテナンスの両方の観点から非常に醜いです。

しかし、これは質問を頼む:すべてのボタンが同じアクションメソッドを呼び出しているので、どのように我々はボタンを区別しないが、実際にタップされたのですか?これがタグの入っている場所です。ボタンが設定されると、それぞれに固有の整数識別子が割り当てられます。

デフォルトではタグはゼロであるため、非ゼロのタグ値を使用することが必須です。したがって、タグで識別するビューは、明示的に有効と見なされます。

利便性と実用性の両面から、ボタンのインデックスは1から9までになります。これにより、各ボタンをゲーム状態変数に直接関連付けることができます。この場合、配列に0から始まるインデックスを得るためにtag - 1が使用されます。