UICollectionView 装饰视图

2024-01-18

有人为 iOS 6 UICollectionView 实现了装饰视图吗?不可能 查找有关在网络上实现装饰视图的任何教程。基本上在我的应用程序中,我有多个部分,我只想在每个部分后面显示一个装饰视图。这应该很容易实现,但我没有运气。这让我发疯...谢谢。


这是一个集合视图布局装饰视图教程在 Swift 中(这是 Swift 3,Xcode 8 种子 6)。


装饰视图不是 UICollectionView 的功能;它们本质上属于 UICollectionViewLayout。没有 UICollectionView 方法(或委托或数据源方法)提及装饰视图。 UICollectionView 对它们一无所知;它只是按照它的指示去做。

要提供任何装饰视图,您将需要一个 UICollectionViewLayout 子类;这个子类可以自由定义自己的属性和委托协议方法来自定义其装饰视图的配置方式,但这完全取决于您。

为了说明这一点,我将对 UICollectionViewFlowLayout 进行子类化,以在集合视图的内容矩形的顶部强加一个标题标签。这可能是对装饰视图的愚蠢使用,但它完美地说明了基本原理。为了简单起见,我将首先对整个事情进行硬编码,使客户端无法自定义该视图的任何方面。

在布局子类中实现装饰视图有四个步骤:

  1. 定义 UICollectionReusableView 子类。

  2. 使用布局注册 UICollectionReusableView 子类 (not集合视图),通过调用register(_:forDecorationViewOfKind:)。布局的初始值设定项是执行此操作的好地方。

  3. 实施layoutAttributesForDecorationView(ofKind:at:)返回定位 UICollectionReusableView 的布局属性。要构造布局属性,请调用init(forDecorationViewOfKind:with:)并配置属性。

  4. 覆盖layoutAttributesForElements(in:)使得结果为layoutAttributesForDecorationView(ofKind:at:)包含在返回的数组中。

最后一步是导致装饰视图出现在集合视图中的原因。当集合视图调用时layoutAttributesForElements(in:),它发现结果数组包含指定类型的装饰视图的布局属性。集合视图对装饰视图一无所知,因此它返回到布局,要求这种装饰视图的实际实例。您已经注册了这种装饰视图以对应于您的 UICollectionReusableView 子类,因此您的 UICollectionReusableView 子类被实例化并返回该实例,并且集合视图根据布局属性来定位它。

那么让我们按照步骤操作吧。定义 UICollectionReusableView 子类:

