Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: UIKit does not document a reliable, one-image API that captures an entire offscreen UIWebView document from an IBAction. drawHierarchy(in:afterScreenUpdates:) renders the hierarchy “as visible onscreen,” so the common recipe of resizing an image context to scrollView.contentSize is not a verified full-page solution. For maintained apps, replace the deprecated UIWebView with WKWebView and treat whole-document output as a document-rendering or export problem that must be validated for your HTML and deployment target.
Decide what “full” means before writing the IBAction
Developers use “full screenshot” for three different outputs. Choosing the right one prevents you from shipping a fragile workaround.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
Apple iPhone 14, 128GB, Midnight - Unlocked (Renewed) | $299.00 | Buy on Amazon |
| 2 |
|
Apple iPhone 16, 128GB, Pink - Unlocked (Renewed) | $599.99 | Buy on Amazon |
| 3 |
|
Apple iPhone 15, 128GB, Black - Unlocked (Renewed) | $410.00 | Buy on Amazon |
| 4 |
|
Apple iPhone 13, 128GB, Midnight - Unlocked (Renewed) | $262.00 | Buy on Amazon |
| 5 |
|
Apple iPhone 16e, 128GB, Black - Unlocked (Renewed) | $389.00 | Buy on Amazon |
| Output | What it contains | What UIKit documents | Best fit |
|---|---|---|---|
| Viewport bitmap | The portion currently visible in the web view’s bounds | drawHierarchy(in:afterScreenUpdates:) is designed for this visible hierarchy capture |
Bug reports, visual tests, sharing the current screen |
| Whole HTML document bitmap | All vertically scrollable content, including pixels outside the viewport | No guarantee that changing the bitmap size or using contentSize paints offscreen WebKit content |
Only when you have validated a rendering pipeline for your exact page |
| Document artifact | A PDF or other paginated export rather than one very tall image | Must be implemented and tested as an export feature; it is not the same as a UIKit view snapshot | Printing, archiving, or preserving long documents |
The remainder of this article shows the supported viewport operation, explains why it is not a full-document capture, and gives a safe path for legacy maintenance and migration.
Recommended Free Tools
Why the familiar resize-and-draw recipe is not a reliable full-page capture
UIWebView exposes its associated UIScrollView, so it is tempting to read webView.scrollView.contentSize, create an image context of that size, and call a view-drawing method. That allocates a large bitmap, but allocation is not layout or painting. Web content outside the visible area can be absent, lazily loaded, animated, or dependent on WebKit behavior that UIKit does not promise to reproduce in an offscreen context.
#1 Best Overall
- This phone is unlocked and compatible with any carrier of choice on GSM and CDMA networks (e.g. AT&T, T-Mobile, Sprint, Verizon, US Cellular, Cricket, Metro, Tracfone, Mint Mobile, etc.).
- Please check with your carrier to verify compatibility.
- The device does not come with headphones or a SIM card. It does include a generic (Mfi certified) charging cable.
- Tested for battery health and guaranteed to have a minimum battery capacity of 80%.
Apple’s description of drawHierarchy(in:afterScreenUpdates:) is precise: it “Renders a snapshot of the complete view hierarchy as visible onscreen into the current context.” The phrase “as visible onscreen” is the boundary. A Boolean return value can also be false when image data is missing for a view. Neither fact establishes that a UIWebView can be stretched to its document height and captured as one complete image.
Do not present a contentSize-sized renderer as universally correct. If your requirement is truly a whole document, define the HTML, dynamic behavior, lazy images, cross-origin resources, and minimum iOS version you support, then validate a document-oriented export or rendering design on those exact conditions.
Capture the visible UIWebView viewport in an IBAction
For a screen capture of what the user can currently see, use UIGraphicsImageRenderer. Apple deprecated UIGraphicsBeginImageContext; the renderer is the current bitmap-context API. This code belongs in a view controller with an Interface Builder outlet.
Rank #2
- 6.1" Super Retina XDR OLED, HDR10, Dolby Vision, 1000nits (typ), 2000nits (HBM), 2556x1179px at 460ppi, 3561mAh Battery
- 128GB 8GB RAM, Apple A18 (3nm), Hexa-core (2x4.04 GHz + 4x2.20 GHz), Apple GPU 5-core, 16‑core Neural Engine
- Rear camera: 48MP, f/1.6, wide + 12MP, f/2.2, ultrawide, Front Camera: 12MP, f/1.9, wide, iOS 18, upgradable to iOS 18.5
- 4G LTE: 1/2/3/4/5/7/8/12/13/14/17/18/19/20/25/26/28/29/30/32/34/38/39/40/41/42/48/53/66/71, 5G: n1/2/3/5/7/8/12/14/20/25/26/28/29/30/38/40/41/48/53/66/70/71/75/76/77/78/79 - Dual eSIM
- Unlocked for freedom to choose your carrier. Compatible with both GSM & CDMA networks. The phone is unlocked to work with all GSM Carriers & CDMA Carriers Including AT&T, T-Mobile, Verizon, Sprint., Etc.
import UIKit
final class LegacyWebViewController: UIViewController {
@IBOutlet private weak var webView: UIWebView!
@IBAction func captureViewport(_ sender: UIButton) {
precondition(Thread.isMainThread)
let size = webView.bounds.size
guard size.width > 0, size.height > 0 else {
print("The web view has no drawable bounds yet.")
return
}
var hierarchyRendered = true
let renderer = UIGraphicsImageRenderer(size: size)
let image = renderer.image { _ in
hierarchyRendered = webView.drawHierarchy(
in: webView.bounds,
afterScreenUpdates: true
)
}
guard hierarchyRendered, let png = image.pngData() else {
print("The viewport snapshot is incomplete or could not be encoded.")
return
}
let outputURL = FileManager.default.temporaryDirectory
.appendingPathComponent("uiwebview-viewport.png")
do {
try png.write(to: outputURL, options: .atomic)
print("Saved viewport image to: (outputURL.path)")
} catch {
print("Could not save the image: (error)")
}
}
}
The image dimensions are the web view’s current bounds, not its scrollable document height. Call the action after Auto Layout has produced nonzero bounds and after the page has finished loading. If the action follows a visual change, dispatch it after that change has reached the screen so afterScreenUpdates: true can include it.
Objective-C IBAction equivalent
#import <UIKit/UIKit.h>
- (IBAction)captureViewport:(id)sender {
NSAssert([NSThread isMainThread], @"UI capture must run on the main thread");
CGSize size = self.webView.bounds.size;
if (size.width <= 0 || size.height <= 0) {
NSLog(@"The web view has no drawable bounds yet");
return;
}
__block BOOL rendered = YES;
UIGraphicsImageRenderer *renderer =
[[UIGraphicsImageRenderer alloc] initWithSize:size];
UIImage *image = [renderer imageWithActions:^(UIGraphicsImageRendererContext *context) {
rendered = [self.webView drawViewHierarchyInRect:self.webView.bounds
afterScreenUpdates:YES];
}];
NSData *png = rendered ? UIImagePNGRepresentation(image) : nil;
if (!png) {
NSLog(@"The viewport snapshot is incomplete or could not be encoded");
return;
}
NSURL *url = [NSURL fileURLWithPath:
[NSTemporaryDirectory() stringByAppendingPathComponent:@"uiwebview-viewport.png"]];
NSError *error = nil;
if (![png writeToURL:url options:NSDataWritingAtomic error:&error]) {
NSLog(@"Could not save the image: %@", error);
}
}
This Objective-C action has the same contract: it captures the onscreen viewport. It does not turn the web view into a full-document renderer.
Wait for the page and layout before capturing
A correct viewport call can still produce a blank or partial result if it races loading or layout. Keep readiness separate from the drawing operation.
Rank #3
- 6.1inch Super Retina XDR display. Aluminum with color-infused glass back. Ring/Silent switch
- Dynamic Island. A magical way to interact with iPhone. A16 Bionic chip with 5-core GPU
- Advanced dual-camera system. 48MP Main | Ultra Wide. Super-high-resolution photos (24MP and 48MP). Next-generation portraits with Focus and Depth Control. 4X optical zoom range
- Emergency SOS via satellite. Crash Detection. Roadside Assistance via satellite
- Up to 26 hours video playback. USB C, Supports USB 2. Face ID
- Wait for navigation completion. Use the existing
UIWebViewdelegate’s load-finished callback rather than enabling the capture button immediately afterloadRequest. - Confirm usable bounds. Check that width and height are nonzero after Auto Layout has run. A zero-sized renderer cannot contain a useful image.
- Keep the call on the main thread. UIKit view drawing and WebKit presentation are main-thread operations.
- Stabilize dynamic content. Pause or remove animations and wait for images or script-generated elements that your product requires. The API does not promise that resources still loading will appear.
- Handle a false return. Treat
falsefrom the hierarchy-drawing method as an incomplete capture, not as a successful file.
Do not embed a UIWebView inside another UIScrollView; Apple warns that nested scrolling can mix up touch events and cause them to be handled incorrectly.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWhat to do when the requirement is the entire document
Prefer migration to WKWebView
UIWebView is deprecated, and Apple’s API guidance says, “Use WKWebView instead.” Apple describes WKWebView as the native view for interactive web content and supports adding it in Interface Builder or creating it programmatically. Migration removes a legacy dependency, but it does not by itself create a guaranteed one-image full-page screenshot API.
Choose a document-oriented output when possible
If the real need is printing, sharing, or archiving a long page, a PDF or another document artifact may be more appropriate than a single extremely tall PNG. Define pagination, margins, fonts, links, and whether scripts and remote resources must execute. Then validate the export path against the pages your app actually loads. Rasterize the document only when a bitmap is required by a downstream system.
Rank #4
- This pre-owned product is not Apple certified, but has been professionally inspected, tested and cleaned by Amazon-qualified suppliers.
- There will be no visible cosmetic imperfections when held at an arm’s length.
- This product is eligible for a replacement or refund within 90 days of receipt if you are not satisfied.
- Product may come in generic Box.
If a bitmap is mandatory
There is no primary-source guarantee that resizing a legacy web view to its contentSize and drawing it captures every offscreen pixel. A team can build and test a custom renderer, section-by-section capture, or HTML-aware export, but those are engineering designs rather than a universally supported UIKit recipe. Test lazy-loaded images, long pages, fixed-position elements, animations, failed resources, and the oldest iOS version you ship. Record the exact WebKit and content conditions under which the result is accepted.
Common failure modes and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Only the visible screen appears | The code uses a documented viewport hierarchy snapshot | Decide whether a document export is acceptable; do not assume a larger context adds offscreen pixels |
| Blank or tiny image | The action ran before layout, or the bounds are zero | Wait for layout and verify webView.bounds.size before creating the renderer |
| Old page state appears | The capture raced navigation, script updates, or image loading | Enable capture from the load-finished delegate and add an app-specific readiness check |
| Missing images or subviews | drawHierarchy returned false or resources were unavailable |
Check the Boolean result, retry after resources settle, and log the failing content |
| Memory warning or crash on a tall bitmap | Pixel dimensions and bytes per pixel grow with document height and scale | Avoid unbounded one-piece images; use a validated document or tiled design and enforce maximum dimensions |
| Touch behavior becomes erratic | The web view is nested in another scroll view | Remove the outer scroll container or redesign the hierarchy |
| Legacy API warnings | UIWebView or UIGraphicsBeginImageContext is deprecated |
Use UIGraphicsImageRenderer for new bitmap code and schedule migration to WKWebView |
Performance, fidelity, and testing considerations
- Pixel scale: A renderer’s size is in points, while the backing bitmap also depends on scale. Decide whether your consumer needs display-resolution pixels or a smaller file.
- Encoding: PNG preserves sharp text and transparency but can be large. JPEG is smaller for photographic pages but loses lossless detail. Choose after measuring your actual pages.
- Determinism: Freeze clocks, animations, random content, and network-dependent widgets in visual tests. Otherwise two captures can differ even when the code is unchanged.
- Security: Do not log cookies, authorization headers, or private page contents while diagnosing capture failures.
- Acceptance tests: Include short and very long documents, lazy images, fixed headers, forms, dark mode, offline failures, and pages that redirect. A successful viewport screenshot is not evidence that a whole-document export works.
Or skip the browser setup
If the page you need is publicly reachable by URL rather than a private in-app state, ScreenshotNeo provides a website screenshot API. It is not a replacement for capturing unsaved local UIWebView state, but it avoids maintaining a browser automation stack for URL-based captures. Before the capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →See the ScreenshotNeo API documentation for authentication and options. A basic request is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same call in Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
And in Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo includes full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF settings, custom CSS and JavaScript, click and wait controls, request and resource blocking, custom headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, configurable caching, signed links, asynchronous webhooks, bulk capture for up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameters commonly used by other screenshot APIs are accepted to ease migration.
Best Value
- 6.1" Super Retina XDR OLED, HDR10, 800 nits (HBM), 1200 nits (peak), 2532x1170px at 460ppi, 4005mAh Battery
- 8GB RAM, Apple A18 6-core CPU (2 performance + 4 efficiency cores), Apple GPU 4-core, 16‑core Neural Engine
- Rear camera: 48MP, f/1.6, wide, Front Camera: 12MP, f/1.9, wide, iOS 18.3.1, upgradable to iOS 18.5
- Connectivity: Global 4G LTE, Sub-6 GHz 5G, LTE, Wi-Fi 6, Bluetooth 5.3, NFC, USB-C, Wireless Charging (7.5W). (does not have mmWave 5G or MagSafe or physical SIM card) - Dual eSIM Only
- Unlocked for freedom to choose your carrier. Compatible with both GSM & CDMA networks. The phone is unlocked to work with all GSM Carriers & CDMA Carriers Including AT&T, T-Mobile, Verizon, Straight Talk., Etc.
| Plan | Allowance | Price |
|---|---|---|
| Free | 1,000 shots/month | Free; no card |
| Starter | 3,000 shots | $5 |
| Growth | 15,000 shots | $15 |
| Pro | 60,000 shots | $39 |
| Scale | 250,000 shots | $99 |
| Business | 1,000,000 shots | $249 |
Yearly billing gives two months free, and every feature is included on every plan. You can sign up for the free plan to get 1,000 screenshots a month without a card.
FAQ
Does the iPhone or Safari “Full Page” option provide an app API for UIWebView?
No. Apple’s consumer screenshot workflow is a device feature. It should not be treated as an API that captures an app’s UIWebView document.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Should I keep investing in a UIWebView workaround for a new feature?
Usually not. Keep legacy code only when migration is constrained, and document the exact content and OS combinations you support. For new work, move to WKWebView and design the required document or image output explicitly.
Frequently Asked Questions
Does the iPhone or Safari “Full Page” option provide an app API for UIWebView?
No. Apple’s consumer screenshot workflow is a device feature, not an API for capturing an app’s UIWebView document.
Should I keep investing in a UIWebView workaround for a new feature?
Only when migration is constrained and you can test the exact content and OS combinations. New work should use WKWebView and an explicitly designed document or image output.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitches

