14724


質問の内容がわかりずらくてゴメンなさい。

縦４ 横４ の計１６個の画像を配置してあります。  
１５こは同じ画像なのですが１つ違う画像にしてあります。  
その違う１つをタッチするたびに違う場所に出現させたいのですがやり方がわかりません。

ランダムに再配置するやり方がわかりません

touchesBeganの所になんと書けばいいのでしょうか？

コードは以下のとうりです  
見よう見まねでやったので雑でゴメンなさい。

[code]

    class ViewController:UIViewController{
    
        private var myImageView: UIImageView!
        private var myImageView2: UIImageView!
        private var myImageView3: UIImageView!
        private var myImageView4: UIImageView!
        private var myImageView5: UIImageView!
        private var myImageView6: UIImageView!
        private var myImageView7: UIImageView!
        private var myImageView8: UIImageView!
        private var myImageView9: UIImageView!
        private var myImageView10: UIImageView!
        private var myImageView11: UIImageView!
        private var myImageView12: UIImageView!
        private var myImageView13: UIImageView!
        private var myImageView14: UIImageView!
        private var myImageView15: UIImageView!
        private var myImageView16: UIImageView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            myImageView = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage = UIImage(named: "images2.png")
            myImageView.image = myImage
            myImageView.layer.position = CGPoint(x: 60, y: 150)
            self.view.addSubview(myImageView)
    
    
            myImageView2 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage2 = UIImage(named: "images.png")
            myImageView2.image = myImage2
            myImageView2.layer.position = CGPoint(x: 140, y: 150)
            self.view.addSubview(myImageView2)
    
            myImageView3 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage3 = UIImage(named: "images.png")
            myImageView3.image = myImage3
            myImageView3.layer.position = CGPoint(x: 220, y: 150)
            self.view.addSubview(myImageView3)
    
            myImageView4 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage4 = UIImage(named: "images.png")
            myImageView4.image = myImage4
            myImageView4.layer.position = CGPoint(x: 300, y: 150)
            self.view.addSubview(myImageView4)
    
            myImageView5 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage5 = UIImage(named: "images.png")
            myImageView5.image = myImage5
            myImageView5.layer.position = CGPoint(x: 60, y: 250)
            self.view.addSubview(myImageView5)
    
            myImageView6 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage6 = UIImage(named: "images.png")
            myImageView6.image = myImage6
            myImageView6.layer.position = CGPoint(x: 140, y: 250)
            self.view.addSubview(myImageView6)
    
            myImageView7 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage7 = UIImage(named: "images.png")
            myImageView7.image = myImage7
            myImageView7.layer.position = CGPoint(x: 220, y: 250)
            self.view.addSubview(myImageView7)
    
            myImageView8 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage8 = UIImage(named: "images.png")
            myImageView8.image = myImage8
            myImageView8.layer.position = CGPoint(x: 300, y: 250)
            self.view.addSubview(myImageView8)
    
            myImageView9 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage9 = UIImage(named: "images.png")
            myImageView9.image = myImage9
            myImageView9.layer.position = CGPoint(x: 60, y: 350)
            self.view.addSubview(myImageView9)
    
            myImageView10 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage10 = UIImage(named: "images.png")
            myImageView10.image = myImage10
            myImageView10.layer.position = CGPoint(x: 140, y: 350)
            self.view.addSubview(myImageView10)
    
            myImageView11 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage11 = UIImage(named: "images.png")
            myImageView11.image = myImage11
            myImageView11.layer.position = CGPoint(x: 220, y: 350)
            self.view.addSubview(myImageView11)
    
            myImageView12 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage12 = UIImage(named: "images.png")
            myImageView12.image = myImage12
            myImageView12.layer.position = CGPoint(x: 300, y: 350)
            self.view.addSubview(myImageView12)
    
            myImageView13 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage13 = UIImage(named: "images.png")
            myImageView13.image = myImage13
            myImageView13.layer.position = CGPoint(x: 60, y: 450)
            self.view.addSubview(myImageView13)
    
            myImageView14 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage14 = UIImage(named: "images.png")
            myImageView14.image = myImage14
            myImageView14.layer.position = CGPoint(x: 140, y: 450)
            self.view.addSubview(myImageView14)
    
            myImageView15 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage15 = UIImage(named: "images.png")
            myImageView15.image = myImage15
            myImageView15.layer.position = CGPoint(x: 220, y: 450)
            self.view.addSubview(myImageView15)
    
            myImageView16 = UIImageView(frame: CGRectMake(0,0,60,60))
            let myImage16 = UIImage(named: "images.png")
            myImageView16.image = myImage16
            myImageView16.layer.position = CGPoint(x: 300, y: 450)
            self.view.addSubview(myImageView16)
    
            myImageView.userInteractionEnabled = true
            myImageView2.userInteractionEnabled = true
            myImageView3.userInteractionEnabled = true
            myImageView4.userInteractionEnabled = true
            myImageView5.userInteractionEnabled = true
            myImageView6.userInteractionEnabled = true
            myImageView7.userInteractionEnabled = true
            myImageView8.userInteractionEnabled = true
            myImageView9.userInteractionEnabled = true
            myImageView10.userInteractionEnabled = true
            myImageView11.userInteractionEnabled = true
            myImageView12.userInteractionEnabled = true
            myImageView13.userInteractionEnabled = true
            myImageView14.userInteractionEnabled = true
            myImageView15.userInteractionEnabled = true
            myImageView16.userInteractionEnabled = true
        }
    
        override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
            let touch = touches.first as! UITouch
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    
[/code]


