问题
I want my app to be optimized for every accessibility options including the text size.
I made a collectionView layout based on sections with a compositional layout. So I need my cell's height to grow with it's content. I thought using .estimated(constant)
would do the job but it doesn't seem to work. The inner constraints seems good to me.
Here is the layout I'm working with :
let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.42), heightDimension: .estimated(90))
let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(90)))
item.contentInsets = NSDirectionalEdgeInsets(top: 5.0, leading: 12.0, bottom: 5.0, trailing: 12.0)
let group = NSCollectionLayoutGroup.vertical(layoutSize: size, subitem: item, count: 1)
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 0.0, leading: 6.0, bottom: 0.0, trailing: 0.0)
section.orthogonalScrollingBehavior = .groupPaging
When I set a higher text size on the accessibility settings here is what happens :
The cell is supposed to contain 2 labels here is the autoLayoutConstraints :
NSLayoutConstraint.activate([
self.titleLabel.topAnchor.constraint(equalTo: self.container.topAnchor, constant: 10),
self.titleLabel.leftAnchor.constraint(equalTo: self.container.leftAnchor, constant: 20),
self.titleLabel.rightAnchor.constraint(equalTo: self.container.rightAnchor, constant: -20)
])
NSLayoutConstraint.activate([
self.subtitleLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 10),
self.subtitleLabel.leftAnchor.constraint(equalTo: self.container.leftAnchor, constant: 20),
self.subtitleLabel.rightAnchor.constraint(equalTo: self.container.rightAnchor, constant: -20),
self.subtitleLabel.bottomAnchor.constraint(equalTo: self.container.bottomAnchor, constant: -10)
])
Thanks in advance for your help.
回答1:
What solved the issue for me was to set the same height dimension to both the item and the group.
I know it's the case in the question's shared code, and @Que20's solution definitely helped. But in case the problem persists you might wanna check that.
Example
I'm trying to display a cell containing a single UIButton pinned to the cell's margins. The button has a 44 points high height constraint.
Original Attempt
static func mapSection() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: .fractionalHeight(1)) // Here: a fractional height to the item
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .estimated(100)) // There: estimated height to the button cell
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
return section
}
Despite everything being configured correctly, the button's height constraint breaks and the "estimation" becomes an absolute value.
Successful implementation
static func mapSection() -> NSCollectionLayoutSection {
/*
Notice that I estimate my button cell to be 500 points high
It's way too much. But since it's an estimation and we're doing things well,
it doesn't really matter to the end result.
*/
let heightDimension = NSCollectionLayoutDimension.estimated(500)
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1),
heightDimension: heightDimension)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: heightDimension)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
return section
}
The only real difference lies in the fact that both the item and the group are set to the same estimated height dimension. But it works now!
回答2:
I found that making my LayoutGroup horizontal instead of vertical fixed the issue. Here is my final layout :
let estimatedHeight = CGFloat(100)
let layoutSize = NSCollectionLayoutSize(widthDimension: .estimated(200), heightDimension: .estimated(estimatedHeight))
let item = NSCollectionLayoutItem(layoutSize: layoutSize)
let group = NSCollectionLayoutGroup.horizontal(layoutSize: layoutSize, subitem: item, count: 1)
let section = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
section.interGroupSpacing = 10
section.orthogonalScrollingBehavior = .groupPaging
Hope it'll help ^^
回答3:
On iOS13+ if you want to create layout where the cell's constraints determine the height of the cell - try this one:
private func configureCollectionView() {
collectionView.collectionViewLayout = createLayout()
}
private func createLayout() -> UICollectionViewLayout {
let layout = UICollectionViewCompositionalLayout {
(sectionIndex: Int, layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
let size = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(10))
let item = NSCollectionLayoutItem(layoutSize: size)
item.edgeSpacing = NSCollectionLayoutEdgeSpacing(leading: nil, top: NSCollectionLayoutSpacing.fixed(20), trailing: nil, bottom: NSCollectionLayoutSpacing.fixed(0))
let group = NSCollectionLayoutGroup.vertical(layoutSize: size, subitems: [item])
group.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 20, bottom: 0, trailing: 20)
let section = NSCollectionLayoutSection(group: group)
return section
}
return layout
}
Make sure your constraints and hugging and compression resistance in the cell have priority - 1000 (required), all of them: stackviews, labels etc.
You should get something like this:
Or if you want horizontal scrolling with pagination, just add:
section.orthogonalScrollingBehavior = .groupPaging
to your section property, on layout creation and you will get something like this:
Enjoy :)
回答4:
Not sure it’s relevant to the system accessibility but AFAIK you can’t use .estimated()
with .contentInsets
on items.
It does work sometimes but unreliably. I’m also fighting this right even when trying to apply the insets to a group (tho it's a subclass of item, would've imagined it'd work) :(
来源:https://stackoverflow.com/questions/58339188/collection-view-compositional-layout-with-estimated-height-not-working