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

时间:2012-08-26 02:13:39

标签: iphone objective-c ios

我希望标题能够屏蔽单元格,而不是背景。

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

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

10 个答案:

答案 0 :(得分:64)

尝试创建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;
}

并在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];
        }
    }
}

*请注意,[iNotifyHeaderView height]HeaderView的高度。并使用#import <QuartzCore/QuartzCore.h>作为自定义单元格。

答案 1 :(得分:16)

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

- (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;
}

答案 2 :(得分: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;
}

答案 3 :(得分: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;
}

答案 4 :(得分:4)

Clean 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
    }
}

我刚刚使用它,它就像一个魅力。我要感谢帖子中的每个人!四处投票!

答案 5 :(得分:0)

我有两个可能的解决方案,没有代码 - 只是想法:

  1. 不是通用的,应该与申请中心使用的设置/设计一起使用。
  2. 使Section-Header不透明,'克隆'表格的背景图案作为section-Header的背景。根据节标题偏移量定位背景图案。


    1. genereic,但可能是更多的性能问题。用很少的细胞就可以正常工作。
    2. 为所有单元格图层添加Alpha蒙版。根据细胞位置移动Alpha Mask。


      (使用scrollViewDidScroll委托方法来维护背景图案/ Alpha-Mask偏移量。)

答案 6 :(得分:0)

我最终将节标题的高度设置为最小值,并覆盖UITableView的layoutSubviews,将标题放在tableView的超视图上,将帧的原点向上调整高度。

答案 7 :(得分:0)

Swift 3版本对我不起作用,因为我将UITableViewController添加为子视图。所以我不得不对scrollview的扩展进行一些更改。

这也适用于从另一个ViewController推送的UITableViewController(注意:未测试)

extension NavNotitionTableViewController {
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    for cell in tableView.visibleCells {

        let calculatedY = cell.frame.origin.y - scrollView.contentOffset.y;
        if let customCell = cell as? NavNotitionTableViewCell {

            if(calculatedY < 44 && calculatedY > 0){
                let hideAmount = 44 - calculatedY;

                if let customCell = cell as? NavNotitionTableViewCell {
                    customCell.maskCell(fromTop: hideAmount)
                }
            }else if (calculatedY > 0){
                //All other cells
                customCell.maskCell(fromTop: 0)
            }else if (calculatedY < 0){
                customCell.maskCell(fromTop: cell.frame.height);
            }
        }
    }
}
}

在这个例子中,我首先得到单元格的框架Y原点并分散scollViews contentOffsetY。

我的自定义部分的高度是44.所以我定义了蒙版的hideAmount值。

Cell函数不受影响:

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
}

答案 8 :(得分:0)

如果您想在表格视图后面显示内容,这将不起作用,但是,由于我只是试图创建带有纯色纯色背景的圆形标题,因此,解决该问题的方法是通过设置透明度标题背景视图的背景色与表格视图(或具有不透明背景的第一个父视图)的背景色。

答案 9 :(得分:-3)

或者,如果您需要的只是让UI看起来不错, 你可以

将您的表视图更改为没有浮动节标题

通过两个快速简单的步骤(iOS 6):

  1. 将您的UITableView样式更改为UITableViewStyleGrouped。 (您可以从Storyboard / NIB或通过代码执行此操作。)

  2. 接下来,将tableview的背景视图设置为空视图[在[em> viewDidAppear 等方法中,或者甚至在 cellForRow 方法中)(尽管我宁愿前者)]。

  3. yourTableView.backgroundView = [[UIView alloc] initWithFrame:listTableView.bounds];
    

    Voila,现在你有了你的桌面视图 - 但没有浮动部分标题。你的章节标题现在随着单元格一起滚动,你的凌乱的UI问题就解决了!

    请尝试一下,让我知道它是怎么回事。 快乐编码:)

    编辑:对于iOS 7,只需将表格视图样式更改为“ UITableViewStyleGrouped ”,并将视图的色调颜色更改为“清除颜色”。