2

I have a tableView having 30 rows and I also have a View on the top of tableView(Not in the tableview header) ,I want to capture the complete screen shot of the screen including the View and all the row of tableview but i can only able to capture the visible rows of tableview and the view .Please help me and thanks in advance. Here is my Code and the screen shot of simulator. Note(I don't want my View to be in tableview header because it will also scroll when we scroll the tableview thats why the view is fixed)

- (void)viewDidLoad {
    [super viewDidLoad];


    _myTableView.delegate = self;
    _myTableView.dataSource = self;

     UIBarButtonItem *next = [[UIBarButtonItem alloc]initWithTitle:@"Next" style:UIBarButtonItemStylePlain target:self action:@selector(nextButtonAction)];
     UIBarButtonItem *screenShot = [[UIBarButtonItem alloc]initWithTitle:@"Screenshot" style:UIBarButtonItemStylePlain target:self action:@selector(screenshotButtonAction)];

    self.navigationItem.leftBarButtonItem = screenShot;
    self.navigationItem.rightBarButtonItem = next;


 }

-(void)nextButtonAction
{

    NextViewController *myVc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"NextViewController"];
     NSLog(@"value of image is %@",viewImage);
     myVc.myImage = viewImage;
    [self.navigationController pushViewController:myVc animated:YES];

}

-(void)screenshotButtonAction
{

    UIView *viewToRender = self.myTableView;
    CGPoint contentOffset = self.myTableView.contentOffset;
     UIGraphicsBeginImageContext(viewToRender.bounds.size);
     CGContextRef ctx = UIGraphicsGetCurrentContext();
      CGContextTranslateCTM(ctx, 0,-contentOffset.y ); //-contentOffset.y
     [viewToRender.layer renderInContext:ctx];
     viewImage = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
  }


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
     return  30;
 }
- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

     static   NSString *myString = @"reused";
     UITableViewCell *Cell = [tableView dequeueReusableCellWithIdentifier:myString];
    if (Cell == nil)
    {
         Cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:myString];
    }
     Cell.textLabel.text = [NSString stringWithFormat:@"This is Cell %ld",indexPath.row];
    return Cell;
 }

This is the view I want to take screenshot with full tableview and above image

Deepak Sharma
  • 373
  • 3
  • 16
  • 1
    Since a tableview is a scrollview, possible a duplicate of: http://stackoverflow.com/questions/3539717/getting-a-screenshot-of-a-uiscrollview-including-offscreen-parts – Sealos Oct 13 '16 at 13:38

1 Answers1

4

I've changed this code for Swift 3 from Getting a screenshot of a UIScrollView, including offscreen parts

Edit: 2022 - TableView get restored after screenshot

 func screenshot() -> UIImage{
    
    var image = UIImage();
    UIGraphicsBeginImageContextWithOptions(self.tableView.contentSize, false, UIScreen.main.scale)
    
    // save initial values
    let savedContentOffset = self.tableView.contentOffset;
    let savedFrame = self.tableView.frame;
    let savedBackgroundColor = self.tableView.backgroundColor
    
    // reset offset to top left point
    self.tableView.contentOffset = CGPoint(x: 0, y: 0);
    // set frame to content size
    self.tableView.frame = CGRect(x: 0, y: 0, width: self.tableView.contentSize.width, height: self.tableView.contentSize.height);
    // remove background
    self.tableView.backgroundColor = self.tableView.backgroundColor;
    
    // make temp view with scroll view content size
    // a workaround for issue when image on ipad was drawn incorrectly
    let tempView = UIView(frame: CGRect(x: 0, y: 0, width: self.tableView.contentSize.width, height: self.tableView.contentSize.height));
    
 
    
    // save superview
    let tempSuperView = self.tableView.superview
    
    // Save constraints
    guard let superView = self.tableView.superview else {
        return UIImage();
    }
    
    //get old constraints from table
    var oldConstraints: [NSLayoutConstraint] = []
    for constraint in superView.constraints {
        if constraint.firstItem as? NSObject == self.tableView || constraint.secondItem as? NSObject == self.tableView{
           oldConstraints.append(constraint)
       }
    }
    
    // remove scrollView from old superview
    self.tableView.removeFromSuperview()
    // and add to tempView
    tempView.addSubview(self.tableView)
    
    // render view
    // drawViewHierarchyInRect not working correctly
    tempView.layer.render(in: UIGraphicsGetCurrentContext()!)
    // and get image
    image = UIGraphicsGetImageFromCurrentImageContext()!;
    
    // and return everything back
    tempView.subviews[0].removeFromSuperview()
    tempSuperView?.addSubview(self.tableView)
    
    //activate table's old constraints
    NSLayoutConstraint.activate(oldConstraints)
    
    // restore saved settings
    self.tableView.contentOffset = savedContentOffset;
    self.tableView.frame = savedFrame;
    self.tableView.backgroundColor = savedBackgroundColor
     
    UIGraphicsEndImageContext();
    
    
    return image
}