如何在UITableView透明标题下面屏蔽UITableViewCells

Jes*_*mpo 30 iphone objective-c ios

我希望标题掩盖单元格,但不是背景.

我有一个带有透明标题的UITableView和类似于Apple的通知中心的单元格(当你向下滑动iPhone上的状态栏时).我无法弄清楚如何屏蔽单元格,以便在滚动时它们不会显示在标题下方.

我已经尝试更改tableview的contentInsets,并且我已经尝试将标题View的框架更改为负面原点.

Ale*_*man 65

尝试创建子类UITableviewCell并添加这些方法

- (void)maskCellFromTop:(CGFloat)margin {
    self.layer.mask = [self visibilityMaskWithLocation:margin/self.frame.size.height];
    self.layer.masksToBounds = YES;
}

- (CAGradientLayer *)visibilityMaskWithLocation:(CGFloat)location {
    CAGradientLayer *mask = [CAGradientLayer layer];
    mask.frame = self.bounds;
    mask.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:1 alpha:0] CGColor], (id)[[UIColor colorWithWhite:1 alpha:1] CGColor], nil];
    mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:location], [NSNumber numberWithFloat:location], nil];
    return mask;
}
Run Code Online (Sandbox Code Playgroud)

并添加此委托方法 UITableView

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    for (iNotifyTableViewCell *cell in self.visibleCells) {
        CGFloat hiddenFrameHeight = scrollView.contentOffset.y + [iNotifyHeaderView height] - cell.frame.origin.y;
        if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) {
            [cell maskCellFromTop:hiddenFrameHeight];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

*注意[iNotifyHeaderView height]是高度HeaderView.并#import <QuartzCore/QuartzCore.h>用于自定义单元格.

  • @AlexMarkman谢谢你,完美地运作.我将tableView的`contentInset`属性的顶部添加到你正在计算的`hiddenFrameHeight`中,以考虑iOS 7添加到scrollViews的自动插入,以及刷新控件添加的任何空间等:`CGFloat hiddenFrameHeight = scrollView.contentOffset .y + [iNotifyHeaderView height] - cell.frame.origin.y + scrollView.contentInset.top;` (5认同)
  • 我还将此代码添加到UITableViewCell的`maskCellFromTop:`方法以提高性能(如果margin不适合当前单元格,则删除掩码)`if(margin> 0){self.layer.mask = [self visibilityMaskWithLocation:margin/self. frame.size.height]; self.layer.masksToBounds = YES; } else {self.layer.mask = nil; }` (4认同)

Ant*_*ine 16

对Alex Markman的答案进行一点编辑,您可以跳过为UITableViewCell创建子类.这种方法的好处是您可以将它用于多个不同的UITableViewCell.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    for (UITableViewCell *cell in self.tableView.visibleCells) {
        CGFloat hiddenFrameHeight = scrollView.contentOffset.y + self.navigationController.navigationBar.frame.size.height - cell.frame.origin.y;
        if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) {
            [self maskCell:cell fromTopWithMargin:hiddenFrameHeight];
        }
    }
}

- (void)maskCell:(UITableViewCell *)cell fromTopWithMargin:(CGFloat)margin
{
    cell.layer.mask = [self visibilityMaskForCell:cell withLocation:margin/cell.frame.size.height];
    cell.layer.masksToBounds = YES;
}

- (CAGradientLayer *)visibilityMaskForCell:(UITableViewCell *)cell withLocation:(CGFloat)location
{
    CAGradientLayer *mask = [CAGradientLayer layer];
    mask.frame = cell.bounds;
    mask.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:1 alpha:0] CGColor], (id)[[UIColor colorWithWhite:1 alpha:1] CGColor], nil];
    mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:location], [NSNumber numberWithFloat:location], nil];
    return mask;
}
Run Code Online (Sandbox Code Playgroud)


kow*_*wal 11

@Alex Markman - 你的答案很棒,对我来说非常有用,但我发现当你滚动视网膜设备时,细胞不能平滑滚动.我发现它是由locations渲染过程中的图层参数引起的:

mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:location];

我稍微修改了你的代码.也许有人会发现它很有用:

- (void)maskCellFromTop:(CGFloat)margin
{
    self.layer.mask = [self visibilityMaskFromLocation:margin];
    self.layer.masksToBounds = YES;
}

- (CAGradientLayer *)visibilityMaskFromLocation:(CGFloat)location
{
    CAGradientLayer *mask = [CAGradientLayer layer];
    mask.frame = CGRectMake(
                            self.bounds.origin.x,
                            location+self.bounds.origin.y,
                            self.bounds.size.width,
                            self.bounds.size.height-location);
    mask.colors = @[
                    (id)[[UIColor colorWithWhite:1 alpha:1] CGColor],
                    (id)[[UIColor colorWithWhite:1 alpha:1] CGColor]
                    ];
    return mask;
}
Run Code Online (Sandbox Code Playgroud)


Sho*_*aib 5

Swift版本

func scrollViewDidScroll(_ scrollView: UIScrollView) { 
    for cell in tableView.visibleCells {
        let hiddenFrameHeight = scrollView.contentOffset.y + navigationController!.navigationBar.frame.size.height - cell.frame.origin.y
        if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) {
            maskCell(cell: cell, margin: Float(hiddenFrameHeight))
        }
    }
}

func maskCell(cell: UITableViewCell, margin: Float) {
    cell.layer.mask = visibilityMaskForCell(cell: cell, location: (margin / Float(cell.frame.size.height) ))
    cell.layer.masksToBounds = true
}

func visibilityMaskForCell(cell: UITableViewCell, location: Float) -> CAGradientLayer {
    let mask = CAGradientLayer()
    mask.frame = cell.bounds
    mask.colors = [UIColor(white: 1, alpha: 0).cgColor, UIColor(white: 1, alpha: 1).cgColor]
    mask.locations = [NSNumber(value: location), NSNumber(value: location)]
    return mask;
}
Run Code Online (Sandbox Code Playgroud)


Set*_*hmr 5

清洁 Swift 3 版本:

extension YourViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        for cell in tableView.visibleCells {
            let hiddenFrameHeight = scrollView.contentOffset.y + navigationController!.navigationBar.frame.size.height - cell.frame.origin.y
            if (hiddenFrameHeight >= 0 || hiddenFrameHeight <= cell.frame.size.height) {
                if let customCell = cell as? CustomCell {
                    customCell.maskCell(fromTop: hiddenFrameHeight)
                }
            }
        }
    }
}

class CustomCell: UITableViewCell {
    public func maskCell(fromTop margin: CGFloat) {
        layer.mask = visibilityMask(withLocation: margin / frame.size.height)
        layer.masksToBounds = true
    }

    private func visibilityMask(withLocation location: CGFloat) -> CAGradientLayer {
        let mask = CAGradientLayer()
        mask.frame = bounds
        mask.colors = [UIColor.white.withAlphaComponent(0).cgColor, UIColor.white.cgColor]
        let num = location as NSNumber
        mask.locations = [num, num]
        return mask
    }
}
Run Code Online (Sandbox Code Playgroud)

我刚刚使用了这个,它就像一个魅力。我要感谢帖子里的每一个人!各地投票!