Ich habe eine einfache Horizontale UIStackView
mit mehreren darin gestapelten UIViews. Mein Ziel ist es, einen variablen Abstand zwischen Ansichten zu schaffen. Mir ist klar, dass ich mit der Eigenschaft "Abstand" einen konstanten Abstand zwischen den Unteransichten erstellen kann. Mein Ziel ist es jedoch, variablen Raum zu schaffen. Bitte beachten Sie, dass ich nach Möglichkeit vermeiden möchte, unsichtbare Ansichten zu verwenden, die als Abstandshalter dienen.
Das Beste, was ich mir ausgedacht habe, war, meine UIViews
in eine separate Datei zu wickeln UIStackView
und die layoutMarginsRelativeArrangement = YES
Layoutränder meines inneren Stapels zu respektieren. Ich hatte gehofft, mit jedem etwas Ähnliches machen zu können, UIView
ohne auf diese hässliche Umgehung zurückzugreifen. Hier ist mein Beispielcode:
// Create stack view
UIStackView *stackView = [[UIStackView alloc] init];
stackView.translatesAutoresizingMaskIntoConstraints = NO;
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.alignment = UIStackViewAlignmentCenter;
stackView.layoutMarginsRelativeArrangement = YES;
// Create subview
UIView *view1 = [[UIView alloc] init];
view1.translatesAutoresizingMaskIntoConstraints = NO;
// ... Add Auto Layout constraints for height / width
// ...
// I was hoping the layoutMargins would be respected, but they are not
view1.layoutMargins = UIEdgeInsetsMake(0, 25, 0, 0);
// ... Create more subviews
// UIView view2 = [[UIView alloc] init];
// ...
// Stack the subviews
[stackView addArrangedSubview:view1];
[stackView addArrangedSubview:view2];
Das Ergebnis ist ein Stapel mit Ansichten direkt nebeneinander mit Abstand:
SWIFT 4
Nach der Antwort von lilpit finden Sie hier eine Erweiterung von UIStackView, um Ihrer arrangierten Unteransicht einen oberen und einen unteren Abstand hinzuzufügen
Dann würden Sie es so verwenden:
quelle
Aus Robs Antwort habe ich eine UIStackView- Erweiterung erstellt, die helfen könnte:
Sie können es verwenden und ändern, wie Sie möchten. Wenn Sie beispielsweise die Referenz " separatorView " möchten , können Sie einfach die UIView zurückgeben:
quelle
stackView.alignment = .fill
setCustomSpacing
ist es möglich, die Abstandseigenschaft für Indizes zu verwenden, die Sie nicht verwendet habensetCustomSpacing
, also ist meine Antwort richtigsetCustomSpacing
. Außerdem haben Sie die Namen und Dinge des Ortes geändert, um eine andere Antwort zu erhalten.Um iOS 11.x und niedriger zu unterstützen, habe ich das UIStackView wie von Enrique erwähnt erweitert, es jedoch so geändert, dass es Folgendes enthält:
extension UIStackView { func addSpacing(_ spacing: CGFloat, after arrangedSubview: UIView) { if #available(iOS 11.0, *) { setCustomSpacing(spacing, after: arrangedSubview) } else { let index = arrangedSubviews.firstIndex(of: arrangedSubview) if let index = index, arrangedSubviews.count > (index + 1), arrangedSubviews[index + 1].accessibilityIdentifier == "spacer" { arrangedSubviews[index + 1].updateConstraint(axis == .horizontal ? .width : .height, to: spacing) } else { let separatorView = UIView(frame: .zero) separatorView.accessibilityIdentifier = "spacer" separatorView.translatesAutoresizingMaskIntoConstraints = false switch axis { case .horizontal: separatorView.widthAnchor.constraint(equalToConstant: spacing).isActive = true case .vertical: separatorView.heightAnchor.constraint(equalToConstant: spacing).isActive = true @unknown default: return } if let index = index { insertArrangedSubview(separatorView, at: index + 1) } } } } func addSpacing(_ spacing: CGFloat, before arrangedSubview: UIView) { let index = arrangedSubviews.firstIndex(of: arrangedSubview) if let index = index, index > 0, arrangedSubviews[index - 1].accessibilityIdentifier == "spacer" { let previousSpacer = arrangedSubviews[index - 1] switch axis { case .horizontal: previousSpacer.updateConstraint(.width, to: spacing) case .vertical: previousSpacer.updateConstraint(.height, to: spacing) @unknown default: return // Incase NSLayoutConstraint.Axis is extended in future } } else { let separatorView = UIView(frame: .zero) separatorView.accessibilityIdentifier = "spacer" separatorView.translatesAutoresizingMaskIntoConstraints = false switch axis { case .horizontal: separatorView.widthAnchor.constraint(equalToConstant: spacing).isActive = true case .vertical: separatorView.heightAnchor.constraint(equalToConstant: spacing).isActive = true @unknown default: return } if let index = index { insertArrangedSubview(separatorView, at: max(index - 1, 0)) } } } func removeSpacing(after arrangedSubview: UIView) { if #available(iOS 11.0, *) { setCustomSpacing(0, after: arrangedSubview) } else { if let index = arrangedSubviews.firstIndex(of: arrangedSubview), arrangedSubviews.count > (index + 1), arrangedSubviews[index + 1].accessibilityIdentifier == "spacer" { arrangedSubviews[index + 1].removeFromStack() } } } func removeSpacing(before arrangedSubview: UIView) { if let index = arrangedSubviews.firstIndex(of: arrangedSubview), index > 0, arrangedSubviews[index - 1].accessibilityIdentifier == "spacer" { arrangedSubviews[index - 1].removeFromStack() } } } extension UIView { func updateConstraint(_ attribute: NSLayoutConstraint.Attribute, to constant: CGFloat) { for constraint in constraints { if constraint.firstAttribute == attribute { constraint.constant = constant } } } func removeFromStack() { if let stack = superview as? UIStackView, stack.arrangedSubviews.contains(self) { stack.removeArrangedSubview(self) // Note: 1 removeFromSuperview() } } }
Hinweis: 1 - Gemäß der Dokumentation:
quelle
Um ein ähnliches Verhalten wie CSS-Rand und Auffüllung zu erzielen.
Polsterung
myStackView.directionalLayoutMargins = NSDirectionalEdgeInsets (oben: oben, führend: links, unten: unten, nachlaufend: rechts);
Rand (erstellen Sie eine Wrapper-Ansicht und fügen Sie dem Wrapper Polster hinzu)
quelle
Wenn Sie die vorherige Ansicht nicht kennen, können Sie eine eigene UIView mit Abstand erstellen und diese als angeordnete Unteransicht zu Ihrer Stapelansicht hinzufügen.
quelle