在 UICollectionView 或 UITableView 中实现粘性单元格

2023-12-09

我要实现一个包含项目列表的表格,其中包括一个应始终显示在屏幕上的项目。因此,例如:

  • 您的列表中有 50 项
  • 您的“粘性”列表项是第 25 个
  • 您可能会同时在屏幕上显示 10 个项目
  • 无论您在列表中的位置如何,“粘性”列表应始终保持可见
  • 如果您的项目低于您在列表中的位置,它将显示在列表的底部
  • 如果您的项目位于之前的项目之间,则它应该显示在列表的顶部
  • 一旦您到达列表中项目的实际位置,它应该与列表的滚动一起移动

以下是为了更好地理解实施要求的图示:

3 screens. On 1st screen, 25th cell is stuck at bottom, overlapping other cells underneath. On 2nd screen, 25th screen is inline with the other cells. On 3rd screen, 25th cell is stuck at the top.

我们将很高兴提供有关如何实施的任何可能的想法、建议或建议。不幸的是,我未能找到任何有用的库或解决方案来解决这个问题。 UICollectionView 和 UITableView 对于这种情况都是可以接受的。

根据我的理解,粘性页眉或页脚在这种情况下不起作用,因为它们只涵盖了我需要的一半功能。

预先感谢您的评论和回答!


我很确定你实际上不可能让同一个实际细胞像那样粘在一起。不过,您可以通过自动布局技巧来创造粘性的错觉。基本上,我的建议是,您可以拥有与您想要“粘性”的单元格相同的视图,并将它们限制在粘性单元格的顶部,同时您的粘性单元格可见。如果你慢慢滚动,我能做到的最好的事情看起来并不那么完美。 (粘性单元格在捕捉到顶部或底部位置之前大部分会离开屏幕。我认为在相当正常的滚动速度下这并不明显。您的里程可能会有所不同。)

关键是设置一个表视图委托,以便您可以收到有关单元格何时出现或不出现在屏幕上的通知。

我已经包含了一个示例视图控制器。我确信我的示例代码在某些区域无法工作。 (例如,我没有处理堆叠多个“粘性”单元格或动态行高。此外,我将粘性单元格设置为蓝色,这样更容易看到粘性。)

为了运行示例代码,您应该能够将其粘贴到 Xcode 在创建新的 UIKit 应用程序时生成的默认项目中。只需用这个替换他们给你的视图控制器即可看到它的实际效果。

import UIKit

