AutoLayoutの制約を動的に変更した話
追記 2016/03/26
iOS9.2で意図した通りに動作しなくなったので、
この話の続きを書きました。
— ここまで追記 —
解像度(主に高さ)が異なると、
ToyTone for iOS(App Store)みたいなアプリの場合は、
だいぶ面倒なことになる。
正攻法としては、
いきなりコントロールを配置しないで、
まずは、コンテナとしてテーブルビューのごとくUIView
を配置して、
コンテナの高さの制約は、SuperViewの高さに係数を掛けたものを設定し、
そのコンテナにコントロールを配置するのが一般的と思われる。
今思うと、そうすれば良かったと思うけど、
早く形にしたかったのでコードでなんとかした。
まず、左側のラベルについて、SuperViewの上辺から距離を設定して、
ラベルの右側にあるコントロールの配置は、左側のラベルを基準にするようにした。
次にコードはこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | import UIKit class MainContainerView : UIView { var containerHeightAtDesigned : CGFloat = 0.0 var containerHeightAtUpdated : CGFloat = 0.0 var constantsAtDesigned : [ UIView : CGFloat ] = [:] required init ( coder aDecoder : NSCoder ) { super . init ( coder : aDecoder ) containerHeightAtDesigned = self . frame . height // memo: デザイン時の高さ //println( "MainContainerView.init, frame: \(self.frame)" ) for c in self . constraints () { if let label = c . firstItem as ? UILabel { if c . firstAttribute == . Top { constantsAtDesigned [ label ] = c . constant } } } } override func updateConstraints () { //println( "updateConstraints: \(self.frame)" ) containerHeightAtUpdated = self . frame . height let constraints = self . constraints () for var i = 0 ; i < constraints . count ; i ++ { let c = constraints [ i ] as ! NSLayoutConstraint if let label = c . firstItem as ? UILabel { if c . firstAttribute == . Top { var val = constantsAtDesigned [ label ]! val = val * ( self . frame . height / containerHeightAtDesigned ) //println( "\(label.text) -> \(c.constant) -> \(val)" ) c . constant = val //println() } } } super . updateConstraints () } override func layoutSubviews () { if containerHeightAtUpdated != self . frame . height { //println( "layoutSubviews: \(self.frame)" ) setNeedsUpdateConstraints () } //println( "layoutSubviews: Here!" ) super . layoutSubviews () } } |
MainContainerView
というのは、
この右側にあるViewControllerにある最上位のUIView
に設定したクラスである。
これにより、デザイン時の制約を元に、実行時に制約が変更される。
参考にしたページ
UIViewControllerのライフサイクル
http://qiita.com/mo_to_44/items/0ca628b4cc74c8c5599d
めでたし、めでたし。
Leave a Comment