web-dev-qa-db-ja.com

UIStackViewでのビューの重複

私はそれに配置されたサブビュー(7セル)を追加した水平スタックビューを持っています。スタック内の各セルには、ビューの境界を超える円形のバッジがあります(負の制約)。実行すると、以下に示すように、各セルは前のセルのバッジの上にあります。バッジが完全に表示されるように順序を変更したい

enter image description here

Zインデックスで遊んでみましたが、次のビュー階層でわかるように、レイヤーがどういうわけかフラットではないため、役に立ちませんでした:

enter image description here

それを行う方法やアイデアはありますか?

ありがとう。

18
yossile

IStackViewクラスのドキュメント は次のことを伝えます。

サブビュー配列の順序は、サブビューのZオーダーを定義します。ビューが重複している場合、インデックスが低いサブビューは、インデックスが高いサブビューの後ろに表示されます。

これはまさに私が質問で経験したことです。私の特定のケースを克服するために、私はビューのセマンティクスをRTLに変更するトリックをしました。

enter image description here

デバイスのグローバル設定でRTL言語が設定されている可能性があるため、これは一般的なケースをカバーしていません。一般的なケースでは、インターフェースのセマンティクスを確認し、スタックビューに対して反対方向を強制する必要があると思います。

P.S。これは一種のハックなので、サブビューのZオーダーを別の方法で並べ替える方法についてのアイデアは大歓迎です!

12
yossile

このSwiftソリューションは、UIViewメソッドsendSubviewToBack(_:)docs here )を使用してスタックビューのサブビューの順序を逆にします:

@IBOutlet weak var stackView: UIStackView!

for view in stackView.arrangedSubviews {
    stackView.sendSubviewToBack(view)
}

スタックビューの配置されたビューを(下から上に)進めると、後の(つまり高い)ビューが下にプッシュされ、それによって順序が逆になります:-)

13
future-adam

IOS 9.0以降、スタックビューのサブビューのZオーダーと配置を個別に設定できるようになりました。新しいarrangedSubviewsプロパティを使用して、スタックビューの軸に沿ったサブビューの配置を指定します。 subviewsプロパティを使用して、配列のインデックスに基づいてサブビューのZオーダーを指定します。

スタックビューは、そのarrangedSubviewsプロパティが常にsubviewsプロパティのサブセットであることを保証します。

arrangedSubviewsのドキュメント

3
IvanRublev

以下は、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() }
    }
  }

}
1
sean woodward

他のアイデアは、サブビュー(7セル)の背景色をデフォルト(完全に透明)に設定することです。 スタックビュー自体を白の背景のみを設定します。

私にも同様の問題がありますが、すべてのサブビューに特定の背景が必要です。そして私の場合、あなたのハックが役立つかもしれません... ????それをありがとう!

1
MonsieurDart

プログラムでサブビューを追加するときに、高さと幅の定数制約を追加します。最後に、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()
0
user1039695