[英]ios uitableview fade bottom cell and top cell as you scroll
我在 uitableview 的单元格滚动出视图时淡出它们,或者在它们滚动到视图中时淡出它们。 我面临的问题是,如果我滚动得非常快,有时完全可见的单元格会变暗。 这是我的代码如下:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Fades out top and bottom cells in table view as they leave the screen
NSArray *visibleCells = [self.tableView visibleCells];
if (visibleCells != nil && [visibleCells count] != 0) { // Don't do anything for empty table view
/* Get top and bottom cells */
UITableViewCell *topCell = [visibleCells objectAtIndex:0];
UITableViewCell *bottomCell = [visibleCells lastObject];
/* Make sure other cells stay opaque */
// Avoids issues with skipped method calls during rapid scrolling
for (UITableViewCell *cell in visibleCells) {
cell.contentView.alpha = 1.0;
}
/* Set necessary constants */
NSInteger cellHeight = topCell.frame.size.height - 1; // -1 To allow for typical separator line height
NSInteger tableViewTopPosition = self.tableView.frame.origin.y;
NSInteger tableViewBottomPosition = self.tableView.frame.origin.y + self.tableView.frame.size.height;
/* Get content offset to set opacity */
CGRect topCellPositionInTableView = [self.tableView rectForRowAtIndexPath:[self.tableView indexPathForCell:topCell]];
CGRect bottomCellPositionInTableView = [self.tableView rectForRowAtIndexPath:[self.tableView indexPathForCell:bottomCell]];
CGFloat topCellPosition = [self.tableView convertRect:topCellPositionInTableView toView:[self.tableView superview]].origin.y;
CGFloat bottomCellPosition = ([self.tableView convertRect:bottomCellPositionInTableView toView:[self.tableView superview]].origin.y + cellHeight);
/* Set opacity based on amount of cell that is outside of view */
CGFloat modifier = 1.2; /* Increases the speed of fading (1.0 for fully transparent when the cell is entirely off the screen,
2.0 for fully transparent when the cell is half off the screen, etc) */
CGFloat topCellOpacity = (1.0f - ((tableViewTopPosition - topCellPosition) / cellHeight) * modifier);
CGFloat bottomCellOpacity = (1.0f - ((bottomCellPosition - tableViewBottomPosition) / cellHeight) * modifier);
/* Set cell opacity */
if (topCell) {
topCell.alpha = topCellOpacity;
}
if (bottomCell) {
bottomCell.alpha = bottomCellOpacity;
}
}
}
知道为什么当我快速滚动时,视图中的单元格有时会变暗吗?
问题是滚动事件不会总是发生得足够频繁,以至于当它从顶部/底部滚动到中间时,滚动到视图中的单元格将从褪色的 alpha 变为 1.0 的 alpha。 但是,当您真正快速滚动时,不会频繁调用scrollViewDidScroll
以确保确实如此。 而您显然试图重置alpha
的循环正在更新错误视图的alpha
( contentView
而不是单元格本身)。
您可以通过替换现有的for
循环来解决此问题:
for (UITableViewCell *cell in visibleCells) {
cell.contentView.alpha = 1.0;
}
和
for (UITableViewCell *cell in visibleCells) {
cell.alpha = 1.0;
}
或者,从那里消除该循环,然后替换设置顶部和底部单元格的 alpha 的行:
if (topCell) {
topCell.alpha = topCellOpacity;
}
if (bottomCell) {
bottomCell.alpha = bottomCellOpacity;
}
和:
for (UITableViewCell *cell in self.tableView.visibleCells) {
if (cell == topCell) {
cell.alpha = topCellOpacity;
} else if (cell == bottomCell) {
cell.alpha = bottomCellOpacity;
} else {
cell.alpha = 1.0;
}
}
顺便说一句,实现类似效果的另一种方法是将渐变蒙版应用到整个 tableview 并scrollViewDidScroll
方法。 这里唯一的技巧是你不能将渐变蒙版应用到表格视图本身(否则渐变会随着表格视图滚动),而是将表格视图放在某个容器UIView
,然后将蒙版应用到它:
- (void)viewDidAppear:(BOOL)animated
{
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.containerView.bounds;
gradient.colors = @[(id)[UIColor clearColor].CGColor,
(id)[UIColor whiteColor].CGColor,
(id)[UIColor whiteColor].CGColor,
(id)[UIColor clearColor].CGColor];
gradient.locations = @[@0.0, @0.1, @0.9, @1.0];
self.containerView.layer.mask = gradient;
}
诚然,这是一种略有不同的效果,但有时它是可取的。 这仅取决于您要拍摄的内容。
这是您如何为 Swift 4 执行此操作
extension UITableView {
func fadeEdges(with modifier: CGFloat) {
let visibleCells = self.visibleCells
guard !visibleCells.isEmpty else { return }
guard let topCell = visibleCells.first else { return }
guard let bottomCell = visibleCells.last else { return }
visibleCells.forEach {
$0.contentView.alpha = 1
}
let cellHeight = topCell.frame.height - 1
let tableViewTopPosition = self.frame.origin.y
let tableViewBottomPosition = self.frame.maxY
guard let topCellIndexpath = self.indexPath(for: topCell) else { return }
let topCellPositionInTableView = self.rectForRow(at:topCellIndexpath)
guard let bottomCellIndexpath = self.indexPath(for: bottomCell) else { return }
let bottomCellPositionInTableView = self.rectForRow(at: bottomCellIndexpath)
let topCellPosition = self.convert(topCellPositionInTableView, to: self.superview).origin.y
let bottomCellPosition = self.convert(bottomCellPositionInTableView, to: self.superview).origin.y + cellHeight
let topCellOpacity = (1.0 - ((tableViewTopPosition - topCellPosition) / cellHeight) * modifier)
let bottomCellOpacity = (1.0 - ((bottomCellPosition - tableViewBottomPosition) / cellHeight) * modifier)
topCell.contentView.alpha = topCellOpacity
bottomCell.contentView.alpha = bottomCellOpacity
}
}
这就是你将如何称呼它...
你像这样在scrollViewDidScroll
方法中调用它......
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
tableView.fadeEdges(with: 1.0)
}
修改器增加淡入淡出的速度(例如,当单元格完全离开屏幕时,1.0 表示完全透明,当单元格位于屏幕的一半时,2.0 表示完全透明。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.