私はそれに配置されたサブビュー(7セル)を追加した水平スタックビューを持っています。スタック内の各セルには、ビューの境界を超える円形のバッジがあります(負の制約)。実行すると、以下に示すように、各セルは前のセルのバッジの上にあります。バッジが完全に表示されるように順序を変更したい。
Zインデックスで遊んでみましたが、次のビュー階層でわかるように、レイヤーがどういうわけかフラットではないため、役に立ちませんでした:
それを行う方法やアイデアはありますか?
ありがとう。
IStackViewクラスのドキュメント は次のことを伝えます。
サブビュー配列の順序は、サブビューのZオーダーを定義します。ビューが重複している場合、インデックスが低いサブビューは、インデックスが高いサブビューの後ろに表示されます。
これはまさに私が質問で経験したことです。私の特定のケースを克服するために、私はビューのセマンティクスをRTLに変更するトリックをしました。
デバイスのグローバル設定でRTL言語が設定されている可能性があるため、これは一般的なケースをカバーしていません。一般的なケースでは、インターフェースのセマンティクスを確認し、スタックビューに対して反対方向を強制する必要があると思います。
P.S。これは一種のハックなので、サブビューのZオーダーを別の方法で並べ替える方法についてのアイデアは大歓迎です!
このSwiftソリューションは、UIViewメソッドsendSubviewToBack(_:)
( docs here )を使用してスタックビューのサブビューの順序を逆にします:
@IBOutlet weak var stackView: UIStackView!
for view in stackView.arrangedSubviews {
stackView.sendSubviewToBack(view)
}
スタックビューの配置されたビューを(下から上に)進めると、後の(つまり高い)ビューが下にプッシュされ、それによって順序が逆になります:-)
IOS 9.0以降、スタックビューのサブビューのZオーダーと配置を個別に設定できるようになりました。新しいarrangedSubviews
プロパティを使用して、スタックビューの軸に沿ったサブビューの配置を指定します。 subviews
プロパティを使用して、配列のインデックスに基づいてサブビューのZオーダーを指定します。
スタックビューは、そのarrangedSubviews
プロパティが常にsubviews
プロパティのサブセットであることを保証します。
以下は、UIStackView
のサブビューのz-indexを逆にし、オプションでレイアウトを必要とするUIStackView
の単純な拡張です。
extension UIStackView {
func reverseSubviewsZIndex(setNeedsLayout: Bool = true) {
let stackedViews = self.arrangedSubviews
stackedViews.forEach {
self.removeArrangedSubview($0)
$0.removeFromSuperview()
}
stackedViews.reversed().forEach(addSubview(_:))
stackedViews.forEach(addArrangedSubview(_:))
if setNeedsLayout {
stackedViews.forEach { $0.setNeedsLayout() }
}
}
}
他のアイデアは、サブビュー(7セル)の背景色をデフォルト(完全に透明)に設定することです。 スタックビュー自体を白の背景のみを設定します。
私にも同様の問題がありますが、すべてのサブビューに特定の背景が必要です。そして私の場合、あなたのハックが役立つかもしれません... ????それをありがとう!
プログラムでサブビューを追加するときに、高さと幅の定数制約を追加します。最後に、StackViewのsetNeedsLayoutを呼び出します。間隔を空けてビューを計算して調整しようとします
いろいろ試して、横に作れる
stackView.leadingAnchor.constraint(equalTo: stackScrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: stackScrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: stackScrollView.bottomAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: stackScrollView.heightAnchor).isActive = true
stackView.distribution = .equalSpacing
stackView.spacing = 5
stackView.axis = .horizontal
stackView.alignment = .fill
for i in 0 ..< images.count {
let photoView = UIButton.init(frame: CGRect(x: 0, y: 0, width: 85, height: 85))
// set button image
photoView.translatesAutoresizingMaskIntoConstraints = false
photoView.heightAnchor.constraint(equalToConstant: photoView.frame.height).isActive = true
photoView.widthAnchor.constraint(equalToConstant: photoView.frame.width).isActive = true
stackView.addArrangedSubview(photoView)
}
stackView.setNeedsLayout()