Снимок экрана из UITableView

Я знаю, что есть много вопросов по этой теме, но я действительно прочитал их все, но не нашли ответа.

Я хочу сделать снимок экрана из текущего представления таблицы. и я делаю это следующим образом:

-(UIImage *)imageFromCurrentView
{
    UIGraphicsBeginImageContextWithOptions(self.tableView.bounds.size, YES, 1);
    [self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

Все работает отлично, но когда я просматриваю таблицу в таблице и делаю скриншот, половина изображения черного цвета. Я не знаю, как сделать снимок экрана с фактического область таблицы.

Ответ 1

Поскольку UITableViewCell можно использовать повторно, при прокрутке представления таблицы ячейки вне портов представления будут выставлены в очередь для повторного использования и удаления из представления таблицы. Поэтому старайтесь держать ячейки только повторно используемыми по его указательному пути:

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *cellIdentifier = [NSString stringWithFormat:@"Cell_%d_%d", indexPath.section, indexPath.row]; 
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
  if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithReuseIdentifier:cellIdentifier] autorelease];
  }
  ...
  return cell;
}

Не тестировалось, попробуйте. Да, это будет потреблять гораздо больше памяти, сделайте это только с помощью скриншота.

Изменить: если вам небезразлично использование памяти, возможно, вы можете сделать снимок экрана текущего порта представления, затем программно прокрутите вверх и вниз, чтобы взять другие части снимков экрана, и, наконец, объединить все снимки экрана.

Ответ 2

Это даст вам текущую видимую область TableView.

Если вы хотите отобразить весь вид таблицы, сначала вам нужно знать, что, вероятно, это не отличная идея для чего-то большего, чем несколько десятков строк из-за памяти, а что нет. Максимальный размер изображения в 2048x2048, поэтому ваш tableView не может быть выше.

UIView *viewToRender = self.tableView;
CGPoint contentOffset = self.tableView.contentOffset;

UIGraphicsBeginImageContext(viewToRender.bounds.size);

CGContextRef ctx = UIGraphicsGetCurrentContext();

//  KEY: need to translate the context down to the current visible portion of the tablview
CGContextTranslateCTM(ctx, 0, -contentOffset.y);

[viewToRender.layer renderInContext:ctx];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

Ответ 3

взгляните на эту библиотеку, которую я сделал для этого, у нее есть очень полезные методы, например:

  • Сделайте полный снимок экрана вашего UITableView (все ячейки отображаются на одном UIImage)
  • Сделайте снимок экрана только для одной ячейки с учетом его indexPath
  • Сделайте снимок экрана только заголовков, нижних колонтитулов или строк вашего UITableView

И еще...

Вы можете добавить его в свой проект через Cocoapods или вручную, перетащив исходные файлы.

Использование так просто:

UIImage * tableViewScreenshot = [self.tableView screenshot];

Надеюсь, вы найдете эту библиотеку полезной, как и я.

Ответ 4

Следующий код отлично работает в моем приложении, вы можете использовать этот код для захвата снимка экрана из таблицы или любого другого прокрутки с горизонтальной прокруткой

CGPoint offset = [_tableView contentOffset];
_tableView.contentOffset = CGPointMake(0.0, 0.0);

CGRect visibleRect = _tableView.bounds;

UIGraphicsBeginImageContextWithOptions(_tableView.contentSize, _tableView.opaque, 0.0);

[_tableView.layer renderInContext:UIGraphicsGetCurrentContext()];

while (_tipsTableView.contentSize.height>= (visibleRect.origin.y+visibleRect.size.height)) {

    visibleRect.origin.y += visibleRect.size.height;

    [_tableView scrollRectToVisible:visibleRect animated:NO];
    [_tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
}

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();   

_tableView.contentOffset = offset;

Ответ 5

- (UIImage *) imageWithView:(UIView *)cellTobeCaptured isImage:(BOOL)isImage
{

//If UITableViewCell contains UIImageView

    if(isImage){
     UIGraphicsBeginImageContextWithOptions(cellTobeCaptured.bounds.size, NO, [UIScreen mainScreen].scale);
     [cellTobeCaptured drawViewHierarchyInRect:CGRectMake(0, 0, cellTobeCaptured.bounds.size.width, cellTobeCaptured.bounds.size.height) afterScreenUpdates:NO];
     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
     return image;
    }
else{
  UIGraphicsBeginImageContextWithOptions(cellTobeCaptured.bounds.size, cellTobeCaptured.opaque, 0.0);
  [cellTobeCaptured.layer renderInContext:UIGraphicsGetCurrentContext()];
   UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();
   return img;
   }
}

= > Вызовите метод как

 UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:arrIndex inSection:0]];
 self->screenShotImage = [self imageWithView:cell isImage:YES];

Ответ 6

У меня была аналогичная проблема с попыткой репликации прокрутки календаря Apple при смене месяцев в моем собственном календаре, построенном с использованием UITableView. После вызова scrollToRowAtIndexPath:, убедитесь, что анимированный: ДА, чтобы вызвать scrollViewDidEndScrollingAnimation: в scrollViewDidEndScrollingAnimation: я вызвал reloadData: в таблицеView перед renderInContext:. Затем на изображение было отображено полное представление таблицы. Я в конечном итоге не использовал это в долгосрочной перспективе, поэтому не уверен в надежности его как постоянного решения, но он работал хорошо, когда я его пробовал.