複数のイメージをランダムな位置に表示する(MyPlayground2)

続いて、適当なサイズのコンテナとして使用するUIViewを用意し、その中に10個のUIImageViewをランダムな位置に配置してみましょう。

 

次にリストを示します。

<リスト> MyPlayground2.playground

import UIKit
import PlaygroundSupport

let viewHeight = 500
let viewWidth = 400
// コンテントビューを生成
let contentView = UIView(frame: CGRect(x:0, y:0, width: viewWidth, height: viewHeight))   //<=①

// 背景色を黄色に
contentView.backgroundColor = UIColor.yellow //<=②

// イメージビューを生成
var myImg = UIImage(named: "myFish")
var imgView:UIImageView

// 10個のイメージビューをコンテントビューにランダムに配置
for _ in 1...10 {  //<=③
      let x = arc4random_uniform(UInt32(viewWidth))
      let y = arc4random_uniform(UInt32(viewHeight))
      imgView = UIImageView(image: myImg)
      imgView.center = CGPoint(x: Int(x), y: Int(y))
      contentView.addSubview(imgView) 
}

// コンテントビューをPlaygroundのliveViewにセット
PlaygroundPage.current.liveView = contentView

①でコンテンツビューとして使用する400×500ピクセルのUIViewを生成しています。②でその背景色を黄色(yellow)に設定しています(Swift 3ではUIColorの色の設定/取得はメソッドではなくプロパティとなりました)。③のforループで10個のUIImageViewを生成し、コンテンツビュー内のランダムな位置に配置しています。

クラスを別のソースファイルにする(MyPlayground3)

Playgroundでは、メインのPlaygroundファイルとは別に、SourcesフォルダにSwiftファイルを用意することで、それを読み込んで使用することもできます。この場合もコンパイルを手動で行う必要はありません。Playgroundファイルの拡張子は「.playground」ですが、Swiftファイルの拡張子は通常通り「.swift」となります。ここでは、カスタムビューとしてMyViewクラスを別ファイル「MyView.swift」に保存してみましょう。MyViewクラスではイニシャライザの第一引数としてUIImageオブジェクトを受け取り、ビュー内のランダムな位置にUIImageViewとして配置しています。

1. 「Project Navigator」の「Sources」を右クリックし、表示されるメニューから「New File」を選択します。

2. 「Sources」フォルダに「New File.swift」というからのファイルが作成されるので、名前を変更します。
次の例では「MyView.swift」に変更しています。

次に、MyView.swiftのリストを示します。

<リスト> MyView.swift

import UIKit
open class MyView: UIView{
      var imgView: UIImageView      
      public init(img: UIImage?, frame: CGRect, color: UIColor) {    //<=①
            imgView = UIImageView(image: img)            
            super.init(frame: frame)
            backgroundColor = color
            
            let x = arc4random_uniform(UInt32(frame.width))
            let y = arc4random_uniform(UInt32(frame.height))
            imgView = UIImageView(image: img)
            imgView.center = CGPoint(x: Int(x), y: Int(y))
            self.addSubview(imgView)    
      }      
      required public init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
      }      
      override open func draw(_ rect: CGRect) {    //<=②
            // 円を描く
            UIColor.blue.setStroke()
            let circle = UIBezierPath(ovalIn: CGRect(x: 10, y: 10, width: Int(self.frame.width) - 20 , height: Int(self.frame.height) - 20))            
            circle.lineWidth = 4
            circle.stroke()
      }
}

 

①のイニシャライザでは引数として渡されたUIImageオブジェクトからUIImageViewを生成しランダムな位置に配置しています。アクセス修飾子に「public」を指定している点に注意してください。
②ではUIViewのdraw(_:)メソッドをオーバライドして円を描いています。

次に、Playgroundファイルのリストを示します。

<リスト>MyPlayground3.playground

//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport

// イメージを生成
var myImg = UIImage(named: "myFish")

// MyViewクラスからコンテントビューを生成
let contentView = MyView(img: myImg, frame: CGRect(x:0, y:0, width:400, height:500), color: UIColor.yellow)

PlaygroundPage.current.liveView = contentView

次に実行結果を示します。アシスタントエディタを2つ表示し、一つはSwiftファイルのエディタ、もう一つは実行結果の表示に使用すると作業がやりやすくなります。

タッチイベントを受け取る(MyPlayground4)

PlaygroundSupportモジュールを使用すると、liveViewでタッチイベントなどのイベントを受け取ることもできます。次に、MyPlayground3を変更しタッチした位置にイメージを移動する例を示します(MyPlayground4)。

 

変更点はMyView.swiftのMyViewクラスに、touchesEnded(_:with:)メソッドをオーバライドして追加し、タッチ位置にimgViewを移動している点です(Swift 2.0ではtouchesBeganメソッドの最初の引数が、NSObjectではなく、UITouchのSetとなりました)

<リスト>MyView.swift(追加部分)

override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            if let touch = touches.first {
                  let pos = touch.location(in: self)
            
                  imgView.center = pos
            }
      }

 

ソースファイル

ソースはGitHubで公開しています。

https://github.com/makotoo2/MyPlayground-1