Constraint 付きのView にコードでView を重ねる


StoryBoard でView や ImageViewなどパーツ をxAny-yAny で配置するときは、基本的に各機種で表示に齟齬が無いようにConstraint を設定します。その画面にコードで画像やUIパーツを配置しようとするときには、設定されたConstraint にマッチしたサイズと位置にするひつようがあります。
例えば、StoryBoard でバックグラウンドのImage をレイアウトしておいて、その1ピクセル内側にコードで画像を表示するというようなときです。
このときの方法としては、

  1. 表示する画像にConstraint をコードで設定する
  2. 元の画像のサイズと位置を読んで、表示する画像の位置とサイズを決める

があります。
1. は例えばバックグラウンドに対して4方向1ピクセルのスペースというConstraint をつけるのですが、この場合元のバックグラウンド画像のアスペクト比がどうなっているかわからないので、表示画像をバックグラウンド内で正方形でできるだけ大きくというような設定はできません。またこのようにするのであれば、表示用のImageView をStoryboard で設定しておいてコードでイメージだけを後で設定することでよいでしょう。
2. はサイズと位置を自分で把握できるので上記のようなバックグラウンド内で正方形とか、という設定もできます。この場合、いつ元の画像の情報を取得するかも重要であり、一般によくやる viewDidLoad のタイミングではまだ元の画像のConstraint が反映されておらず、viewDidLayoutSubview あるいは viewDidAppear のタイミングでなければ正しい情報が得られません。
また、この方法ではバックグラウンド画像との関係がないので、ローテートを許容するアプリではローテートの際に一度外して設定し直すという処理が必要です。

```import UIKit
import iAd

class PhotoPickerViewController: UIViewController,
UINavigationControllerDelegate, UIImagePickerControllerDelegate,
ADBannerViewDelegate {

// 画面要素プロパティ

@IBOutlet weak var _Advertise: ADBannerView!    // 広告エリア
@IBOutlet weak var _picturebg: UIImageView!     // 画像表示バックグランド
@IBOutlet weak var _cropFrame: UISlider!        // 切り取りフレームサイズ

// 画面用変数
var _photoView = UIImageView()                    // 画像表示エリア

// 変数

var _photoImage: UIImage?       // 選択写真イメージ

var photoFrame: CGRect?         // 写真フレーム

var puzzlePhoto: UIImage?       // パズル用写真データ


var _pickButton: UIButton?      // ピッカーボタン
var _okButton: UIButton?        // 確定ボタン
var _scaleSlider: UISlider?     // スライダー

// ===================
// UI
// ===================
// ロード完了時に呼ばれる      **** iPad は表示位置とサイズを変える
override func viewDidLoad() {
    super.viewDidLoad()

    // 設定値ロード
    loadDefault()


}

override func viewDidAppear(animated: Bool) {
    // 表示エリアサイズ設定
    if _photoView.image != nil {
        _photoView.removeFromSuperview()
    }
    let _screen = UIScreen.mainScreen().bounds
    let photoX = _picturebg.frame.origin.x + 1
    let photoY = _picturebg.frame.origin.y + 1
    let photoWidth = _picturebg.frame.width - 2
    let photoHeight = _picturebg.frame.height - 2

    // 画像設定
    if let photo = puzzlePhoto {
        _photoImage = photo
    } else {
        _photoImage = UIImage(named: "DefaultPhoto.png")
    }
    _photoView = makeImageView(CGRectMake(photoX, photoY, photoWidth, photoHeight), image: _photoImage!)
    _photoView.contentMode = UIViewContentMode.ScaleAspectFit
    self.view.addSubview(_photoView)


}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// イメージビューの生成
func makeImageView(frame: CGRect, image: UIImage) -> UIImageView {
    var imageView = UIImageView()
    imageView.frame = frame
    imageView.image = image
    return imageView
}

}
```