FlexLayout icon indicating copy to clipboard operation
FlexLayout copied to clipboard

Add helper to simulate UIStackView spacing

Open Villy21 opened this issue 5 years ago • 4 comments

You can add small helper to make UIStackView like UI with spacing between items.

/**
 Set offset from other items in same container.
 Assign same spacing for all items in container to make spacing like in UIStackView.
 This method conflicts with setting vertical padding and margin.
 */
@discardableResult
func spacingVertical(_ value: CGFloat) -> Flex {
	let offset = value / 2.0
	return paddingVertical(-offset).marginVertical(offset)
}

/**
 Set offset from other items in same container.
 Assign same spacing for all items in container to make spacing like in UIStackView.
 This method conflicts with setting horizontal padding and margin.
 */
@discardableResult
func spacingHorizontal(_ value: CGFloat) -> Flex {
	let offset = value / 2.0
	return paddingHorizontal(-offset).marginHorizontal(offset)
}

Use like this

// |view1 - 10 - view2 - 10 - view3|
flex.addItem().direction(.column).define({ (flex) in
	flex.addItem(view1).spacingVertical(10)
	flex.addItem(view2).spacingVertical(10)
	flex.addItem(view3).spacingVertical(10)
})

// |view1|
flex.addItem().direction(.column).define({ (flex) in
	flex.addItem(view1).spacingVertical(10)
})

Villy21 avatar Sep 27 '19 13:09 Villy21

Not sure to understand your proposition. Your methods are setting the item's padding and margin. Padding applies only to sub-items of this item, so it shouldn't have any impact if the item doesn't have any sub-items.

How is it different to just call marginVertical:

flex.addItem().direction(.column).define({ (flex) in
	flex.addItem(view1).marginVertical(10)
	flex.addItem(view2).marginVertical(10)
	flex.addItem(view3).marginVertical(10)
})

lucdion avatar Oct 07 '19 20:10 lucdion

Hello, UIStackView add space only between items. If you use only marginVertical it will also add same space from top and bottom borders of parent container.

So using paddingVertical + marginVertical will only change space between items. But space between top item and top border will be 0. And space from bottom item and bottom border will be 0. So it will work like UIStackView.

Villy21 avatar Oct 07 '19 21:10 Villy21

But this would also add an extra spacing of 10 pixels below the last items 🤔

This would do exactly what you want:

flex.addItem().direction(.column).define({ (flex) in
	flex.addItem(view1)
	flex.addItem(view2).marginTop(10)
	flex.addItem(view3).marginTop(10)
})

Maybe we could add a method on the container that does that once all items have been added? ex:

flex.addItem().direction(.column).define({ (flex) in
	flex.addItem(view1)
	flex.addItem(view2)
	flex.addItem(view3)
}).spacingVertical(10)

lucdion avatar Oct 08 '19 13:10 lucdion

This would be very useful when using .wrap, because I don't want margin on the first view of the row.

lluisgerard avatar Apr 28 '20 16:04 lluisgerard

Very old topic. Closing it.

lucdion avatar Mar 01 '23 20:03 lucdion