Снимок экрана из UITableView - PullRequest
11 голосов
/ 19 июня 2011

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

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

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

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

Ответы [ 6 ]

26 голосов
/ 01 апреля 2012

Это даст вам текущую видимую область 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();
22 голосов
/ 04 декабря 2013

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

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

И еще ...

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

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

UIImage * tableViewScreenshot = [self.tableView screenshot];

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

3 голосов
/ 15 мая 2013

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


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;

2 голосов
/ 19 июня 2011

Поскольку 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;
}

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

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

1 голос
/ 01 июня 2017
- (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];
0 голосов
/ 29 апреля 2012

У меня была похожая проблема при попытке повторить прокрутку календаря Apple при смене месяцев в моем собственном пользовательском календаре, созданном с использованием UITableView. После вызова scrollToRowAtIndexPath:, убедившись, что animated: является YES, чтобы вызывался scrollViewDidEndScrollingAnimation: в scrollViewDidEndScrollingAnimation: я вызывал reloadData: для tableView перед renderInContext :. Полный табличный вид был затем представлен к изображению. В конечном итоге я не использовал это в долгосрочной перспективе, поэтому не был уверен в надежности этого решения в качестве постоянного решения, но оно работало хорошо, когда я попробовал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...