2017-07-18 6 views
0

私の目標は、スタックビューを任意の(〜5-10)配置されたサブビューを格納し、その高さがそのビューに含まれるビューよりも高くなる私はスクロールビューを使用しています。スクロールスタックビューを含むときの高さ/サイズの表示は常に曖昧です

distributionfillに設定されたスタックビューは、配置された各サブビューに明示的な高さ制約がある場合は、固有のコンテンツサイズを持つ必要があります。だから私はスクロールビューにスタックビューを追加することができ、スクロールスタックビューの本質的なコンテンツサイズからそのコンテンツサイズを得ることができます。

私はまた、このスクロールスタックビューを(キーボードからの)フレームの変化に強くしようとしています。

私はScroll ViewとStackViewとすべてのプログラミングガイドで多くの時間を費やし、長い記事を読んだことがありますが、完全に動作するようにはできません。

以下のコードとわずかに異なるバリエーションは、常にcontent size is ambiguousまたはHeight is ambiguous for Scroll Viewです。キーボードがポップアップすると(Stack Viewのtextviewをタップすると)、Scroll Viewのボトム拘束の定数から400を引いただけです。私の考えは、スクロールビューのフレーム/境界がスタックビューの本質的なコンテンツの高さより小さくなり、スクロールが発生するということです。ただし、画面は空白になります。コンソールに制約ログもありません。

私はこのシナリオのすべての考慮事項を考えて非常に長い時間を費やしましたが、それはちょうど私を超えているようです。私は、スクロールビューのStack Viewの主題についての助けや指導に感謝します。ここで

はそれで私の現在の実験である:

class ViewController: UIViewController { 

    let scrollView = UIScrollView() 
    var scrollViewBottomConstraint: NSLayoutConstraint! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // stack view setup (one blue and hellow view at 100 height) 
     let stackView = UIStackView() 
     stackView.distribution = .fill 
     stackView.axis = .vertical 
     let v1 = UIView() 
     v1.backgroundColor = .blue 
     let v2 = UITextView() 
     v2.backgroundColor = .yellow 
     stackView.addArrangedSubview(v1) 
     stackView.addArrangedSubview(v2) 


     // scroll 
     scrollView.addSubview(stackView) 

     view.addSubview(scrollView) 

     // constraints for stack view arranged views 
     v1.heightAnchor.constraint(equalToConstant: 100).isActive = true 
     v2.heightAnchor.constraint(equalToConstant: 100).isActive = true 

     // pin scroll view in main view 
     scrollView.translatesAutoresizingMaskIntoConstraints = false 
     scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true 
     scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true 
     scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true 
     // pin scroll view to stack view's bottom anchor 
     scrollViewBottomConstraint = scrollView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 0) 
     scrollViewBottomConstraint.isActive = true 


     stackView.translatesAutoresizingMaskIntoConstraints = false 
     stackView.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true 
     stackView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true 
     stackView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true 


     // constrain "content view to main view and not scroll view." 
     stackView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1).isActive = true 


     NotificationCenter.default.addObserver(self, 
               selector: #selector(ViewController.handleKeyboard), 
               name: Notification.Name.UIKeyboardWillShow, 
               object: nil) 
     NotificationCenter.default.addObserver(self, 
               selector: #selector(ViewController.handleKeyboard), 
               name: Notification.Name.UIKeyboardWillHide, 
               object: nil) 


    } 

    func handleKeyboard(notification: Notification) { 

     scrollViewBottomConstraint.constant = -400 
    } 
} 
+0

をビューの下部。例えば。 'scrollView.bottomAnchor.constraint(equalTo:view.bottomAnchor、定数:0).isActive = true'です。私はバグの自己完結型、簡単に再現可能な例を入れてくれてありがとうと思います。これにより、問題ははるかに親しみやすくなります。 – paulvs

+0

キーボードが表示されているとき、通常のパターンは、スクロール・ビューの 'contentInset'プロパティを設定してキーボードのためのスペースを確保することです。 – paulvs

+0

しかし、私がその制約を追加すると(39行目 - https://gist.github.com/alexbollbach/38b96dec87f6a04df0eab63c299b56ad)、ビジュアルデバッガで ''スクロール可能なコンテンツサイズがUIScrollViewのためにあいまいです。また、これを実行し、黄色のテキストビューをタップすると、それは私の主な問題を再現します。つまり、スクロールビューの下限制約が、スクロールビューの境界がスタックビューの内容よりも短いところまでアニメーション化されている場合、スクロールは機能しません。 –

答えて

0

私はここに私の作業例追加している:あなたがにスクロールビューの下部を固定する制約を逃している

class ViewController: UIViewController { 

    let scrollView = UIScrollView() 
    var scrollViewBottomConstraint: NSLayoutConstraint! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // stack view setup (one blue and hellow view at 100 height) 
     let stackView = UIStackView() 
     stackView.distribution = .fill 
     stackView.axis = .vertical 
     let v1 = UIView() 
     v1.backgroundColor = .blue 
     let v2 = UITextView() 
     v2.backgroundColor = .yellow 
     let v3 = UITextView() 
     v3.backgroundColor = .green 
     let v4 = UITextView() 
     v4.backgroundColor = .brown 
     stackView.addArrangedSubview(v1) 
     stackView.addArrangedSubview(v2) 
     stackView.addArrangedSubview(v3) 
     stackView.addArrangedSubview(v4) 


     // scroll 
     scrollView.addSubview(stackView) 

     view.addSubview(scrollView) 

     // constraints for stack view arranged views 
     v1.heightAnchor.constraint(equalToConstant: 200).isActive = true 
     v2.heightAnchor.constraint(equalToConstant: 200).isActive = true 
     v3.heightAnchor.constraint(equalToConstant: 180).isActive = true 
     v4.heightAnchor.constraint(equalToConstant: 250).isActive = true 

     // pin scroll view in main view 
     scrollView.translatesAutoresizingMaskIntoConstraints = false 
     scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true 
     scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true 
     scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true 
     scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 100).isActive = true 
     // pin scroll view to stack view's bottom anchor 
     scrollViewBottomConstraint = scrollView.bottomAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 0) 
     scrollViewBottomConstraint.isActive = true 


     stackView.translatesAutoresizingMaskIntoConstraints = false 
     stackView.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true 
     stackView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true 
     stackView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true 


     // constrain "content view to main view and not scroll view." 
     stackView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1).isActive = true 


     NotificationCenter.default.addObserver(self, 
               selector: #selector(ViewController.handleKeyboard), 
               name: Notification.Name.UIKeyboardWillShow, 
               object: nil) 
     NotificationCenter.default.addObserver(self, 
               selector: #selector(ViewController.handleKeyboard), 
               name: Notification.Name.UIKeyboardWillHide, 
               object: nil) 


    } 

    func handleKeyboard(notification: Notification) { 

     scrollViewBottomConstraint.constant = -400 
    } 
}