CC BY-SA 3.0
2015-08-21T17:23:53.310
14715
2015-08-25T09:19:42.690
2015-08-24T04:00:55.267
7362
11019
question
ios swift xcode
画像の場所を指定した中でランダムにしたい。


アプリのグラフィックな部分の開発の、ひとつのテクニック、というかひとつの心得として、できるだけ構成を単純化するということが挙げられると思います。  
今回の件では、同じ画像15個＋異なる画像1個という16個で構成をするから、処理が複雑化しているといえます。これを、

> ・同じ画像（UIImage）のUIImageViewインスタンス16個、A01〜A16  
>  ・異なる画像のUIImageViewインスタンス1個、B

このように17個で構成すれば、とたんに単純化されます。A01〜A16は、格子状に配置して、終始固定したままにできます。A01〜A16の任意のインスタンスの上に、Bを重ねて配置すれば、当初想定した外見になります。あとは、ランダムにBの位置を移動するだけです。

もうひとつの心得を挙げさせてもらうならば、それはアプリのふるまいを、漠然とひとつのふるまいとイメージするのではなく、ひとつひとつの小さなパーツの組み合わせとしてイメージすることです。これも今回の件に即してみていけば、

> ・UIImageViewインスタンスBのタッチをトリガー（引き金）にしてイベントを起こす。  
>  ・UIImageViewインスタンスBの位置を、プログラムで移動する（変更する）。  
>  ・UIImageViewインスタンスBのとることができる位置（A01〜A16の位置）を、配列として保持する。  
>  ・ランダムに0〜15（まあ、1〜16でもかまいませんが）を返す関数を用意する。

このくらいのパーツに分けてみるといいんじゃないでしょうか？  
そして、個々のパーツについて、じぶんの知っている範囲、経験のある範囲でプログラムにできるかを検証して、無理なら、そのパーツについて、絞った質問をするよう、心がけるといいでしょう。

* * *

以上の方針に沿ったサンプルコードを掲載しておきます。（Xcode 7.0 Beta 5、Swift 2.0）（Xcode 6.4、Swift
1.2でも動作するはず）

**base16.png**

