

StoryBoard上に乗せたボタンの位置を、  
アプリ実行端末のディスプレイサイズに応じて変えたいと考えています。

位置を変えるには  
button_Save.frame.origin.y += 100  
のように設定すると良いと考えていたのですが変わりませんでした。  
どのように設定する必要があるでしょうか。  
このボタンはアウトレット接続しており、制約などは特に設定していません。

[code]

    override func viewDidLoad() {
        super.viewDidLoad()
    
        displaySize = self.view.frame.size
        if displaySize.height == 480 { //4/4S
             print("this is iPhone4/4s")
             //Do Nothing. This is base size
        }
        else if displaySize.height == 568{ //5/5S
            //保存ボタンを下にずらす
            print("this is iPhone5/5s")
            button_Save.frame.origin.y += 100
        }
    (以下略)
    }
    
[/code]


CC BY-SA 3.0
2016-06-27T09:20:05.437
27109
2016-06-28T13:12:59.310
2016-06-27T22:28:48.117
16907
16950
question
swift ios
端末のディスプレイサイズに応じてボタンの位置を変えたい(Swift)


自己解決したかもしれません。  
今までoverride func viewDidLoad()で処理を行おうとしていたのですが、これをoverride func
viewDidLayoutSubviews()を作成して、その中で行うとボタンの位置が変更できました。

表示する文字列などはviewDidLoad()で変更できるのですが、レイアウト関連は  
viewDidLayoutSubviews()じゃないと変更できないようですね。

[code]

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    
        displaySize = self.view.frame.size
        if displaySize.height == 480 { //4/4S
             print("this is iPhone4/4s")
             //Do Nothing. This is base size
        }
        else if displaySize.height == 568{ //5/5S
            //保存ボタンを下にずらす
            print("this is iPhone5/5s")
            button_Save.frame.origin.y += 100
        }
    (以下略)
    }
    
[/code]


CC BY-SA 3.0
2016-06-27T10:00:40.097
27110
2016-06-27T10:00:40.097
16950
27109
answer


> アプリ実行端末のディスプレイサイズに応じて変えたいと考えています。

ディスプレイサイズに応じて変えたいということですが、iOS の場合 iOS 8
以降サイズクラスという仕組みが導入されました。それとオートレイアウトを使いスクリーンサイズに応じたインターフェースを簡単に作ることができます。

スクリーンサイズに応じてボタン(UIButton)の配置を変える例を説明します。

