美文网首页
(iOS - Objective-C) UITableView

(iOS - Objective-C) UITableView

作者: Raywf | 来源:发表于2017-08-28 21:29 被阅读0次

    2018.9.19

    本文提供了 UIView,UIScrollView,UITableView 三个常用的视图的代码截图方法,三者的思路都是一样的,即将所有显示内容渲染到一个上下文对象中去,然后将这个上下文对象保存成UIImage对象就OK了。
    UIView 截图

    简单的设置上下文对象,然后调用几句代码就好了,关键在于设置UIView的大小,以及比例系数(影响清晰度?),方便起见建议写入UIImage的分类中;

    + (UIImage *)CapturedWithUIView:(UIView *)view {
        // 下面方法,第一个参数表示区域大小。第二个参数表示是否是非透明的。如果需要显示半透明效果,需要传NO,否则传YES。第三个参数就是屏幕密度了,关键就是第三个参数。
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, [UIScreen mainScreen].scale);
    
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
    }
    
    UIScrollView 截图

    其实方法和UIView的截图方法基本没有区别,如果将设置一个UIView的父视图,大小为UIScrollViewcontentSize的大小,那么用UIView的截图方法应该也是没问题的;方便起见建议写入UIImage的分类中;

    + (UIImage *)CapturedWithUIScrollView:(UIScrollView *)scrollView {
        UIImage* image = nil;
        UIGraphicsBeginImageContextWithOptions(scrollView.contentSize, NO, [UIScreen mainScreen].scale);
        {
            CGPoint savedContentOffset = scrollView.contentOffset;
            CGRect savedFrame =  scrollView.frame;
    
            scrollView.contentOffset = CGPointZero;
            scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
    
            [scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
            image = UIGraphicsGetImageFromCurrentImageContext();
    
            scrollView.contentOffset = savedContentOffset;
            scrollView.frame = savedFrame;
        }
        UIGraphicsEndImageContext();
        return image;
    }
    
    UITableView 截图

    这个地方有点麻烦的就是Cell可能是重用的,也就说上面的方法不能适用了,因为Cell的内容都没有被绘制到上下文对象中,当然也就无法成功截图了。。。
    处理思路同样是想办法将所有的视图渲染到上下文对象中去,然后将上下文对象转成UIImage实例;方便起见建议写入UIImage的分类中;
    这个,我的最终实现方法还是比较糙的,若是哪位猿兄有更好的处理方式,还请不吝赐教了啊;
    注:1.需要实现协议方法 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 或 - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section 时,首先需要实现相应的返回高度的协议方法,其次一定要用UITableViewHeaderFooterView类创建实例,并返回这个实例,这样下面的方法中才可以用 headerViewForSection 或 footerViewForSection 取得相关视图实例;
    2.如果像QQ好友列表那样的折叠情况,我觉得可以复制这个TableView,然后设定为不折叠,即只要保证所有视图的高度值能被方法成功获取到就可以了;
    参考:UITableView screenshot

    + (UIImage *)CapturedWithUITableView:(UITableView *)tableView {
        CGPoint savedContentOffset = tableView.contentOffset;
        ///计算画布所需实际高度
        CGFloat contentHeight = 0;
        if (tableView.tableHeaderView)
            contentHeight += tableView.tableHeaderView.frame.size.height;
        {
            NSInteger sections = tableView.numberOfSections;
            for (NSInteger i = 0; i < sections; i++) {
                contentHeight += [tableView rectForHeaderInSection:i].size.height;
    
                NSInteger rows = [tableView numberOfRowsInSection:i];
                {
                    for (NSInteger j = 0; j < rows; j++) {
                        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:i];
                        [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO];
                        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
                        contentHeight += cell.frame.size.height;
                    }
                }
    
                contentHeight += [tableView rectForFooterInSection:i].size.height;
            }
        }
        if (tableView.tableFooterView)
            contentHeight += tableView.tableFooterView.frame.size.height;
    
        ///创建画布
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(tableView.frame.size.width, contentHeight), NO, [UIScreen mainScreen].scale);
        CGContextRef ctx = UIGraphicsGetCurrentContext();
    
        ///把所有的视图 render到CGContext上
        if (tableView.tableHeaderView) {
            contentHeight = tableView.tableHeaderView.frame.size.height;
            tableView.contentOffset = CGPointMake(0, contentHeight);
            [tableView.tableHeaderView.layer renderInContext:ctx];
            CGContextTranslateCTM(ctx, 0, tableView.tableHeaderView.frame.size.height);
        }
    
        NSInteger sections = tableView.numberOfSections;
        for (NSInteger i = 0; i < sections; i++) {
            ///sectionHeader
            contentHeight += [tableView rectForHeaderInSection:i].size.height;
            tableView.contentOffset = CGPointMake(0, contentHeight);
            UIView *headerView = [tableView headerViewForSection:i];
            if (headerView) {
                [headerView.layer renderInContext:ctx];
                CGContextTranslateCTM(ctx, 0, headerView.frame.size.height);
            }
            ///Cell
            NSInteger rows = [tableView numberOfRowsInSection:i];
            {
                for (NSInteger j = 0; j < rows; j++) {
                    //讓該cell被正確的產生在tableView上, 之後才能在CGContext上正確的render出來
                    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:i];
                    [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO];
                    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
                    contentHeight += cell.frame.size.height;
                    [cell.layer renderInContext:ctx];
                    CGContextTranslateCTM(ctx, 0, cell.frame.size.height);
                }
            }
            ///sectionFooter
            contentHeight += [tableView rectForFooterInSection:i].size.height;
            tableView.contentOffset = CGPointMake(0, contentHeight);
            UIView *footerView = [tableView footerViewForSection:i];
            if (footerView) {
                [footerView.layer renderInContext:ctx];
                CGContextTranslateCTM(ctx, 0, footerView.frame.size.height);
            }
        }
    
        if (tableView.tableFooterView) {
            tableView.contentOffset = CGPointMake(0, tableView.contentSize.height-tableView.frame.size.height);
            [tableView.tableFooterView.layer renderInContext:ctx];
            //CGContextTranslateCTM(ctx, 0, tableView.tableFooterView.frame.size.height);
        }
    
        ///生成UIImage对象
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        tableView.contentOffset = savedContentOffset;
        return image;
    }
    

    相关文章

      网友评论

          本文标题:(iOS - Objective-C) UITableView

          本文链接:https://www.haomeiwen.com/subject/uihgdxtx.html