2016-05-27 15 views
1

ラベルのサイズを画面のサイズに比例させるようにします。アプリが最初に起動したときに(それらに接続制約をスーパーに比例した幅を持っている)ラベルが正しくサイズを変更layoutSubviewsがバックグラウンド状態になると繰り返し呼び出される

@IBDesignable class MyCustomLabel: UILabel { 
    override func layoutSubviews() { 
     super.layoutSubviews() 
     self.font = UIFont(name: "myFontName", size: (self.font?.pointSize)!) 
     self.adjustsFontSizeToFitWidth = true 
    } 
} 

、それがバックグラウンド状態layoutSubviewsに入ったときに取得します。私はこれを達成するためにUILabelクラスをサブクラス化してきました繰り返し呼び出される。アプリはユーザーの入力に応答しなくなり、フォントにフォントサイズを割り当て続けます。

Download test project.どうしてですか?

+1

この質問をしてくれてありがとう! – Fattie

答えて

3

あなたのテストプロジェクトで、私がiPhone上で動くと、layoutSubviews()がバックグラウンドで呼び出されていません。それはiPadでのみ発生します。あなたのアプリがマルチタスクをサポートしているためだ

  • アプリが非アクティブ化されるとは、iOSのアプリスイッチャーのためにそれのスナップショットを取るために、異なるサイズにそれをリサイズします。これらのサイズ変更により、ビューのlayoutSubviews()が呼び出されます。それは完全に正常です。
  • その後、iOSはアプリを元のサイズに戻します。

実際の問題は、「レイアウトループ」を作成していることです。 layoutSubviews()のコードにより、独自のビューのレイアウトが無効になるため、システムはレイアウトプロセスを再度実行する必要があります。レイアウトが実行されたら、もう一度やり直してください。

具体的には、原因は次のとおりです。

self.font = UIFont(name: fontName, size: fontSize) 

はあなたのラベルのフォントを変更するレイアウト処理を再度実行する必要があるように、そのsuperviewsは、更新される彼らのレイアウトを必要とするかもしれないことを意味し、そのintrinsicSizeを変化させます。 layoutSubviews()でこれを行うのは悪い考えです。レイアウトループが発生するからです。実際には、ビュー自体ではなく、サブビューのプロパティのみを変更する必要があります。

は、なぜあなたはlayoutSubviews()でこれを行う必要があると思いますか?おそらくレイアウトプロセスの外で、それを置くためのより良い場所があります。あなたの例では、私はこのコードが何か役に立たせるものは何も見ません。

かつてはadjustsFrameSizeToWidthを設定するために、より理にかなって、その後、layoutSubviews()で何もしない:

override init(frame: CGRect) { 
    super.init(frame: frame) 
    self.adjustsFontSizeToFitWidth = true 
} 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    self.adjustsFontSizeToFitWidth = true 
} 

あなたのサイズのクラスに応じてフォントのサイズを変更しようとしている場合は、あなたが行うことができますそれを上書きしてコードでtraitCollectionDidChange()

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) { 
    super.traitCollectionDidChange(previousTraitCollection) 

    var fontSize: CGFloat 
    if (self.traitCollection.horizontalSizeClass == .Regular) { 
     fontSize = 70 
    } 
    else { 
     fontSize = 30 
    } 
    self.font = UIFont(name: fontName, size:fontSize) 
} 
+0

ありがとうKurt!ソリューションでカスタムフォントをプログラムで設定する方法はありますか?あなたが知っているかもしれませんが、カスタムフォントはhttp://stackoverflow.com/questions/26166737/custom-font-sizing-in-xcode6-size-classes-not-working-properly-w-(サイズクラスとうまく動作しません参照のためのカスタムフォント)。 – Cesare

+0

カスタムフォントがInterface Builder_のサイズクラスサポートでうまく動作しないことを意味します。サイズクラスは常に存在します。あなたは 'self.traitCollection.horizo​​ntalSizeClass'または' self.traitCollectionを使っていつでもそれらを得ることができます。verticalSizeClass'を使用し、 'traitCollectionDidChange()'をオーバーライドして使用することができます。とにかく、IBのサポートはそれだけです。私は例を追加します。 –

+0

すばらしい答え、Kurtに感謝します!本当の問題です。あなたはそれを解決しました。 – Fattie

関連する問題