ボタンを Object Library からドラッグ＆ドロップし配置します。  
[図1](https://i.stack.imgur.com/PwyKt.png)

先程配置したボタンにコンストレイントを設定します。  
[図2](https://i.stack.imgur.com/cNCJi.png)

サイズクラスを幅を Any、高さを Compact に変更します。  
[図3](https://i.stack.imgur.com/DRe35.png)

このサイズクラスでボタンを配置したい場所へとボタンを移動させ再配置します。  
[図4](https://i.stack.imgur.com/NmGNV.png)

ボタンのコンストレイントを再設定します。まずボタンの上にマウスカーソルを持って行き、そこからコントロールキーを押しながらドラッグすると青い線を引いてこれます。この青い線をドラッグして関連付けるターゲットが
view になるようにしマウスを離します。  
[図5](https://i.stack.imgur.com/rP7NN.png)

メニュが出てくるので trailing space のコンストレイントを選択します。  
[図6](https://i.stack.imgur.com/PP4d0.png)

次にコンフリクトを起こすコンストレイントを削除します。図7で指し示している leading space
のコンストレイントを選択しデリートキーを押して削除します。  
[図7](https://i.stack.imgur.com/z7IvE.png)

以上でスクリーンサイズに応じてボタンの位置が変わるようにする設定は終わりました。  
実行してボタンの位置が変わるか見てみましょう。⌘Rで実行します。

ポートレイトでは中央左端にボタンが配置されています。  
[図8](https://i.stack.imgur.com/GpqCU.png)

ランドスケープに切り替えると中央右端にボタンが配置されます。  
[図9](https://i.stack.imgur.com/PlFBk.png)

このようにサイズクラスとオートレイアウトを使うとスクリーンサイズに合わせたインターフェースを簡単に作ることができます。

またこの例ではあるサイズクラスでコンストレイントの追加と削除を行ったように、サイズクラスでは次の点をサイズクラスごとに変更しそれぞれのスクリーンサイズに合わせてインターフェースを変化させることができます。  
* ビューの大きさと位置の変更  
* ビューの追加と削除  
* コンストレイントの変更と追加と削除  
* ラベル、テキストフィールド、テキストビュー、ボタンのフォントの変更

次の文献に詳しく解説されているので参考にしてください。  
[Adaptive User Interfaces](https://developer.apple.com/design/adaptivity/)  
[Building Adaptive Apps with UIKit - WWDC
2014](https://developer.apple.com/videos/play/wwdc2014/216/)  
[Size Classes Design
Help](https://developer.apple.com/library/ios/recipes/xcode_help-
IB_adaptive_sizes/chapters/AboutAdaptiveSizeDesign.html)


CC BY-SA 3.0
2016-06-27T22:03:50.953
27118
2016-06-27T22:03:50.953
16907
27109
answer


Yuu Qさん、大変丁寧な回答をありがとうございます。  
サイズクラスに応じてコンストレイントを設定出来ることは分かりました。  
しかし、同一サイズクラス内で端末毎となると、コンストレイントを色々と駆使する必要がありそうで、かなりコツが必要そうだと改めて感じております。（※理由は後述します）

一旦、現状を整理してお話させて頂くと以下の通りとなります。

今回私はiPhone4/4S/5/5S/6/6S/6Plus向けのアプリで縦向きのアプリを作ろうとしています。サイズクラスで言うところのW:C,H:Rです。  
このサイズクラスで各端末ごとに表示を整えたく、viewDidLayoutSubviews()内のコーディングでレイアウトを整えることにより、一応見た目だけは理想に近づきつつあります。（画像の②。コーディング前は一番右の画像の状態。）  
ただ、問題も幾つか出てきています。  
１：コードが冗長になった  
２：UISegmen‌​tedControlで、タップするとコントローラが②の画像の位置から、一番右の画像の位置へ移動する現象が起きたので対応が必要

そのため、やはり出来るだけStoryBoardから設定するように出来ないかと考えています。  
調べてみたところ、  
・UI Viewを複数乗せて画面サイズに応じて比率を制約で指定する（参考リンク１）  
・隙間の制約のアウトレットを追加して端末ごとに比率を制約で指定する（参考リンク２）  
・ダミーのUIViewをコントローラの間に差し込んであげて、端末ごとに隙間の比率を制約で指定する  
といった方法を知りました。  
（※みんな苦労しているなぁと感じています。ここが前述の「コツが必要そう」と感じた部分です。）

結論として  
・サイズクラスごとでは、コンストレイントの指定がStoryBoard上から比較的手軽に指定出来る  
・同一サイズクラスにおいては、理想に近づけるためには『コンストレイントを駆使して頑張る』  
という考えに至っております。

私自身、まだサイズクラスやオートレイアウト、コンストレイントを熟知していないため、もし  
「同じサイズクラスでももっと簡単に調整できるぞ」という方法がございましたら是非ご教授願います。

////以下、参考リンク及びイメージ画像////

※アクセスは頭にhを付ける  
[リンク１：AutoLayoutでViewのサイズやUIレイアウトをパーセント指定する方法]  
ttp://qiita.com/emadurandal/items/04c11db5eb1117eabe1e  
[リンク２：【Swift】Auto Layoutで特定のデバイス・画面サイズの時だけ制約を変更する方法]  
ttp://egg-is-world.com/2014/12/25/auto-layout-device/

[![UIのイメージ図](https://i.stack.imgur.com/FKRk1.png)](https://i.stack.imgur.com/FKRk1.png)


CC BY-SA 3.0
2016-06-28T05:24:36.803
27130
2016-06-28T05:43:33.377
2020-06-17T08:14:45.997
-1
16950
27109
answer


AutoLayoutについてまだ[こちら](https://developer.apple.com/jp/documentation/UserExperience/Conceptual/AutoLayoutGuide/GettingStarted/GettingStarted.html)をご覧になっていないのであれば、是非ご一読ください。

私としてはグループ化とスタックビューの使用をお勧めしておきます。

(1) 横に並んだ一まとまりのUI部品をグループ化する

グループにまとめたい要素を全て選択した状態で、XcodeのメニューからEditor>Embed
In>Viewを選ぶと、選択された要素全てを含む新しいUIViewがView階層に追加されます。あなたの回答にあるような画面ですと、5〜6グループにまとめるのが適当でしょうか。

(2) 上記のグループをさらにスタックビューで囲む

上の(1)で作った5〜6個のグループの代表であるUIViewを全部選択して、Editor>Embed In>Stack
Viewで、それらのグループを子要素に持つUIStackViewを作成します。

(3) スタックビューの属性を設定する

細かいところの微調整は後にして、AxisをVertical, DistributionをEqual
Spacingに設定してください。これにより、各グループの隙間が同じ幅になるようにレイアウトされます。

(4) グループ内で適切な制約を設定する

画面全体にあれこれ制約を張り巡らせるのは結構大変ですが、ある程度絞り込んだグループの中での制約であれば、比較的簡単に設定できるはずです。

言葉だけですと少しわかりにくいですが、ご自身で少し簡略化したサンプルを作って試しながら再度読み直していただけるとわかりやすくなると思います。  
スタックビューはiOS9以降の機能なので、それ以前のバージョンもサポートする必要がある場合には使えませんが、画面全体に多数のUI要素がある場合にグループ化して管理すると言うのは、スタックビューが使えない場合でも有効な手段です。是非お試しください。


CC BY-SA 3.0
2016-06-28T13:12:59.310
27145
2016-06-28T13:12:59.310
13972
27109
answer