- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在改进 UITableView 的滚动时遇到了问题,它的自定义单元格是使用自动布局布局的。我有两种不同高度的自定义 UITableViewCell(一种大约 200px,一种大约 500px)我尝试了很多东西,包括:
cellForRowAt
移至 willDisplayCell
以及遵循许多声称可以提高滚动速度的在线指南。然而,滚动仍然生涩!
此外,当我尝试滚动到顶部单元格时,它有时无法到达顶部。我想估计的单元格高度与此有关,但由于单元格的高度各不相同,因此很难做到正确。
仪器表明,当我将文本设置到我的单元格标签中时,我的代码速度变慢(这是调整单元格高度的位)。
我正在尝试弄清楚 Twitter 应用程序(它与我的 UITableView 具有基本相同的功能,具有属性文本和图像等)如何具有如此出色的滚动效果。我不久前看到他们的一篇博客文章说如何对所有内容使用 drawRect,但是,我很确定他们现在不会那样做。有人对他们如何实现 60fps 的平滑滚动有任何见解吗?
所以首先我的两个表格单元格具有以下结构:
表格单元格 1:
- UITableViewCell
- UIView (content view)
- UIView (Shadow view)
- UIView (Card background)
- UIView x 3
- UIButton x 5
- UILabel x 2
- UITextView
我将 UIView 称为 shadow view
和 card background
的原因是我将 shadowPath
添加到 shadow view
s 层,它是一个 UIBezierPath
。然后我将半径添加到 card background
。这两个不能在同一层上完成,因为半径仅在两个角中,并且在尝试同时具有阴影和半径时会出现问题。
表格单元格 2:
- UITableViewCell
- UIView (content view)
- UIView (Shadow view)
- UIView (Card background)
- UIView x 3
- UIButton x 5
- UILabel x 3
- UITextView
- UIImageView x 2
这使用相同的代码来添加阴影和圆角。
要获取行的估计高度,我使用以下代码:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
let type = model.dataContent[indexPath.row]["type"].stringValue
if type == MediaType.text.rawValue {
return 150
} else {
return 500
}
}
在我的 UITableViewController 的 cellForRowAt
中,我有以下代码:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Create the custom cell
let mediaTableCellIdentifier = "MediaCell"
let textTableCellIdentifier = "TextCell"
let type = MediaType(rawValue: model.dataContent[indexPath.row]["type"].stringValue)
var cell: TableCell!
if type == .text {
cell = tableView.dequeueReusableCell(withIdentifier: textTableCellIdentifier, for: indexPath) as! TableTextCell
if flowState == .individualPost {
(cell as! TableTextCell).expandView()
}
} else {
cell = tableView.dequeueReusableCell(withIdentifier: mediaTableCellIdentifier, for: indexPath) as! TableMediaCell
(cell as! TableMediaCell).postImageView.image = nil
}
cell.delegate = self
if type == .image {
let cell = cell as! TableMediaCell
let urlString = model.dataContent[indexPath.row]["img"]["loc"].stringValue
// Check if we have an image stored in our cache for the image URL. If not, download it.
if let cellImage = model.imageCache[urlString] {
cell.postImageView.image = cellImage
}
else {
model.downloadImage(
atIndexPath: indexPath,
type: type!,
progress: { percentage in
cell.progressView.isHidden = false
cell.progressView.updateCirclePath(percentage: percentage)
},
completion: { [weak self] error, image in
if let strongSelf = self {
if error == nil {
// Store the image in to our cache
strongSelf.model.imageCache[urlString] = image
// Update the cell with our image
if let cellToUpdate = tableView.cellForRow(at: indexPath) as? TableMediaCell {
cellToUpdate.postImageView.image = image
cellToUpdate.progressView.resetCircleAnimation()
cellToUpdate.progressView.isHidden = true
}
}
else {
print("Error downloading image: \(error!.localizedDescription)")
}
}
}
)
}
} else if type == .video {
let cell = cell as! TableMediaCell
let urlString = "\(CloudFrontURL.video.rawValue)/\(model.dataContent[indexPath.row]["video"]["loc"].stringValue)"
if let cellVideo = model.videoCache[urlString] {
cell.videoPlayer = AVPlayer(playerItem: AVPlayerItem(asset: cellVideo))
cell.videoPlayer!.actionAtItemEnd = AVPlayerActionAtItemEnd.none
cell.videoView.playerLayer.player = cell.videoPlayer
} else {
let videoURL = URL(string: urlString)
cell.videoPlayer = AVPlayer(url: videoURL!)
model.videoCache[urlString] = cell.videoPlayer?.currentItem?.asset
cell.videoPlayer!.actionAtItemEnd = AVPlayerActionAtItemEnd.none
cell.videoView.playerLayer.player = cell.videoPlayer
}
}
cell.caption.text = model.dataContent[indexPath.row]["caption"].stringValue
cell.caption.isHidden = true
model.retrieveCaption(at: indexPath, forCell: cell, withFont: cell.caption.font!) { (caption, cellToUpdate) in
if let theCell = cellToUpdate {
theCell.caption.attributedText = caption
theCell.caption.isHidden = false
}
}
cell.commentCount.text = model.dataContent[indexPath.row]["commentsCount"].stringValue
// Enable/Disable the controls based on our settings
cell.controlsEnabled = controlsEnabled
// Provide each cell with our data
cell.model = model
// Setting this makes the controls update its data automatically.
cell.indexPath = indexPath
// If we've reached the last post in our loaded data, get the next page of posts (unless it's an individual post).
if (indexPath.row == model.dataContent.count - 3 && !lastItemReached && flowState != .individualPost) {
stateMachine.enterState(.retrievingNextPage)
}
return cell
}
当我设置两个 UITableViewCells 的 indexPath 时,将在自定义单元格类中调用此代码以更新单元格:
var indexPath: IndexPath {
get {
// Return the internalIndexPath when we ask for the indexPath.
return internalIndexPath
}
set {
// Set the internalIndexPath to the value supplied to indexPath.
internalIndexPath = newValue
// Calculate the number of points on a post.
let points = model.dataContent[self.indexPath.row]["upVotes"].intValue - model.dataContent[self.indexPath.row]["downVotes"].intValue
pointsLabel.text = "\(points)"
// Show the upload time of the post.
let uploadTimeString = model.dataContent[self.indexPath.row]["timestamp"].stringValue
let date = DateFormatter.formatter.date(from: uploadTimeString)
let dateString = date?.relativeTime
uploadTime.text = dateString
if let type = MediaType(rawValue: model.dataContent[self.indexPath.row]["type"].stringValue) {
self.type = type
}
/// Adjust up/down arrows
if (model.dataContent[self.indexPath.row]["userVote"]["likeState"] != nil) {
switch model.dataContent[self.indexPath.row]["userVote"]["likeState"].stringValue {
case LikeState.Likes.rawValue:
thumbsUpButton.isSelected = true
thumbsDownButton.isSelected = false
case LikeState.Dislikes.rawValue:
thumbsUpButton.isSelected = false
thumbsDownButton.isSelected = true
case LikeState.Neither.rawValue:
thumbsUpButton.isSelected = false
thumbsDownButton.isSelected = false
default:
break
}
} else {
thumbsUpButton.isSelected = false
thumbsDownButton.isSelected = false
}
}
}
最佳答案
您的 UITableView
显示缓慢的一个非常明显的原因是您的 cellForRowAtIndexPath
太长了。你需要重构你的代码。保持 Cell 声明本身简短。
最好的做法是在 cellForRowAtIndexPath
中声明 Cell,并调用一个 bindData
函数来用内容填充 Cell。例如:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! Cell
let content = contentArray[indexPath.row]
cell.bindData(content)
return cell
}
}
extension Cell {
bindData(content: ContentStruct) {
label.text = content.name
}
}
同样在您的情况下,您应该在设置内容的函数和设置属性的函数之间进行重构。让每个功能更短。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as! Cell
let content = contentArray[indexPath.row]
cell.bindData(content)
cell.setProperties
return cell
}
}
extension Cell {
bindData(content: ContentStruct) {
label.text = content.name
}
setProperties() {
// set stuff like:
// Enable/Disable the controls based on our settings
cell.controlsEnabled = controlsEnabled
// Provide each cell with our data
cell.model = model
// Setting this makes the controls update its data automatically.
cell.indexPath = indexPath
// If we've reached the last post in our loaded data, get the next page of posts (unless it's an individual post).
if (indexPath.row == model.dataContent.count - 3 && !lastItemReached && flowState != .individualPost) {
stateMachine.enterState(.retrievingNextPage)
}
}
}
关于ios - Twitter 让 UITableView 滚动流畅的技巧是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40112211/
如果附加了 'not-scroll' 类,我希望我的 body 不滚动,否则它应该正常工作。 我已经搜索这个问题两天了,但找不到任何适合我的解决方案。 我想要的是向 body 添加一个 class,并
我发现似乎是 iOS Safari 中的错误(我正在 iOS 8 上进行测试)。当绝对定位的 iFrame 漂浮在一段可滚动内容上方时,滚动 iFrame 也会滚动下面的内容。以下 HTML (ava
我有以下代码来显示一系列投资组合图片,这些图片以 SVG 格式存储在滚动 div 中: 在 Safari 中滚动使用两根手指或鼠标滚轮当光标位于 SVG 之一上时不起作用。 该页
我想用 javascript 做的是: 一旦你向下滚动页面,将#sidebar-box-fixed 的位置从 position: relative; 更改为定位:固定;。改回position:rela
我对 Elasticsearch 的滚动功能有点困惑。在 elasticsearch 中,每当用户在结果集上滚动时,是否可以每次调用搜索 API?来自文档 "search_type" => "scan
我试图做到这一点,以便当我向上或向下滚动页面时,它会运行不同的相应功能。我发现了一个类似的问题here但我已经尝试了他们的答案并且没有运气。 注意:此页面没有正常显示的滚动条。没有地方可以滚动。 bo
(C语言,GTK库) 在我的表单上,我有一个 GtkDrawingArea 小部件,我在上面使用 Cairo 绘制 GdkPixbufs(从文件加载)。我想要完成的是能够在窗口大小保持固定的情况下使用
最近我一直在尝试创建一个拉到(刷新,加载更多)swiftUI ScrollView !!,灵感来自 https://cocoapods.org/pods/SwiftPullToRefresh 我正在努
我正在开发一个应用程序,其中有两个带有可放置区域的列表和一个带有可拖动项目的侧面菜单。 当我滚动屏幕时,项目的位置困惑。 我试图在谷歌上寻找一些东西,最后得到了这个问题:jQuery draggabl
我在 UIWebView 中加载了一个 HTML 表单,而我的 UIWebView 恰好从 View 的中间开始并扩展。我必须锁定此 webView 不滚动并将其放在 ScrollView 之上以允许
如何在每个元素而不是整个元素上应用淡入淡出(与其高度相比)? HTML: CSS: * { padding: 0; margin: 0; box-sizing: border
我想使用带有垂直轴的 PageView 并使用鼠标滚动在页面之间移动,但是当我使用鼠标滚动时页面不滚动...仅页面单击并向上/向下滑动时滚动。 有什么办法吗? 我想保留属性 pageSnapping:
我制作这个程序是为了好玩,但我被卡住了,因为程序在屏幕外运行。如何在不完全更改代码的情况下实现滚动条。 public static void main(String args[]) throws IO
我想使用带有垂直轴的 PageView 并使用鼠标滚动在页面之间移动,但是当我使用鼠标滚动时页面不滚动...仅页面单击并向上/向下滑动时滚动。 有什么办法吗? 我想保留属性 pageSnapping:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
使用 jquery 技术从 css-tricks.com 获得滚动/跟随侧边栏,如果您不知道我在说什么,这里是代码: $(function() { var $sidebar = $
我是 jQuery Mobile 新手。我需要向我的应用程序添加 Facebook 滑动面板功能。 我经历了 sliding menu panel ,它工作正常,但我在菜单面板中的内容超出了窗口大小,
有没有办法在 js 或 jQuery 或任何其他工具中检测 ctrl + 滚动。我正在尝试执行一些动态布局代码,我需要检测不同分辨率下的屏幕宽度,我通过使用 setTimeout() 的计时器实现了这
我有一部分html代码:
我想控制 RichTextBox 滚动,但在控件中找不到任何方法来执行此操作。 这样做的原因是我希望当鼠标光标位于 RichTextBox 控件上时鼠标滚轮滚动有效(它没有事件焦点:鼠标滚轮事件由表单
我是一名优秀的程序员,十分优秀!