mischa-hildebrand / alignedcollectionviewflowlayout Goto Github PK
View Code? Open in Web Editor NEWA collection view layout that gives you control over the horizontal and vertical alignment of the cells.
License: MIT License
A collection view layout that gives you control over the horizontal and vertical alignment of the cells.
License: MIT License
When integrating this in a project by hand, via submodules or via Carthage Checkouts, currently builds fail since the class doesn't import UIKit
.
I have implemnted AlignedCollectionViewFlowLayout on my app.
let leftAlignLayout = AlignedCollectionViewFlowLayout(horizontalAlignment: .left, verticalAlignment: .top)
leftAlignLayout.estimatedItemSize = CGSize(width: 1, height: 1)
// Margin
leftAlignLayout.minimumInteritemSpacing = 6
leftAlignLayout.minimumLineSpacing = 6
leftAlignLayout.sectionInset = UIEdgeInsets(top: 6, left: 6, bottom: 6, right: 6)
collectionView.collectionViewLayout = leftAlignLayout
It crash on iPhone X. On iphone 6, 6s and other it works normally.
Please help me.
Thank you for creating this great layout and sharing it with the world! ++ for a very nice readme.
I would like to create a justified layout just like the default settings provide, except instead of increasing the spacing between items, it would increase the width of the cells in that row equally to fill the available width. So the amount of spacing between the items remains consistent and the cells themselves are dynamically sized to fill the space. Would that be possible using this layout?
I'm envisioning it would obtain the same amount of spacing in row 4 for rows 1-3 by increasing the width of the cells in each row until that same spacing is obtained.
Loving the library! So useful, its suprising that UICollectionView doesnt support this kind of functionality by default.
Just been testing it myself by using the AlignedCollectionViewFlowLayout
example to test the performance. Only thing is, if I have a list of items around 500 long, I notice that the CPU usage jumps to up to 80% if you can scroll fast enough. This will happen regardless of the arrays size but is more difficult to replicate because you cant scroll as fast.
Is there anything I can do t improve the performance? This is using the iPhone Simulator on iOS 10.3. I know that the iOS Simulator isnt very good for judging performance so maybe its just that.
I'm getting a crash force unwrapping a nil value testing on iOS 15 Beta but on iPad only. iPhone seems to work fine. The crash occurs here
// It's okay to force-unwrap here because we pass a non-empty array.
return verticalAlignmentAxisForLine(with: layoutAttributesInLine)!
the cause being on iPad
super.layoutAttributesForElements
called by layoutAttributes(forItemsInLineWith: currentLayoutAttributes)
returns nil (and therefore an empty array) whereas on iPhone this returns the layout attributes of the cell. The verticalAlignmentAxisForLine
func returns nil if the attributes array is empty therefore causing the force unwrap to crash.
guard let firstAttribute = layoutAttributes.first else {
return nil
}
Whilst this issue might be fixed in a subsequent beta release I think it exposes a valid issue with the force unwrap. Perhaps a default alignment should be returned by verticalAlignmentAxisForLine
instead of nil?
guard let firstAttribute = layoutAttributes.first else {
return AlignmentAxis(alignment: verticalAlignment, position: 0)
}
When I try to add AlignedCollectionViewFlowLayout
via Swift Package Manager in Xcode. It shows me this error:
https://github.com/mischa-hildebrand/AlignedCollectionViewFlowLayout.git has no Package.swift manifest for version 1.1.2
Given that for some layouts the desired alignment of the cells may actually depend upon how the cells themselves align their content with respect to the leading and trailing edges or depending upon their labels' text alignment, it makes sense to be directionally aware in this library.
I am having a hard time trying to add header sections along with your awesome AlignedcollectionViewFlowLayout, but my attempts are failing.
What I did so far was adding layoutAttributesForSupplementaryView:ofKind:at to your .swift file and modifying your setFrame function to process UICollectionElementKindSectionHeader. I also added a public var for header's height: headerHeight
override open func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let attributes = super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath)?.copy() as? UICollectionViewLayoutAttributes else {
print("nill called attributes")
return nil
}
print("first cell frame = \(layoutAttributesForItem(at: indexPath)!.frame)")
let yPos:CGFloat = layoutAttributesForItem(at: indexPath)!.frame.origin.y - headerHeight
attributes.frame = CGRect(x: 0.0, y: yPos, width: (collectionView?.frame.width)!, height: headerHeight)
return attributes
}
and
/// Sets the frame for the passed layout attributes object by calling the `layoutAttributesForItem(at:)` function.
private func setFrame(forLayoutAttributes layoutAttributes: UICollectionViewLayoutAttributes) {
if layoutAttributes.representedElementCategory == .cell { // Do not modify header views etc.
let indexPath = layoutAttributes.indexPath
if let newFrame = layoutAttributesForItem(at: indexPath)?.frame {
layoutAttributes.frame = newFrame
}
} else if layoutAttributes.representedElementCategory == .supplementaryView {
if layoutAttributes.representedElementKind == UICollectionElementKindSectionHeader {
if let newFrame = layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: layoutAttributes.indexPath)?.frame {
layoutAttributes.frame = newFrame
}
}
}
}
My implementation seems to work right, but when I segue to my ViewController where I am implementing your custom flow layout, viewForSupplementaryElementOfKind is called too soon before the correct attributes are calculated. I know this because I am triggering a call to viewForSupplementaryElementOfKind by reloadItems(at:) inside collectionView:didSelectItemAt
(Edit: I added the following block to my viewDidAppear to work around this delay
UIView.performWithoutAnimation {
filterCollection.reloadItems(at: [IndexPath(row: patterns.count - 1, section: 2)])
}
)
I've also printed frame values for first cell in section as well as the header frame. It seems that my attributes are calculated 4 times and the viewForSupplementaryElementOfKind function takes values from the 3rd call
Edit:
see attachment for screens after segueing to VC, log from console about first cell in section and header saved frame, and screen of collectionView after triggering didSelectItemAt or reloadingItems in viewDidAppear
I'd really appreciate it if you'd help me to avoid making extra call to reloadItems(at:)
let layout = AlignedCollectionViewFlowLayout(horizontalAlignment: .left, verticalAlignment: .top)
layout.minimumLineSpacing = 10
layout.minimumInteritemSpacing = 10
layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 20, right: 10)
layout.estimatedItemSize = CGSize(width: 100, height: 40)
When the content is too long for the screen,"cell" display error; I want to process as ellipsis style "xxxx...xxxx"
Right to left support is very important can you do another release so that feature is accessible directly without specifying sha via cocoapods?
Hello @mischa-hildebrand,
I could not figure how to limit the width of cells, so that they do not extend the width of the enclosing collection view.
Do you have any advice ?
In the screenshot below, UILabels have the standard compression resistance, have lineBreakMode = .byTruncatingTail
, and numberOfLines = 1
:
I'm using alignedFlowLayout
this way:
alignedFlowLayout.horizontalAlignment = .left
alignedFlowLayout.verticalAlignment = .top
After XCode updates to 10.0 (but still using Swift 4.0) flow layout requires to update manually after collection view reloaded:
alignedFlowLayout.invalidateLayout()
If there is an any other way for correct using or please fix an issue
Thanx a lot!
Hello @mischa-hildebrand,
Thank you very much for your very useful layout 👍
I could spot an issue: sometimes cells would not appear on screen.
The screenshot below displays various setups for a custom "InlineStackView" based on your layout. The "Various Heights" item displays a collection view with pills of various font sizes. For some arrangement of font sizes, one item is not displayed.
Can describe more if needed.
Edit: having read the code, this would be a pretty intrusive fix.
When will the pod be updated? The pod still has the issue of the init being "internal" and therefore inaccessible to users of the pod.
init(horizontalAlignment:.left,verticalAlignment:.top)
估计项目尺寸=CGSize(宽度:100,高度:40)
cell 内容过长,超出屏幕外
应该处理成 ... 省略模式
If you enter a longer string, even in your example project, in one of the cells, the whole layout breaks and none of the cells are loaded. Is there a way to provide support for multi-line labels which would resize the cell dynamically not only by width as it does now but by height also?
Are there any plans to support SwiftPM?
fileprivate func layoutAttributes(forItemsInLineWith layoutAttributes: UICollectionViewLayoutAttributes) -> [UICollectionViewLayoutAttributes] {
guard let lineWidth = contentWidth else {
return [layoutAttributes]
}
var lineFrame = layoutAttributes.frame
lineFrame.origin.x = sectionInset.left
lineFrame.size.width = lineWidth
// Need to be add
// bug fix for super.layoutAttributesForElements(in:)
// if there are three row (Row1, Row2, Row3), and rows step by step closly, such as
// Row1: (x: 0, y: 0, width: 375, 100)
// Row2: (x: 0, y: 100, width: 375, height: 100)
// Row3: (x: 0, y: 200, width: 375, height: 100)
// then super.layoutAttributesForElements() will reture 3 values(Row1, Row2, Row3), that is incorrect
if lineFrame.height > 2 {
lineFrame.origin.y += 1
lineFrame.size.height -= 2
}
return super.layoutAttributesForElements(in: lineFrame) ?? []
}
That's any way to align the item centralized in the horizontalAlignment ?
Hi! Do you have supported UICollectionViewScrollDirectionHorizontal?
This is a comprehensive and most useful framework. Many thanks! It would be handy to also include a horizontal alignment of centre
ala [https://github.com/Coeur/CollectionViewCenteredFlowLayout]
Is there a way to edit the flow layout to have a single line scrolling horizontally?
Hi,
I have a collectionView with vertical flow layout that contains the header and shows two cells in a row, the following code will return incorrect y pos in one of the cell:
Line 303:
switch verticalAlignment {
case .top:
let minY = layoutAttributes.reduce(CGFloat.greatestFiniteMagnitude) { min($0, $1.frame.minY) }
return AlignmentAxis(alignment: .top, position: minY)
I found out the issue is caused by the UICollectionElementKindSectionHeader contains in the layoutAttributes array and affected the result of minY.
Here is my quick fix:
let filteredLayoutAttributes = layoutAttributes.filter { layoutAttribute in
return layoutAttribute.representedElementCategory == .cell
}
let minY = filteredLayoutAttributes.reduce(CGFloat.greatestFiniteMagnitude) { min($0, $1.frame.minY) }
return AlignmentAxis(alignment: .top, position: minY)
With the justify horizontal alignment, would it be possible to justify this row as well so that the last cell is aligned on the right with all the rows above it?
This example with iOS 9 has crash
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.