0

ここ数週間、プログラムによる動的 UI 要素に苦労した後、UIstackView を試してみることにしました。カスタム UIView クラスが、削除するユーザー入力に基づいて異なる高さでスタックビューを占有し、その場でビューを追加するようにします。

stackView の「セル」の高さは、UI 要素の固有のコンテンツ サイズに基づいていることがわかりました。ただし、UIViews にはありません。広く検索したところ、ビューの intrisicContentsize 関数を、幅と高さを明示的に設定できる関数でオーバーライドする必要があることがわかりました。ただし、結果は非常に予測不可能であり、この奇妙な動作の原因となることがわかっていない小さなことがあると確信しています。私は言語に不慣れで、落とし穴がたくさんあるので、ここにコードを貼り付けて、私が間違っていることを見つけていただければ幸いです。

私はdocs ofc、多くの記事を読みましたが、それらはすべて、私からは機能していないように見えるオーバーライド機能を指しています。

これは私の mainViewController クラスです。

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

var bv = BackButtonView(frame: CGRect.zero, image: UIImage(named: "backArrow.png")!)

var redView : UIView  = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .red
    return view
}();

var blueView : UIView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .blue
    return view
}();

let stack : UIStackView = {
    let stack = UIStackView();
    stack.translatesAutoresizingMaskIntoConstraints = false;
    stack.axis = .vertical
    stack.distribution = .fillProportionally;
    stack.spacing = 8
    return stack;
}();

override func viewDidLoad() {
    let view = UIView(frame: UIScreen.main.bounds)
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .white
    self.view = view
    self.view.addSubview(stack)
    createLayout()
    bv.intrinsicContentSize
    stack.addArrangedSubview(bv)
    print(bv.frame)
    print(bv.intrinsicContentSize)
    stack.layoutIfNeeded()
    stack.addArrangedSubview(redView)
    stack.addArrangedSubview(blueView)

}

private func setConstraints(view: UIView) -> [NSLayoutConstraint] {
    return [
        view.heightAnchor.constraint(equalToConstant: 50),
    ]
}

private func createLayout() {
    stack.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    stack.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    stack.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    stack.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true

}
}

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = MyViewController()

ここに、このすべての問題を引き起こしているカスタム UIClass があります。

import UIKit

public class BackButtonView : UIView {


public var size = CGSize(width: 10, height: UIView.noIntrinsicMetric)
override open var intrinsicContentSize: CGSize {
     return size
}

var button : UIButton;

public init(frame: CGRect, image: UIImage) {
    button = UIButton()
    super.init(frame : frame);
    self.translatesAutoresizingMaskIntoConstraints = false;
    self.backgroundColor = .black
    self.addSubview(button)
    setupButton(image: image);
    print(button.intrinsicContentSize)
}
let backButtonTrailingPadding : CGFloat = -18

lazy var buttonConstraints = [
    button.heightAnchor.constraint(equalToConstant: 50),
    button.widthAnchor.constraint(equalToConstant: 50),
    button.centerYAnchor.constraint(equalTo: self.centerYAnchor),
    button.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: backButtonTrailingPadding),
]
private func setupButton(image: UIImage) {
    self.button.translatesAutoresizingMaskIntoConstraints = false;
    self.button.setImage(image, for: .normal);
    self.button.contentMode = .scaleToFill
    NSLayoutConstraint.activate(buttonConstraints)

}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

struct anchors {
    var topAnchor = NSLayoutConstraint()
    var bottomAnchor = NSLayoutConstraint()
    var leadingAnchor = NSLayoutConstraint()
    var trailingAnchor = NSLayoutConstraint()
}

}

size プロパティで指定された幅が無視されることがわかります。上記の条件の下で、これは出力です

Al の高さはここで等しい カスタム UIClass の intrisiContentSize の高さを他のものに変更すると、次のようになります。

    public var size = CGSize(width: UIView.noIntrinsicMetric, height: 10)
override open var intrinsicContentSize: CGSize {
     return size
}

結果: ここに画像の説明を入力

何が起こっていて何が起こっていないのかを理解するのを手伝ってください

最終的な画面は次のようになります。

ここに画像の説明を入力

4

0 に答える 0