对于我们使用的UICollectionView动态高度单元,
if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout {
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}
Run Code Online (Sandbox Code Playgroud)
对于高度和宽度的适当约束,它适用于iOS 11.*版本,但它破坏并且不会使iOS 12.0的单元格动态
uicollectionview uicollectionviewlayout swift uicollectionviewflowlayout ios12
我发现了一个关于如何制作粘性标题的博客,它的效果非常好.唯一的问题是我不认为它考虑了sectionInserts.
这是它的目的:

我有我的插页:
collectionViewFlowLayout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
Run Code Online (Sandbox Code Playgroud)
使用粘性标题,它向下移动16个像素:

我尝试使用原始代码进行调试,我认为问题出在最后一部分:
layoutAttributes.frame = (CGRect){
.origin = CGPointMake(origin.x, origin.y),
.size = layoutAttributes.frame.size
Run Code Online (Sandbox Code Playgroud)
如果我将其更改为origin.y - 16,则标题将从正确的位置开始,但是当向上推时,头部的16个像素会离开屏幕:

我不知道如何让它考虑到sectionInsects.有人可以帮忙吗?
以下是博客中的完整代码:
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
UICollectionView * const cv = self.collectionView;
CGPoint const contentOffset = cv.contentOffset;
NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet];
for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell) {
[missingSections addIndex:layoutAttributes.indexPath.section];
}
}
for (UICollectionViewLayoutAttributes *layoutAttributes in answer) {
if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) …Run Code Online (Sandbox Code Playgroud) 因此,我已通过返回实现部分工作在我UICollectionView粘头YES的shouldInvalidateLayoutForBoundsChange:.但是,这会影响性能,我不想让整个布局无效,只有我的标题部分无效.
现在,根据我可以用来UICollectionViewLayoutInvalidationContext为我的布局定义自定义失效上下文的官方文档,但文档非常缺乏.它要求我"定义代表可以独立重新计算的布局数据部分的自定义属性",但我不明白它们的含义.
有没有人有任何经验子类UICollectionViewLayoutInvalidationContext?
是否可以使用UICollectionView构建布局,其中每个部分可以独立滚动?例如,想象20行图像,其中每行可以水平独立滚动以在屏幕外显示更多图像(在此过程中不滚动其他行); 并且整个视图可以垂直滚动以显示更多行.
我相信这样的事情可以用UIScrollView中的几个UICollectionView实例来实现; 但是,利用UICollectionView插入/移动部分会很棒.
我怀疑这是不实际的,因为UICollectionView是UIScrollView的子类; 但也许这可以通过自定义UICollectionViewLayout完成?
这是导致警告的代码:
private override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
let distance = CGRectGetMidX(attributes!.frame) - self.midX;
var transform = CATransform3DIdentity;
transform = CATransform3DTranslate(transform, -distance, 0, -self.width);
attributes!.transform3D = CATransform3DIdentity;
return attributes
}
Run Code Online (Sandbox Code Playgroud)
控制台还打印:
这可能是因为流布局"xyz"正在修改UICollectionViewFlowLayout返回的属性而不复制它们.
我该如何修复此警告?
当使用UICollectionViewFlowLayout的子类在具有现有补充视图的集合视图中插入多个自定义补充视图时,集合视图似乎会创建出色的动画或者无法正确处理插入.
插入一个补充视图的行为与预期相同,但一次插入两个补充视图会导致明显的视觉故障,并且一次插入许多补充视图(例如4+)会使故障恶化.(iOS 10.2,iOS 9.3,Swift 3,Xcode 8.2.1)
这是一个演示:
您可以使用此示例项目重现该问题.在该简化示例中,每个项目有一个补充视图,并且在每个批次更新期间插入两个项目(具有两个补充视图).在我的实际项目中,我的补充视图少于项目,我使用其他流程布局功能.
我最好的猜测是,某些东西导致集合视图混淆了与现有/插入的补充视图相对应的索引路径或布局属性.如果这是Apple课程中的一个错误,我将非常感谢您最优雅的解决方法.
试图解决方案
我试过并仔细检查以下各项:
实现 -indexPathsToInsertForSupplementaryView(ofKind:)据我所知,这很简单,我的实现返回正确的索引路径.始终插入视图.对于补充页眉和页脚视图,UICollectionViewFlowLayout似乎返回索引路径的排序数组,但对数组进行排序对我没有任何影响.
提供初始和最终布局属性 - super为这些方法调用似乎返回正确的帧,因此对初始或最终布局属性进行哪些调整(如果有)以解决问题并不明显.但请看下面提到的第三个好奇心.
使布局无效 -it似乎完全没有区别是布局是在全部或部分之前,期间,之后performBatchUpdates(),还是根本手动无效.
自定义索引路径 - 尽管补充元素的索引路径不需要对应于项索引路径,但据我所知,尽管文档相反,UICollectionViewFlowLayout将崩溃(通过请求不存在的索引路径的布局属性),除非相同类型的补充元素从0开始按顺序编号.我假设这是集合视图和/或布局对象在插入或删除元素时(即通过递增或递减item索引的属性)计算新索引路径的方式路径).因此,构建任意索引路径不是一种选择.
调试时注意到了好奇心
视觉故障特定于补充视图,并且对于插入的项目不会发生,即使索引路径和帧对于两者都相同.
调试视图层次结构表明,虽然插入的补充视图的帧是正确的,但是一些现有补充视图的帧不正确.尽管布局对象为这些索引路径上的现有视图返回的帧看起来是正确的,但事实仍是如此.
插入多个补充视图时,集合视图对初始和最终布局属性的调用似乎是不平衡的.也就是说,对于相同的索引路径,多次请求初始布局属性(当然,每次都返回相同的属性),并且对最终布局属性的请求较少.此外,对于一些现有的补充视图,根本不会请求初始和最终布局属性.我觉得这很可疑.它让我相信集合视图在更新之前和之后会以某种方式混淆补充视图和/或索引路径.
我的Swift代码创建的IndexPath实例的内存地址与UICollectionView和UICollectionViewFlowLayout内部创建的NSIndexPath实例截然不同.前者总是不同(如预期的那样),而后者在发射之间看起来是相同的(例如[0,0],[0,1]和[0,2]总是在0xc000000000000016,0xc000000000200016和0xc000000000400016).在Swift中,IndexPath桥接到NSIndexPath,但前者是值类型,而后者是引用类型.NSIndexPath还使用标记指针.很可能两者没有完全桥接和/或集合视图类内部依赖NSIndexPath行为以某种方式导致索引路径混淆.我不知道如何测试这个或进一步.
类似的问题
以下问题可能有关,但没有一个答案对我有用:
该问题也可能与Open Radar上的此错误报告有关.该报告附带的示例项目有点过于复杂而无法使用.
Apple技术支持
发布此问题后,我向Apple提交了技术支持事件.Apple Developer Support回复如下:
我们的工程师已经审核了您的请求,并确定最好将其作为错误报告处理.
请使用https://developer.apple.com/bug-reporting/上的错误报告工具提交有关此问题的完整错误报告.
...
我们花了一些时间调查解决方法的可能性,不幸的是空手而归.请跟进你的错误.如果我们将来发现某种解决方法的可能性,我们会伸出援助之手.对不起,我没有更好的消息.
如果您遇到此问题,请复制rdar:// 30510010.
我在CollectionView中使用CustomLayout完成了一个View.在iOS6中,它工作得很好,但iOS7会抛出这样的异常.
因未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:
'索引路径({length = 2,path = 0 - 0})上的补充项的布局属性从CustomSupplementaryAttributes:0xd1123a0索引路径更改:(NSIndexPath:0xd112580 {length = 2,path = 0 - 0}); 元素种类:(标识符); frame =(0 0; 1135.66 45); zIndex = -1; 到CustomSupplementaryAttributes:0xd583c80索引路径:(NSIndexPath:0xd583c70 {length = 2,path = 0 - 0}); 元素种类:(标识符); frame =(0 0; 1135.66 45); zIndex = -1; 没有使布局失效'
我正在使用UICollectionView并需要一个全局页眉和页脚以及节标题.全局页眉和页脚都应该与其余内容一起滚动.基本上它们应该像UITableView的tableHeaderView和tableFooterView属性一样工作.
根据我的理解,补充意见在特定部分的上方或下方,装饰视图无功能.我的全局页眉和页脚应该具有交互元素.
尝试了几个小时后,我真的把头发拉了出来.我找到了一些令人讨厌的方法,比如使用contentInsets进行黑客攻击并将子视图添加到collectionview中.我真正想要的是一个干净的方法来做到这一点.
我期待着任何建议!
我有一个常见的UICollectionView与分页和所有.
仍然试图找出viewDidLoad:,viewWillAppear:和viewDidAppear:上的原因,仅在第一次视图调用时,我在调用myCollectionView.collectionView.contentSize.width时得到了错误的大小.它始终以0宽度响应(高度总是正确的).连续重新加载视图让我得到正确的视图.
求助于使用
self.collectionView.collectionViewLayout.collectionViewContentSize
Run Code Online (Sandbox Code Playgroud)
在第一次加载时给我正确的宽度事件.
对我来说还是一个谜.
所以这是我们UICollectionViewFlowLayout在iOS 10上发现的一个有趣的问题(仍然是11的问题)并UICollectionViewFlowLayoutAutomaticSize用于estimateItemSize.
我们发现使用UICollectionViewFlowLayoutAutomaticSizeestimatedItemSize导致页脚补充视图浮动在底部的几个单元格之上.(红色/粉红色是标题,绿色是页脚.)
以下是示例应用的VC代码:
import UIKit
class ViewController: UIViewController {
// MARK: Properties
let texts: [String] = [
"This is some text",
"This is some more text",
"This is even more text"
]
// MARK: Outlets
@IBOutlet var collectionView: UICollectionView! {
didSet {
self.collectionView.backgroundColor = .orange
}
}
// MARK: Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Layout
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
if #available(iOS 10.0, *) {
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
} …Run Code Online (Sandbox Code Playgroud) uicollectionview ×10
ios ×7
swift ×3
objective-c ×2
animation ×1
cocoa-touch ×1
ios12 ×1
ios6 ×1
uikit ×1