[![base16.png](https://i.stack.imgur.com/3B1Dc.png)](https://i.stack.imgur.com/3B1Dc.png)

**heart.png**

[![heart.png](https://i.stack.imgur.com/pFdRv.png)](https://i.stack.imgur.com/pFdRv.png)

Single View Applicationのプロジェクトを新規作成します。  
上のふたつの画像を、プロジェクトに追加します。  
`ViewController.swift`を下のように編集します。

**ViewController.swift**

[code]

    import UIKit
    
    class ViewController: UIViewController {
    
        // heartViewのプロパティtagを100とるす定数
        let heartTag = 100
        // 要素数16、CGPointの配列を用意する。
        var points = [CGPoint](count: 16, repeatedValue: CGPointZero)
    
        // ランダムな位置（CGPoint）を返すメソッド
        func randomPoint(under: Int) -> CGPoint {
            let n = Int(arc4random_uniform(UInt32(under)))
            // 「頼みもしない機能」を実装
            let tmp = points[n]
            points[n] = points[15]
            points[15] = tmp
            return tmp
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // 配列pointsに、位置座標を代入
            points[0] = CGPoint(x: 38.0, y: 38.0 + 36.0)
            points[1] = CGPoint(x: 114.0, y: 38.0 + 36.0)
            points[2] = CGPoint(x: 190.0, y: 38.0 + 36.0)
            points[3] = CGPoint(x: 266.0, y: 38.0 + 36.0)
            points[4] = CGPoint(x: 38.0, y: 114.0 + 36.0)
            points[5] = CGPoint(x: 114.0, y: 114.0 + 36.0)
            points[6] = CGPoint(x: 190.0, y: 114.0 + 36.0)
            points[7] = CGPoint(x: 266.0, y: 114.0 + 36.0)
            points[8] = CGPoint(x: 38.0, y: 190.0 + 36.0)
            points[9] = CGPoint(x: 114.0, y: 190.0 + 36.0)
            points[10] = CGPoint(x: 190.0, y: 190.0 + 36.0)
            points[11] = CGPoint(x: 266.0, y: 190.0 + 36.0)
            points[12] = CGPoint(x: 38.0, y: 266.0 + 36.0)
            points[13] = CGPoint(x: 114.0, y: 266.0 + 36.0)
            points[14] = CGPoint(x: 190.0, y: 266.0 + 36.0)
            points[15] = CGPoint(x: 266.0, y: 266.0 + 36.0)
    
            // base16.pngをviewに貼り付け。
            let baseView = UIImageView(image: UIImage(named: "base16.png"))
            baseView.center = CGPoint(x: 152.0, y: 152.0 + 36.0)
            baseView.userInteractionEnabled = false
            self.view.addSubview(baseView)
    
            // heart.pngをviewに貼り付け
            let heartView = UIImageView(image: UIImage(named: "heart.png"))
            // heartViewをランダムな位置にする。
            heartView.center = randomPoint(16)
            heartView.userInteractionEnabled = true
            // heartViewのプロパティtagをheartTag（100）にする
            heartView.tag = heartTag
            self.view.addSubview(heartView)   
        }
    
        // heartViewをタップすると
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            // タッチイベントを受け取ったviewが、heartViewなら
            if let touch = touches.first,
                let theView = touch.view
                where theView.tag == heartTag {
                    // それっぽく見せるために、フリップ（裏返す）アニメーションを付加
                    UIView.transitionWithView(theView, duration: 0.4, options: UIViewAnimationOptions.TransitionFlipFromRight, animations: {
                            theView.hidden = true
                        }, completion: {
                            (finished) in
                            theView.center = self.randomPoint(15)
                            UIView.transitionWithView(theView, duration: 0.4, options: UIViewAnimationOptions.TransitionFlipFromRight, animations: {
                                    theView.hidden = false
                                }, completion: nil)
                    })
            }
        }
    
    }
    
[/code]

上のコードには、頼まれていない処理が付加されています。  
ランダムに`heartView`の位置を変更すると、16分の1の確率で、移動前と同じ位置に移動する、すなわち見た目移動しない結果になります。それはかっこよくないので、かならず現在位置から移動するようにしたいものです。その処理を付加しています。


CC BY-SA 3.0
2015-08-22T08:14:38.997
14724
2015-08-25T09:19:42.690
2015-08-25T09:19:42.690
7362
7362
14715
answer


> 全てコードで配置しております。  
>  再配置のやり方がわかりません

全てコードで配置しているなら、最初に16個の画像を配置する時に、  
UIImageViewのframeプロパティで表示位置を座標指定しているはずです。

再配置するには、そのframeプロパティを変更してUIImageViewの  
表示位置を変更すればよいだけです。

ただ、これはビューを表示する際の基本中の基本の  
当たり前のことしか回答していないので、  
あなたがわからないと思っているポイントは  
別のところにあるのではないかと思います。

補足を求めても、たった2言しか補足できないということは、  
たぶんなにがわからないのか(何をどう聞いたらいいのか)  
自分でうまく説明できない状態なんだろうと思います。

全てコードで配置しているなら、そのコードを全部質問に記載すれば、  
あなたがなにがわからないのか瞬時に理解し、具体的で適切な  
アドバイスを与えてくれる人がここにはいると思います。

* * *

(2015/8/24追記)  
コードを貼ってもらったので、そのコードをベースにアドバイスしたいと思いますが、touchesBeganの中身がほとんど何も書かれてないということは、たぶんどんな手順で処理したらいいのかすらさっぱりわからないのだと思います。その概略手順がわかったら今度は各手順の細かい処理方法に疑問が出てくると思うので、とりあえず現在のコードをベースに、こう追記したら動くというサンプルを書いてみました。

設計方針としては、UIImageViewを再配置するのではなく、各UIImageViewに設定している表示イメージ(UIImage)を更新することにしました。現在のコードをベースにするならこの方が簡単だと思います。

まず、ViewControllerのプロパティに以下の2つを追記します。  
touchesBeganの中でどちらの画像が設定されているか判断できるようにするためです。

[code]

    private var myImageA: UIImage!  // 他と同じ画像
    private var myImageX: UIImage!  // 他と異なる画像
    
[/code]

次に、viewDidLoadの最後に以下を追記します。

[code]

    // イメージ設定
    myImageA = UIImage(named: "images.png")
    myImageX = UIImage(named: "images2.png")
    myImageView.image = myImageX
    myImageView2.image = myImageA
    myImageView3.image = myImageA
    myImageView4.image = myImageA
    myImageView5.image = myImageA
    myImageView6.image = myImageA
    myImageView7.image = myImageA
    myImageView8.image = myImageA
    myImageView9.image = myImageA
    myImageView10.image = myImageA
    myImageView11.image = myImageA
    myImageView12.image = myImageA
    myImageView13.image = myImageA
    myImageView14.image = myImageA
    myImageView15.image = myImageA
    myImageView16.image = myImageA
    // タグ番号設定
    myImageView.tag = 1
    myImageView2.tag = 2
    myImageView3.tag = 3
    myImageView4.tag = 4
    myImageView5.tag = 5
    myImageView6.tag = 6
    myImageView7.tag = 7
    myImageView8.tag = 8
    myImageView9.tag = 9
    myImageView10.tag = 10
    myImageView11.tag = 11
    myImageView12.tag = 12
    myImageView13.tag = 13
    myImageView14.tag = 14
    myImageView15.tag = 15
    myImageView16.tag = 16
    
[/code]

このあたりは、本来はUIImageViewを配列に入れる設計にすべきです。そうすればfor文でもっとすっきりと簡潔にコーディングできます。が、元のコードをいろいろ直すのが面倒なので、この回答ではタグを使いました。配列を使うならタグ番号を使う必要はなく、替わりに配列の添え字番号を使って全体としてもっとすっきりと簡潔になると思います。

そして、touchesBeganを以下のようにします

[code]

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    
        let touch = touches.first as! UITouch
        // タッチしたUIImageViewを取得
        let touchedImageView = touch.view as! UIImageView
        // タッチした画像が他と同じ画像(myImageA)なら何もしない
        if touchedImageView.image == myImageA {
            return
        }
        // タッチしたUIImageViewに他と同じ画像(myImageA)を設定
        touchedImageView.image = myImageA
        // タッチしたUIImageViewの番号を取得
        let touchedTag = touch.view.tag
        // タッチした番号と異なる別の新しい番号(1〜16)を取得
        // (1〜15のランダム値を取得し、タッチした番号と同じかそれ以上なら1加算する)
        var newTag = Int(arc4random_uniform(15))+1
        if newTag >= touchedTag {
            newTag++
        }
        // 新しいタグ番号を持つUIImageViewに他と異なる画像(myImageX)を設定
        let newImageView = self.view.viewWithTag(newTag) as! UIImageView
        newImageView.image = myImageX
    
    }
    
[/code]

これで質問にあった動作はできると思います。  
ソースにコメントを入れておいたので、どんな手順でどんなことをしているか理解してください。


CC BY-SA 3.0
2015-08-22T13:57:14.437
14734
2015-08-25T02:11:37.787
2015-08-25T02:11:37.787
9367
9367
14715
answer