Swift 4中如何将JSON中的图片放入Scroll View实现切换
Great choice using SDWebImage for image loading—let's get those two images into a scroll view so users can swipe between them seamlessly. Here's a step-by-step solution tailored to your setup:
Core Approach
We'll use a UIScrollView with paging enabled (so it snaps neatly to each image) and place your front/back image views side-by-side inside it. Each image will take up the full width/height of the scroll view, so swiping left/right toggles between them.
Step 1: Configure the Scroll View
First, set up the scroll view's key properties. You can do this programmatically or via Interface Builder (IB):
Option A: Programmatic Setup
If you're creating the scroll view in code, add this to your viewDidLayoutSubviews (better for dynamic sizing when the screen rotates or resizes):
// Assuming you have outlets for your scroll view and image views @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var figImage: UIImageView! @IBOutlet weak var figBackImage: UIImageView! override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // Enable paging and hide scroll indicators for a clean look scrollView.isPagingEnabled = true scrollView.showsHorizontalScrollIndicator = false // Set content size to fit both images (twice the scroll view width) scrollView.contentSize = CGSize(width: scrollView.bounds.width * 2, height: scrollView.bounds.height) // Position the front image at the start (x=0) figImage.frame = scrollView.bounds // Position the back image to the right of the front one figBackImage.frame = CGRect( x: scrollView.bounds.width, y: 0, width: scrollView.bounds.width, height: scrollView.bounds.height ) // Add image views to the scroll view if they aren't already if !figImage.isDescendant(of: scrollView) { scrollView.addSubview(figImage) } if !figBackImage.isDescendant(of: scrollView) { scrollView.addSubview(figBackImage) } }
Option B: Auto Layout (Recommended for Adaptive Layouts)
If you prefer Auto Layout (better for handling rotation and different screen sizes), replace the frame setup with these constraints:
override func viewDidLoad() { super.viewDidLoad() scrollView.isPagingEnabled = true scrollView.showsHorizontalScrollIndicator = false // Disable auto-resizing masks for image views figImage.translatesAutoresizingMaskIntoConstraints = false figBackImage.translatesAutoresizingMaskIntoConstraints = false // Add image views to scroll view first scrollView.addSubview(figImage) scrollView.addSubview(figBackImage) // Set constraints for front image NSLayoutConstraint.activate([ figImage.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), figImage.topAnchor.constraint(equalTo: scrollView.topAnchor), figImage.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), figImage.widthAnchor.constraint(equalTo: scrollView.widthAnchor) ]) // Set constraints for back image NSLayoutConstraint.activate([ figBackImage.leadingAnchor.constraint(equalTo: figImage.trailingAnchor), figBackImage.topAnchor.constraint(equalTo: scrollView.topAnchor), figBackImage.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor), figBackImage.widthAnchor.constraint(equalTo: scrollView.widthAnchor), figBackImage.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor) ]) }
Step 2: Load Images Safely with SDWebImage
Keep using SDWebImage, but add safety checks to avoid crashes from invalid URLs. Update your image loading code like this:
// Assuming 'figure' is your model object parsed from the JSON if let figure = figure { // Load front image if let frontImageURL = URL(string: figure.image) { figImage.sd_setImage( with: frontImageURL, placeholderImage: UIImage(named: "placeholder") // Add a placeholder for better UX ) } else { // Fallback to placeholder if URL is invalid figImage.image = UIImage(named: "placeholder") } // Load back image if let backImageURL = URL(string: figure.backImage) { figBackImage.sd_setImage( with: backImageURL, placeholderImage: UIImage(named: "placeholder") ) } else { figBackImage.image = UIImage(named: "placeholder") } }
Bonus Tips
- Placeholder Images: Always use a placeholder to keep the UI looking polished while images load.
- Initial Scroll Position: If you want to start on the back image, add this line after layout:
scrollView.contentOffset = CGPoint(x: scrollView.bounds.width, y: 0) - Error Handling: SDWebImage lets you add completion handlers to handle load failures gracefully:
figImage.sd_setImage(with: frontImageURL, placeholderImage: UIImage(named: "placeholder")) { [weak self] image, error, _, _ in if let error = error { print("Front image load failed: \(error.localizedDescription)") self?.figImage.image = UIImage(named: "error-placeholder") } }
内容的提问来源于stack exchange,提问作者Medicine Man

