我有一个有 30 行的 tableView,并且在 tableView 的顶部还有一个 View(不在 tableview 标题中),我想捕获屏幕的完整屏幕截图,包括视图和 tableview 的所有行,但我可以只能捕获表视图和视图的可见行。请帮助我并提前致谢。 这是我的代码和模拟器的屏幕截图。 注意(我不希望我的视图位于表视图标题中,因为当我们滚动表视图时它也会滚动,这就是视图被固定的原因)
- (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;
}
我已经从 获取 UIScrollView 的屏幕截图,包括屏幕外部分更改了 Swift 3 的代码
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
}
他们不需要在任何地方添加屏幕,我们可以通过计算高度直接获取视图的屏幕截图
public func getEntireTable(completion: @escaping(_ image: UIImage?)->()){
let stackView = UIView()
stackView.frame = self.frame
stackView.frame.origin = .zero
stackView.frame.size = self.contentSize
var ypos: CGFloat = 0.0
var height : CGFloat = 0.0
let group = DispatchGroup()
group.enter()
for i in 0..<self.numberOfSections{
for j in 0..<self.numberOfRows(inSection: i){
self.scrollToRow(at: IndexPath(row: j, section: i), at: .none, animated: false)
if let cell = self.cellForRow(at: IndexPath(item: j, section: i)){
var v = cell.contentView
v.frame.origin.y = ypos
stackView.addSubview(v)
ypos += cell.contentView.frame.height ?? 0
height += cell.contentView.frame.height
if i == self.numberOfSections - 1 && j == self.numberOfRows(inSection: i)-1{
stackView.frame.size.height = height
group.leave()
}
}
}
}
group.wait()
group.notify(queue: .main, execute: {[weak self] in
if let snap = self?.snapshot(view: stackView) as? UIImage{
completion(snap)
}
})
}
func snapshot(view: UIView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, UIScreen.main.scale)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}