class MyTitleView : UICollectionReusableView {
    weak var lab : UILabel!
    override init(frame: CGRect) {
        super.init(frame:frame)
        let lab = UILabel(frame:self.bounds)
        self.addSubview(lab)
        lab.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        lab.font = UIFont(name: "GillSans-Bold", size: 40)
        lab.text = "Testing"
        self.lab = lab
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

现在我们转向 UICollectionViewLayout 子类,我将其称为 MyFlowLayout。我们在布局的初始值设定项中注册 MyTitleView;我还定义了剩余步骤所需的一些私有属性:

private let titleKind = "title"
private let titleHeight : CGFloat = 50
private var titleRect : CGRect {
    return CGRect(10,0,200,self.titleHeight)
}
override init() {
    super.init()
    self.register(MyTitleView.self, forDecorationViewOfKind:self.titleKind)
}

实施layoutAttributesForDecorationView(ofKind:at:):

override func layoutAttributesForDecorationView(
    ofKind elementKind: String, at indexPath: IndexPath) 
    -> UICollectionViewLayoutAttributes? {
        if elementKind == self.titleKind {
            let atts = UICollectionViewLayoutAttributes(
                forDecorationViewOfKind:self.titleKind, with:indexPath)
            atts.frame = self.titleRect
            return atts
        }
        return nil
}

覆盖layoutAttributesForElements(in:);这里的索引路径是任意的(我在前面的代码中忽略了它):

override func layoutAttributesForElements(in rect: CGRect) 
    -> [UICollectionViewLayoutAttributes]? {
        var arr = super.layoutAttributesForElements(in: rect)!
        if let decatts = self.layoutAttributesForDecorationView(
            ofKind:self.titleKind, at: IndexPath(item: 0, section: 0)) {
                if rect.intersects(decatts.frame) {
                    arr.append(decatts)
                }
        }
        return arr
}

这有效!标题标签“测试”出现在集合视图的顶部。


现在我将展示如何使标签可定制。我们将允许客户端设置一个确定标题的属性,而不是标题“测试”。我将把我的布局子类设为 publictitle财产:

class MyFlowLayout : UICollectionViewFlowLayout {
    var title = ""
    // ...
}

任何使用此布局的人都应该设置此属性。例如,假设此集合视图显示美国 50 个州:

func setUpFlowLayout(_ flow:UICollectionViewFlowLayout) {
    flow.headerReferenceSize = CGSize(50,50)
    flow.sectionInset = UIEdgeInsetsMake(0, 10, 10, 10)
    (flow as? MyFlowLayout)?.title = "States" // *
}

现在我们遇到了一个奇怪的难题。我们的布局有一个title属性,其值需要以某种方式传递给我们的 MyTitleView 实例。但这什么时候可能发生呢?我们不负责实例化 MyTitleView;当集合视图在后台请求实例时,它会自动发生。 MyFlowLayout 实例和 MyTitleView 实例没有相遇的时刻。

解决方案是使用布局属性作为信使。 MyFlowLayout 永远不会满足 MyTitleView,但它确实创建了布局属性对象,该对象被传递到集合视图以配置 MyFlowLayout。所以布局属性对象就像一个信封。通过子类化 UICollectionViewLayoutAttributes,我们可以在该信封中包含我们喜欢的任何信息 - 例如标题:

class MyTitleViewLayoutAttributes : UICollectionViewLayoutAttributes {
    var title = ""
}

这是我们的信封!现在我们重写我们的实现layoutAttributesForDecorationView。当我们实例化布局属性对象时,我们实例化我们的子类并设置它的title财产:

override func layoutAttributesForDecorationView(
    ofKind elementKind: String, at indexPath: IndexPath) -> 
    UICollectionViewLayoutAttributes? {
        if elementKind == self.titleKind {
            let atts = MyTitleViewLayoutAttributes( // *
                forDecorationViewOfKind:self.titleKind, with:indexPath)
            atts.title = self.title // *
            atts.frame = self.titleRect
            return atts
        }
        return nil
}

最后,在 MyTitleView 中,我们实现了apply(_:)方法。当集合视图配置装饰视图时,这将被调用 - 使用布局属性对象作为其参数!所以我们拉出title并将其用作我们标签的文本:

class MyTitleView : UICollectionReusableView {
    weak var lab : UILabel!
    // ... the rest as before ...
    override func apply(_ atts: UICollectionViewLayoutAttributes) {
        if let atts = atts as? MyTitleViewLayoutAttributes {
            self.lab.text = atts.title
        }
    }
}

很容易看出如何扩展该示例以使字体和高度等标签功能可自定义。由于我们是 UICollectionViewFlowLayout 的子类,因此可能还需要进行一些进一步的修改,通过下推其他元素来为装饰视图腾出空间。另外,从技术上讲,我们应该覆盖isEqual(_:)在 MyTitleView 中区分不同的标题。所有这些都留给读者作为练习。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UICollectionView 装饰视图 的相关文章

  • iOS 8 支持动态链接吗?

    直到 iOS7 之前 出于安全考虑 Apple 都不支持动态链接 开发人员之间的代码重用通常依赖于静态库 这些静态库是作为应用程序可执行文件的一部分构建的 在 iOS8 中引入扩展似乎稍微改变了这一点 因为扩展是单独的可执行文件 扩展及其包
  • 部署目标是什么意思?

    这是我假设的一个非常简单的问题 有人可以告诉我部署目标是什么意思吗 如果我选择 iOS 10 是否意味着只有 iOS 10 的用户才能下载该应用程序 选择较低的部署目标是否不好 另外 继续部署目标 是否不建议在较低的部署目标上运行 假设您已
  • tableView.dequeueReusableCellWithIdentifier() 导致应用程序挂起

    原帖 我们最近将我们的应用程序转换为 Swift 2 0 和 iOS9 我看到的一个奇怪的问题是调用 tableView dequeueReusableCellWithIdentifier 会导致应用程序挂在模拟器中 The code fu
  • 如何在 iOS 上压缩 Realm DB?

    我想定期压缩 iOS 上的 Realm 实例以回收空间 我认为该过程是将数据库复制到临时位置 然后将其复制回来并使用新的default realm 文件 我的问题是Realm 其行为就像单例并回收对象 因此我无法真正关闭它并告诉它打开新的
  • UITextView 动画更改框架不会动画文本重新分配

    我有一个 UITextView 我试图在用户点击按钮时为框架的变化设置动画 基本上 文本视图会变大以适应屏幕 以便可以显示更多文本 然后当用户再次点击按钮时 它会缩小到原始框架 我使用块执行动画 如下所示 if isDisplayingDe
  • iPad 照片选择器崩溃

    我正在使用以下函数根据 UIActionSheet 的结果激活设备相机或图像选择器 如果 fromCamera YES 那么它适用于 iPhone 和 iPad 如果 fromCamera NO 那么它可以在 iPhone 上运行并出现图像
  • 检查定位服务是否开启

    我一直在对 CoreLocation 进行一些研究 最近 我遇到了一个在其他地方 但在 Objective C 和 iOS 8 中 已经讨论过的问题 我觉得问这个问题有点傻 但是如何在 iOS 9 上使用 swift 检查是否启用了位置服务
  • SwiftUI 列表与右侧的部分索引?

    是否可以有一个在右侧有索引的列表 就像下面 SwiftUI 中的示例一样 我在 SwiftUI 中做了这个 Contacts swift TestCalendar Created by Christopher Riner on 9 11 2
  • NSString – 静态还是内联?有性能提升吗?

    如果我写的话会有任何性能提升吗 NSString helloStringWithName NSString name static NSString formatString Hello return NSString stringWith
  • 打乱 NSMutableArray 而不重复并显示在 UIButton 中

    在我看来 我有 12 个按钮 一个数组包含 6 个名称 我想在其中打印数组名称UIButton标题 这是我的代码 texts NSMutableArray alloc initWithObjects 1 2 3 4 5 6 nil UIBu
  • 带操作按钮的颤动本地通知

    我在我的 flutter 项目中尝试了 flutter 本地通知插件 它在简单通知上工作正常 但我需要带有操作按钮的通知功能 请帮助我或建议我实现此功能 不幸的是 flutter local notifications 插件尚不支持操作按钮
  • 当地图视图只是屏幕的一部分时,如何在 iOS 模拟器中进行捏合?

    我在 iPad 上有一个视图 我正在添加MKMapView也就是说 全屏高度的一半 然而 当我尝试在 iOS 模拟器上进行捏合时 它不起作用 因为 to nubs 填充了模拟器上的整个 iPad 视图 And so with the map
  • UIButton的高亮状态由什么控制事件开始和结束

    我正在创建类似钢琴的视图UIButton作为钢琴键 什么UIControlEvents当按钮获得和失去突出显示状态时 我应该监听以获得回调吗 我试图创建子类UIButton并添加属性观察者highlighted并且运行良好 然而 有时我需要
  • 如何在 React Native 中构造 POST 请求主体,而不是使用字符串化的 json,而是使用 json?

    我正在努力用 React Native 替换一些本机代码 预期的 POST 请求 在AFNetworking in Charles应该是这样的 代码片段 NSError err NSData paramData NSJSONSerializ
  • 减少 CoreData 的调试输出?

    我正在开发一个使用 CoreData 的 iOS macOS 项目 它工作正常 但它会向控制台输出大量调试信息 这使得控制台无法使用 因为我的打印语句隐藏在所有与 CoreData 相关的内容中 我有一个非常简单的 CoreData 设置
  • 推送动画,没有阴影和停电

    我有一个简单的iOS NavigationController基于应用程序 二UICollectionViews 相继 如果元素打开 第一个合集 被点击时 第二集 将被打开 非常简单 重要的提示 Both UICollectionViews
  • Apple Watch 预构建操作可更改故事板 customModule 引用

    我目前有一个项目 其中包含同一应用程序的 3 个不同版本 不同的品牌等 该项目运行得很好 从那时起 我添加了 3 个新的 Apple Watch 目标 每个应用程序 版本 1 个 其中 2 个引用 主 Apple Watch 目标中的文件
  • ios水平居中约束问题?

    I am having hard time in learning constraints auto layout in iOS I have used any width any height I have a storyboard sc
  • 根据 iOS 版本使用不同的类实现?

    iOS 11 最近添加了一个我想使用的新功能 但我仍然需要支持旧版本的 iOS 有没有一种方法可以将同一个类编写两次 并让较新版本的 iOS 使用该类的一个版本 而旧版本的 iOS 使用另一个版本 注 最初我用的是if available
  • UIView晃动动画

    我试图在按下按钮时使 UIView 摇动 我正在调整我找到的代码http www cimgf com 2008 02 27 core animation tutorial window shake effect http www cimgf

随机推荐

  • 制作 PIE 对象时,不能使用针对符号“G8”的重定位 R_X86_64_32;使用-fPIE重新编译

    我正在尝试将 lambda 表达式从 schema 编译为 llvm ir 但在处理与位置无关的代码时遇到了问题 source lambda x display x target bunch of declares define SObj
  • 更新Map字段-Flutter

    如何更新 isVerified Boolean 字段的数据 个人信息是地图包含地址 然后经过验证 更新isVerified 您必须执行以下操作 Firestore instance collection collection Name do
  • 我们可以在 Spring Boot 中使用多个 kafka 模板吗?

    在我的 spring boot kafka 发布者应用程序中 我想提供对以 String json 或字节格式发布消息的支持 因为我想同时提供对 json 和 avro 的支持 但是 Spring Boot 中的 Kafka 模板让我们只定
  • 有没有办法在 R 中为 Word 制作漂亮的表格?

    我问我的问题 这是我最后的希望 我必须用 Word 制作一份报告 我从事 R Markdown 工作 必须生成许多表格 我希望我的桌子很漂亮 但我尝试过的一切 pander KableExtra flextable 不工作 我的结果来自co
  • 尝试使用 Angular 中的 Google People API 获取生日和性别

    我已经花了几个小时尝试这样做 但我永远无法获得我想要获得的数据 我需要以其他方式提出请求吗 这是我的代码 doGoogleLogin return new Promise
  • 是否有 jquery 下拉年份选择器 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有一个 jQuery 插件可以自动创建下拉年份选择器 这是一个 选择 元素 填充了从当前开始并追溯
  • 如何使用 jquery/javascript 在 safari 中复制到剪贴板?

    我研究了一堆答案和文章 它们展示了如何通过 jquery 在按钮单击时复制文本 但没有一个对我有用 我通过 ajax 将一个值附加到 DOM 中 我希望通过单击按钮来复制该值 所有这些解决方案都可以在 chrome 上运行 如果使用 jsf
  • 放弃更改而不从历史记录中删除

    有一个提交不起作用 所以我想放弃它而不将其从历史记录中删除 我已经从早期的修订版中更新并提交 从而创建了一个新的头 我没有分支 我不想要分支 我只想简单地继续使用新的头 就像它原来的样子 没有什么花哨的 没有合并 没有担心 只是继续忘记前一
  • Alexa Skills Kit 输入的“包罗万象”不符合既定意图

    我正在构建一个 Alexa 应用程序 它需要能够处理问题的答案 我有一个SkipIntent具有跳过问题的示例话语的意图 我想建立一个AnswerIntent它可以获取任何答案 并根据正确答案对其进行处理 我尝试使用Amazon LITER
  • 如何在 Java 中检测 SQL 表是否存在?

    如何在 Java 中检测给定 SQL 数据库中是否存在某个表 您可以使用DatabaseMetaData getTables http java sun com j2se 1 5 0 docs api java sql DatabaseMe
  • 何时不在 CakePhp 2.x 中使用可包含行为

    在将 Containable Behaviour 添加到我的各种模型类中几次后 我决定简单地将该行放入 AppModel 中 从而使每个模型都可包含 这让我想知道 是否有任何情况下 特定模型具有可控制行为是不理想的或适得其反的 我想说太少了
  • 更改JLabel的字体

    如何更改JLabel的字体 我尝试这样做但没有成功 JLabel nadpis new JLabel nadpis setFont new Font Papyrus Font ITALIC 100 nadpis setText hi 只是大
  • 将 BasedOn 属性与在不同字典中定义的 Style 结合使用

    我正在开发的应用程序有 2 个 ResourceDictionary DefaultStyles xaml 和 CustomStyles xaml CustomStyles 字典中的样式是否可能使用其他字典中定义的基本样式 默认样式 xam
  • 在一个查询中计算 MySQL 中的多行数

    我目前有一个表 其中存储了多个项目的大量统计信息 例如查看 下载 购买等 要获取每个项目的单个操作计数 我可以使用以下查询 SELECT COUNT FROM stats WHERE operation view GROUP BY item
  • pandas groupby 列并检查组是否满足多个条件

    我有一个如下所示的 DataFrame X Y Date are equal 0 50 0 10 0 2018 08 19 False 1 NaN 10 0 2018 08 19 False 2 NaN 50 0 2018 08 19 Tr
  • Spring Security - 记住我身份验证错误

    我们正在使用 Spring MVC 并遇到以下与 Remember Me 身份验证相关的问题 用户在选中 记住我 的情况下登录 工作正常 perpetitive login 表按预期更新 我们重新启动应用程序服务器 也许是在部署之后等 用户
  • 如何使用 Greasemonkey 更改此 javascript?

    这是脚本
  • 从网络摄像头获取帧的最快方法

    我在用 C Visual studio 开发一个程序时遇到了一点问题 现在我正在努力连接多个网络摄像头 通过 USB 电缆连接 为每个摄像头创建单独的线程来捕获帧 并创建单独的帧用于处理图像 我使用 OpenCV 来处理帧 但问题是我没有获
  • 关闭套接字是否会关闭流?

    我正在遗留的java应用程序中工作 在许多文件中 使用套接字和流 其中套接字被关闭但不是流 是否有必要在关闭套接字之前关闭所有流 因为我收到 打开文件太多错误 这个错误是因为没有关闭流 关闭套接字也会自动关闭流吗 来自Socket Java
  • UICollectionView 装饰视图

    有人为 iOS 6 UICollectionView 实现了装饰视图吗 不可能 查找有关在网络上实现装饰视图的任何教程 基本上在我的应用程序中 我有多个部分 我只想在每个部分后面显示一个装饰视图 这应该很容易实现 但我没有运气 这让我发疯