struct StickyView {
    let view: UIView
    let constraint: NSLayoutConstraint
}

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    lazy var stickyViewConstraints = [Int: StickyView]()
    
    lazy var tableView: UITableView = {
        let table = UITableView()
        table.translatesAutoresizingMaskIntoConstraints = false
        table.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        table.rowHeight = 40
        table.dataSource = self
        table.delegate = self
        return table
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        addTable()
        setupStickyViews()
    }
    
    private func addTable() {
        view.addSubview(tableView)
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
    
    private func setupStickyViews() {
        let cell25 = UITableViewCell()
        cell25.translatesAutoresizingMaskIntoConstraints = false
        cell25.backgroundColor = .blue
        cell25.textLabel?.text = "25"
        view.addSubview(cell25)
        cell25.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        cell25.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
        cell25.heightAnchor.constraint(equalToConstant: tableView.rowHeight).isActive = true
        
        let bottom = cell25.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        bottom.isActive = true
        stickyViewConstraints[25] = StickyView(view: cell25, constraint: bottom)
    }

    // MARK: - Data Source
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return section == 0 ? 50 : 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = "\(indexPath.row)"
        return cell
    }
    
    // MARK: - Delegate
    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        guard let stickyView = stickyViewConstraints[indexPath.row] else { return }
        stickyView.constraint.isActive = false
        var verticalConstraint: NSLayoutConstraint
        if shouldPlaceStickyViewAtTop(stickyRow: indexPath.row) {
            verticalConstraint = stickyView.view.topAnchor.constraint(equalTo: view.topAnchor)
        } else {
            verticalConstraint = stickyView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        }
        verticalConstraint.isActive = true
        stickyViewConstraints[indexPath.row] = StickyView(view: stickyView.view, constraint: verticalConstraint)
    }
    
    private func shouldPlaceStickyViewAtTop(stickyRow: Int) -> Bool {
        let visibleRows = tableView.indexPathsForVisibleRows?.map(\.row)
        guard let min = visibleRows?.min() else { return false }
        return min > stickyRow
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if let stickyView = stickyViewConstraints[indexPath.row] {
            stickyView.constraint.isActive = false
            let bottom = stickyView.view.bottomAnchor.constraint(equalTo: cell.bottomAnchor)
            bottom.isActive = true
            stickyViewConstraints[indexPath.row] = StickyView(view: stickyView.view, constraint: bottom)
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 UICollectionView 或 UITableView 中实现粘性单元格 的相关文章

  • 在 Swift 中有条件导入基于 iOS 版本的框架(如 Speech)?

    有没有办法有条件地导入框架Swift基于运行时 iOS 版本 特别是 我有一个部署目标为的应用程序iOS 8 我想使用新的Apple Speech应用程序中的框架 如果在运行时可用 我知道 available iOS 10 代码部分的指令
  • 在phonegap中播放本地声音

    我有一个 wav文件在我的www文件夹 我正在使用 jQuery 和以下代码 警报响起 但声音不播放 难道我做错了什么
  • 如何在气隙 Mac 上安装新的 Apple 全球开发者关系中级证书?

    您可能知道也可能不知道 现在使用新的中间证书生成新的签名证书 你可以在这里读到它 https developer apple com support wwdr intermediate certificate https developer
  • 使用 Swift 访问 Twitter

    我正在使用 Swifter 库在我的 Swift iOS 8 应用程序中访问 Twitter https github com mattdonnelly Swifter https github com mattdonnelly Swift
  • 如何在ios开发中从mp3文件中提取元数据

    我正在开发一个带有云存储的 ios 音乐播放器 我需要提取音乐信息 如标题 艺术家 艺术作品 我有一个名为 playit 的操作 可以播放和暂停 mp3 文件 它还应该使用与 mp3 文件关联的元数据来填充一些 UILables 和 UII
  • 如何在 Alamofire 中使用“responseDecodable”方法?

    I have been trying to use responseDecodable method from Alamofire but I m getting Generic parameter T could not be infer
  • iOS8 自签名证书已安装但仍不受信任

    由于我无法控制的原因 我需要使用自签名证书针对平台进行 iOS 开发 它是一个在 SAN 中具有特定 IP 地址的根证书 当证书安装在 OSX 系统帐户下时 所有浏览器现在将正常信任对给定 IP 地址的任何访问 通过电子邮件将同一证书发送到
  • 如何在 iOS 中创建多行表格单元格?

    如何让第二个单元格扩展以适合文本而不是缩放文本 iOS 中有内置的方法可以做到这一点 还是我必须想出一些自制的解决方案 如果您查看 iOS 联系人应用程序 会发现有一个类似地址的框 但我找不到如何实现这一点 对于任何希望将来实现这一目标的人
  • 每次打开应用程序时,FileManager 的路径 URL 都不同[重复]

    这个问题在这里已经有答案了 我想在fileManager根路径中创建一个文件夹 但在创建之前 我想检查该文件夹是否存在 如果不存在 我将创建 否则将保留它 这是我使用的功能 public func isDirectoryExist path
  • 使用 HTTP NSURL 创建 AVAsset

    我正在尝试合并两个NSURLs包含视频参考 其中一个 URL 指向 AWS 上的视频 另一个 URL 指向本地存储的视频 我的导出代码有效 因为我已经尝试使用两个本地视频 但每当我尝试合并 HTTP url 和本地 url 时 我都会收到此
  • 尽早检测有问题的 XIB 视图

    我的笔尖名称有一个拼写错误 当我推向导航控制器时 它在代码中被破坏了 弄清楚它并没有花太长时间 但我认为最好尽早断言格式良好 以便更容易弄清楚 问题是它不是零 它只是无法从笔尖正确地形成自己 在 initWithNib 之后是否有更好的断言
  • 将时间舍入到最接近的三十秒

    我有一个应用程序 它显示每 30 秒过期的数据 准确地说 在 h m s 11 30 00 11 30 30 11 31 00 等 我可以获得当前时间 但我不确定如何计算现在到最近的三十秒之间的时间 我发现的所有内容都是 Objective
  • 如何使用 SwiftUI 使按钮可拖动/可移动?

    我正在尝试使用 SwiftUI 制作一个可移动的按钮 从看起来这应该可行 我尝试将带有文本的按钮放入另一个 ZStack 中 有一秒钟它可以工作 但一旦我释放按钮 拖动就会停止 我无法再拖动 我注意到尽管按钮已经移动 但水龙头仍然位于中心
  • tableView.cellForRowAtIndexPath(indexPath) 返回 nil

    我有一个循环遍历表视图的验证函数 问题是它在某个时刻返回 nil 单元格 for var section 0 section lt self tableView numberOfSections section for var row 0
  • FIRApp 链接器错误 [“_OBJC_CLASS_$_FIRApp”]

    我已经搜索过 SO 和 Google 但找不到有效的答案 我已经在多个项目中使用了新的 Firebase Cocoapod 但是现在 当将其添加到不同的项目时 我收到以下错误 我正在使用 Xcode 7 3 1 和 cocoapods 1
  • 辅助功能标识符在 iOS 模拟器的辅助功能检查器中不可见

    我想使用辅助功能检查器来验证在模拟器 iOS 9 2 中运行的应用程序中的所有辅助功能标识符 辅助功能检查器能够返回多个辅助功能字段 但不能返回标识符 知道为什么以及如何我能看到它们吗 实际上有一种方法 克里斯 普林斯 Chris Prin
  • SwiftUI 自动调整底部工作表的大小

    SwiftUI 有很多底部工作表的示例 但是它们都指定了使用 GeometryReader 工作表可以增长到的某种类型的最大高度 我想要的是创建一个底部工作表 其高度仅与其中的内容一样高 我使用首选项键提出了下面的解决方案 但必须有更好的解
  • 出现错误:FT_Open_Face 失败:错误 2

    当我使用时出现以下错误CGContextDrawPDFPage context PDFPage 对于某些文件 有解决办法来解决这个问题吗 FT Open Face failed error 2 错误2看起来像errno2 这是 找不到文件
  • ios swift 如何将默认语言设置为阿拉伯语?

    我正在开发一个有两种语言的应用程序 即英语和阿拉伯语 我用英语编写了该应用程序 然后用阿拉伯语本地化了该应用程序 更改语言时需要重新启动应用程序 我唯一的问题是 第一次安装应用程序时如何将默认语言设置为阿拉伯语 我尝试在编辑方案部分将语言设
  • 如何在 Swift 中将所有 iOS 设备的标签水平居中

    我不知道如何使标签在图像视图中水平居中 标签说 You ve been here What would you rate us 我想要What would you rate us属于 You ve been here 我试图完成此操作的方法

随机推荐

  • 如何使用数据工厂创建 Azure 按需 HD Insight Spark 集群

    我正在尝试使用 Azure 数据工厂使用 Hdi 版本 3 5 创建按需 HD Insight Spark 集群 数据工厂拒绝创建并显示错误消息 HdiVersion 不支持 3 5 如果目前无法创建按需 HD Insight Spark
  • 右键单击 jqGrid 时禁用行选择

    在 jqGrid 中 我当前使用以下命令禁用行选择 beforeSelectRow function return false 这对于左键单击效果很好 但是 我注意到它没有触发beforeSelectRow事件处理程序 并且当我右键单击时仍
  • CKeditor保存事件

    我按照本主题中写的步骤进行操作 CKEditor AJAX 保存如果有人按下 AjaxSave 按钮 我尝试触发自定义 saved ckeditor 事件 但我没有成功 ckeditor plugins ajaxsave plugin js
  • 等待 IE 文件下载完成的 VBA 代码

    我正在尝试从网页下载 Excel 文件 到目前为止 我能够打开网页 导航并单击 保存 按钮 但下载后我需要访问该 Excel 文件 但有时下载需要时间 具体取决于文件的大小 有什么方法可以检查窗口并查看下载是否完成 然后才能继续打开下载的文
  • 如何删除 BigQuery 中属于嵌套列的列

    我想删除 BigQuery 表中属于记录或嵌套列的列 我在他们的中找到了这个命令文档 不幸的是 此命令不适用于现有 RECORD 字段内的嵌套列 有什么解决方法吗 例如 如果我有这个架构 我想删除地址字段内的 address2 字段 所以由
  • 拦截 ESC 而不从缓冲区中删除其他按键

    我有一个控制台应用程序 提示用户进行多个输入 我希望用户能够在出现任何取消操作的提示后按转义键 就像是 if Console ReadKey Key ConsoleKey Escape string input Console ReadLi
  • 时间:2019-03-17 标签:c#updatepanelwithtimerpage_load

    我现在正在尝试一些 AJAX 我有一个自定义控件出现在我的母版页上 其中有一个更新面板和一个计时器 计时器启动 面板更新 一切都很顺利 除了我不希望它在每次刷新时执行一些操作之外 似乎每次刷新都会发生整个页面生命周期 我想设置一些变量 并在
  • 指数维护

    什么是索引维护以及如何进行 我需要多久做一次 有什么好处 这与经常修改的事务表有关 所有 DML 操作都将在该表上运行 我赞同乔纳森所说的一切 除了索引维护的频率 好吧 如果您碰巧有一个设计不佳的索引 例如 GUID 键上的聚集索引 您实际
  • 将 CURDATE() 的日期值与完整时间戳字段进行比较

    我有一个函数将时间戳值 YYYY MM DD HH MM SS 放入META VALUE表的列META 我想要做的是比较日期部分 YYYY MM DD 是否META VALUE等于今天 CURDATE 忽略小时 分钟和秒 HH MM SS
  • 尝试访问 Rails 控制台时 git 远程中的多个应用程序

    我有两个 git 分支 staging and production 我将它们部署在 Heroku 上的同一个 Heroku 帐户中 假设我的应用程序名称是app1 heroku app com and app2 heroku app co
  • 如何使用 ggplot2 在 R 中添加可变大小的 y 轴标签而不更改绘图宽度?

    我有一个用 R 中的 ggplot2 制作的图 我想在 y 轴上添加水平文本标签 然而 根据文本的长度 R 会相应地压缩我的绘图以创建固定宽度的图像 但是 无论文本宽度如何 我都需要绘图具有相同的长度并且具有相同的起始位置和停止位置 边距
  • Selenium:会话外部密钥不可用

    每当 Robot Framework 自动化测试 由 Jenkins 作业启动 从 Hub 请求 Chrome 浏览器时 我正在运行的 Selenium Grid Hub 就会显示此错误消息 会话 null externalkey 不可用且
  • Selenium:是否有类似“DOM 中插入新元素”之类的事件

    我正在测试的网站有一个通知逻辑 它会在屏幕底部显示一条消息 将其保留一秒钟 然后将其发送出去 当显示通知时 它会隐藏其他元素 这使我的测试不稳定 我尽力弄清楚通知何时显示 当业务逻辑显示通知时 并忽略它 但时不时地我会检测到我的代码不知道通
  • 如何将项目添加到列表

    我的项目中有模型 这是模型代码 public partial class Logging public string Imei get set public DateTime CurDateTime get set public Nulla
  • 在 Outlook 中自动调整 VML 背景图像的大小

    我知道关于防弹电子邮件背景hack 但由于这会在背景中放置一个设定大小的 VML 矩形 然后将内容放置在其中 因此它不会调整大小 或者换句话说 表格单元格中的文本被裁剪为 VML 矩形的高度 我已经尝试了我能想到的一切 但似乎无论如何都不允
  • 创建新实体时不会自动生成相对路由

    当我使用命令 jhipster实体 entityName 创建新实体时 相对路径不会在我的 entityName route ts中自动生成 相反 在主路线的地方我有这个 而不是 实体名称 另外 所有添加 更新 删除的路由也不包含前缀 en
  • AChartEngine不显示最大图表值

    我正在尝试使用 AChartEngine 显示水平条形图 在条形图中 应显示 ChartValues 我在代码中使用 XYSeriesRenderer setDisplayChartValues true 以下是渲染的图表 正如您所看到的
  • 使用 QTcpSocket 的 TCP 数据包

    我知道 TCP 保证所有数据包都会到达 但是一个数据包可以分成2个或更多吗 我正在使用 Qt 和 QTcpSocket 类 我想知道的是ReadyRead 仅当完整数据包到达时才会发出信号 或者换句话说 以第一个字节发送数据包大小 然后循环
  • 来自资源包的值作为 formatDate 中的模式

    我也想从资源包中读取 JST formatDate 的模式 但这种天真的方法不起作用 我做错了什么 在 com company MyPortlet properties 中是这个键 company date format yyyy MM d
  • 在 UICollectionView 或 UITableView 中实现粘性单元格

    我要实现一个包含项目列表的表格 其中包括一个应始终显示在屏幕上的项目 因此 例如 您的列表中有 50 项 您的 粘性 列表项是第 25 个 您可能会同时在屏幕上显示 10 个项目 无论您在列表中的位置如何 粘性 列表应始终保持可见 如果您的