admin管理员组文章数量:1391928
In the screenshot if i copy the orignial first placed ojbect twice there are two other objects that are only displayed in the saved photo. So I place a circle copy the inal twice hit the copy button twice then in the saved photo there are 5 circles and there should only be 3.You can see in the photos below what is going on. The duplicated images are being saved in the positions of 1 in the first photo.
import UIKit
import CoreData
class First: UIViewController {
var objects = [UIImageView]()
var nextB = UIButton()
var drawView = Canvas()
var libaryB = UIButton()
var ww = 80
var saveB = UIButton()
var circleB = UIButton()
var copyb = UIButton()
var txt = UITextField()
var currentView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
[saveB,circleB, libaryB,txt, drawView,copyb].forEach {
view.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
$0.layer.borderWidth = 1
$0.backgroundColor = UIColor(
red: .random(in: 0.5...0.7),
green: .random(in: 0.0...1),
blue: .random(in: 0.3...0.5),
alpha: 1
)
$0.layer.borderWidth = 1
if let textfield = $0 as? UITextField {
textfield.textAlignment = .center
textfield.inputAccessoryView = createToolbar()
}
if let label = $0 as? UILabel {
label.textAlignment = .center
}
if let button = $0 as? UIButton {
button.setTitleColor(.black, for: .normal)
}
}
circleB.setTitle("Circle", for: .normal)
libaryB.setTitle("Library", for: .normal)
saveB.setTitle("Save", for: .normal)
libaryB.addTarget(self, action: #selector(libraryBUttonFunction), for: .touchDown)
// note that I changed some of the constraints to use the safeAreaLayoutGuide of the view
// you wouldn't want your sliders to go out of the safe area, would you?
NSLayoutConstraint.activate([
txt.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
txt.leadingAnchor.constraint(equalTo: view.leadingAnchor),
txt.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
txt.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
drawView.topAnchor.constraint(equalTo: txt.bottomAnchor),
drawView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
drawView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.6),
drawView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
circleB.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
circleB.leadingAnchor.constraint(equalTo: view.leadingAnchor),
circleB.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
circleB.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1/4),
saveB.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
saveB.leadingAnchor.constraint(equalTo: circleB.trailingAnchor),
saveB.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
saveB.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1/4),
libaryB.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
libaryB.leadingAnchor.constraint(equalTo: saveB.trailingAnchor),
libaryB.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
libaryB.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1/4),
copyb.bottomAnchor.constraint(equalTo: circleB.topAnchor),
copyb.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.05),
copyb.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, multiplier: 1/4),
copyb.leadingAnchor.constraint(equalTo: libaryB.trailingAnchor),
])
copyb.setTitle("Copy", for: .normal)
circleB.addTarget(self, action: #selector(circleBox), for: .touchDown)
saveB.addTarget(self, action: #selector(saveData), for: .touchDown)
copyb.addTarget(self, action: #selector(copyM), for: .touchDown)
}
//2ndBelow
@objc func copyM() {
guard let originalView = currentView as? UIImageView else { return }
// Ensure we are not duplicating unintended objects
if objects.contains(originalView) {
print("Original object already exists, copying it.")
}
let copiedView = UIImageView(image: originalView.image)
copiedView.frame = CGRect(
x: originalView.frame.origin.x + 20,
y: originalView.frame.origin.y + 20,
width: originalView.frame.width,
height: originalView.frame.height
)
copiedView.isUserInteractionEnabled = true
copiedView.backgroundColor = originalView.backgroundColor
copiedView.layer.cornerRadius = originalView.layer.cornerRadius
copiedView.clipsToBounds = true
copiedView.layer.borderWidth = originalView.layer.borderWidth
copiedView.layer.borderColor = originalView.layer.borderColor
for subview in originalView.subviews {
if let label = subview as? UILabel {
let copiedLabel = UILabel(frame: label.frame)
copiedLabel.text = label.text
copiedLabel.textAlignment = label.textAlignment
copiedView.addSubview(copiedLabel)
}
}
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:)))
copiedView.addGestureRecognizer(pan)
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
copiedView.addGestureRecognizer(tap)
objects.append(copiedView)
drawView.addSubview(copiedView)
currentView = copiedView
print("Copied object, total objects: \(objects.count)")
}
func captureFullScreenshot() -> UIImage {
let allFrames = Set(objects.map { $0.frame }) // Unique frames only
let expandedBounds = allFrames.reduce(drawView.bounds) { $0.union($1) }
let renderer = UIGraphicsImageRenderer(bounds: expandedBounds)
return renderer.image { context in
context.cgContext.translateBy(x: -expandedBounds.origin.x, y: -expandedBounds.origin.y)
// Render drawView first (background)
drawView.layer.render(in: context.cgContext)
// Ensure each object is rendered only once
var drawnObjects = Set<UIImageView>()
for imageView in objects where !drawnObjects.contains(imageView) {
let convertedFrame = drawView.convert(imageView.frame, from: view)
context.cgContext.translateBy(x: convertedFrame.origin.x, y: convertedFrame.origin.y)
imageView.layer.render(in: context.cgContext)
context.cgContext.translateBy(x: -convertedFrame.origin.x, y: -convertedFrame.origin.y)
drawnObjects.insert(imageView) // Mark as drawn
}
}
}
@objc func handlePanGestured(_ gesture: UIPanGestureRecognizer) {
guard let draggedView = gesture.view else { return }
let translation = gesture.translation(in: view)
draggedView.center = CGPoint(x: draggedView.center.x + translation.x,
y: draggedView.center.y + translation.y)
gesture.setTranslation(.zero, in: view)
// Update the object position in objects array
if let index = objects.firstIndex(of: draggedView as! UIImageView) {
objects[index].frame = draggedView.frame
}
currentView = draggedView
}
@objc func circleBox() {
// Create a UIImageView for the circle
let subview = UIImageView()
// Enable interaction with the subview
subview.isUserInteractionEnabled = true
objects.append(subview)
view.addSubview(subview)
// Set the frame for the circle (must be a square, so equal width and height)
let size: CGFloat = 80 // Define size of the circle
subview.frame = CGRect(x: view.bounds.midX, y: view.bounds.midY + CGFloat(ww), width: size, height: size)
subview.backgroundColor = UIColor.orange
// Make the UIImageView a circle by setting the cornerRadius to half of the width/height
subview.layer.cornerRadius = size / 2
subview.clipsToBounds = true // Ensures the circle shape is maintained
// Add a border to the subview
subview.layer.borderWidth = 2.0 // Set the border width
subview.layer.borderColor = UIColor.black.cgColor // Set the border color
// Add pan and tap gesture recognizers
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:)))
subview.addGestureRecognizer(pan)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
subview.addGestureRecognizer(tapGesture)
// Create and add bottom label for width (initially set to 3)
let bottomLabel = UILabel()
bottomLabel.text = "3"
bottomLabel.textAlignment = .center
bottomLabel.frame = CGRect(
x: (subview.bounds.width - 50) / 2, // Center horizontally
y: subview.bounds.height - 20, // Align at the bottom
width: 50,
height: 20
)
subview.addSubview(bottomLabel)
// Create and add left label for height (initially set to 1)
let leftLabel = UILabel()
leftLabel.text = "1"
leftLabel.textAlignment = .center
leftLabel.frame = CGRect(
x: 0, // Align to the left edge
y: (subview.bounds.height - 20) / 2, // Center vertically
width: 50,
height: 20
)
subview.addSubview(leftLabel)
// Automatically select the new circle
currentView = subview
}
func createToolbar() -> UIToolbar {
let toolbar = UIToolbar()
toolbar.sizeToFit()
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTapped))
toolbar.items = [flexSpace, doneButton]
return toolbar
}
@objc func libraryBUttonFunction() {
print("Library Button Selected")
// Replace `YourViewController` with the name of the view controller you want to present
let destinationVC = Second()
// Customize the modal presentation style (optional)
destinationVC.modalPresentationStyle = .fullScreen // or .overFullScreen, .pageSheet, etc.
// Present the view controller modally
self.present(destinationVC, animated: true, completion: nil)
}
@objc func doneButtonTapped() {
view.endEditing(true)
}
@objc func saveData() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let context = appDelegate.persistentContainer.viewContext
guard let nameText = txt.text, !nameText.isEmpty else {
print("Text field is empty")
return
}
// Capture the drawing from drawView as an image
let drawingImage = captureFullScreenshot()
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Name")
fetchRequest.predicate = NSPredicate(format: "nameOfPic == %@", nameText)
do {
let results = try context.fetch(fetchRequest)
if let existingEntry = results.first {
// Update the existing entry
existingEntry.setValue(nameText, forKey: "nameOfPic")
existingEntry.setValue(drawingImage.pngData(), forKey: "pic")
} else {
// Create a new entry
let entity = NSEntityDescription.entity(forEntityName: "Name", in: context)!
let newEntry = NSManagedObject(entity: entity, insertInto: context)
newEntry.setValue(nameText, forKey: "nameOfPic")
newEntry.setValue(drawingImage.pngData(), forKey: "pic")
}
try context.save()
print("Data saved successfully.")
// Save image to the photo gallery
UIImageWriteToSavedPhotosAlbum(drawingImage, self, #selector(imageSaved(_:didFinishSavingWithError:contextInfo:)), nil)
// Notify Second about the save and update its list
libraryBUttonFunction()
} catch {
print("Failed to save data: \(error.localizedDescription)")
}
print("Saving screenshot with \(objects.count) objects.")
}
// Completion handler for image saving
@objc func imageSaved(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
print("Error saving image: \(error.localizedDescription)")
} else {
print("Image saved to photo gallery successfully.")
}
}
@objc func handleTapGestured(_ gesture: UITapGestureRecognizer) {
currentView = gesture.view
// Set slider value to match the size of the selected box
}
}
extension UIView {
/// Takes a screenshot of a UIView, with an option to clip to view bounds and place a waterwark image
/// - Parameter rect: offset and size of the screenshot to take
/// - Parameter clipToBounds: Bool to check where self.bounds and rect intersect and adjust size so there is no empty space
/// - Parameter watermark: UIImage of the watermark to place on top
func screenshot(for rect: CGRect, clipToBounds: Bool = true, with watermark: UIImage? = nil) -> UIImage {
var imageRect = rect
if clipToBounds {
imageRect = bounds.intersection(rect)
}
return UIGraphicsImageRenderer(bounds: imageRect).image { _ in
drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
watermark?.draw(in: CGRect(x: 0, y: 0, width: 32, height: 32))
}
}
}
In the screenshot if i copy the orignial first placed ojbect twice there are two other objects that are only displayed in the saved photo. So I place a circle copy the inal twice hit the copy button twice then in the saved photo there are 5 circles and there should only be 3.You can see in the photos below what is going on. The duplicated images are being saved in the positions of 1 in the first photo.
import UIKit
import CoreData
class First: UIViewController {
var objects = [UIImageView]()
var nextB = UIButton()
var drawView = Canvas()
var libaryB = UIButton()
var ww = 80
var saveB = UIButton()
var circleB = UIButton()
var copyb = UIButton()
var txt = UITextField()
var currentView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
[saveB,circleB, libaryB,txt, drawView,copyb].forEach {
view.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
$0.layer.borderWidth = 1
$0.backgroundColor = UIColor(
red: .random(in: 0.5...0.7),
green: .random(in: 0.0...1),
blue: .random(in: 0.3...0.5),
alpha: 1
)
$0.layer.borderWidth = 1
if let textfield = $0 as? UITextField {
textfield.textAlignment = .center
textfield.inputAccessoryView = createToolbar()
}
if let label = $0 as? UILabel {
label.textAlignment = .center
}
if let button = $0 as? UIButton {
button.setTitleColor(.black, for: .normal)
}
}
circleB.setTitle("Circle", for: .normal)
libaryB.setTitle("Library", for: .normal)
saveB.setTitle("Save", for: .normal)
libaryB.addTarget(self, action: #selector(libraryBUttonFunction), for: .touchDown)
// note that I changed some of the constraints to use the safeAreaLayoutGuide of the view
// you wouldn't want your sliders to go out of the safe area, would you?
NSLayoutConstraint.activate([
txt.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
txt.leadingAnchor.constraint(equalTo: view.leadingAnchor),
txt.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
txt.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
drawView.topAnchor.constraint(equalTo: txt.bottomAnchor),
drawView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
drawView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.6),
drawView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
circleB.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
circleB.leadingAnchor.constraint(equalTo: view.leadingAnchor),
circleB.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
circleB.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1/4),
saveB.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
saveB.leadingAnchor.constraint(equalTo: circleB.trailingAnchor),
saveB.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
saveB.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1/4),
libaryB.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
libaryB.leadingAnchor.constraint(equalTo: saveB.trailingAnchor),
libaryB.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.05),
libaryB.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1/4),
copyb.bottomAnchor.constraint(equalTo: circleB.topAnchor),
copyb.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.05),
copyb.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, multiplier: 1/4),
copyb.leadingAnchor.constraint(equalTo: libaryB.trailingAnchor),
])
copyb.setTitle("Copy", for: .normal)
circleB.addTarget(self, action: #selector(circleBox), for: .touchDown)
saveB.addTarget(self, action: #selector(saveData), for: .touchDown)
copyb.addTarget(self, action: #selector(copyM), for: .touchDown)
}
//2ndBelow
@objc func copyM() {
guard let originalView = currentView as? UIImageView else { return }
// Ensure we are not duplicating unintended objects
if objects.contains(originalView) {
print("Original object already exists, copying it.")
}
let copiedView = UIImageView(image: originalView.image)
copiedView.frame = CGRect(
x: originalView.frame.origin.x + 20,
y: originalView.frame.origin.y + 20,
width: originalView.frame.width,
height: originalView.frame.height
)
copiedView.isUserInteractionEnabled = true
copiedView.backgroundColor = originalView.backgroundColor
copiedView.layer.cornerRadius = originalView.layer.cornerRadius
copiedView.clipsToBounds = true
copiedView.layer.borderWidth = originalView.layer.borderWidth
copiedView.layer.borderColor = originalView.layer.borderColor
for subview in originalView.subviews {
if let label = subview as? UILabel {
let copiedLabel = UILabel(frame: label.frame)
copiedLabel.text = label.text
copiedLabel.textAlignment = label.textAlignment
copiedView.addSubview(copiedLabel)
}
}
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:)))
copiedView.addGestureRecognizer(pan)
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
copiedView.addGestureRecognizer(tap)
objects.append(copiedView)
drawView.addSubview(copiedView)
currentView = copiedView
print("Copied object, total objects: \(objects.count)")
}
func captureFullScreenshot() -> UIImage {
let allFrames = Set(objects.map { $0.frame }) // Unique frames only
let expandedBounds = allFrames.reduce(drawView.bounds) { $0.union($1) }
let renderer = UIGraphicsImageRenderer(bounds: expandedBounds)
return renderer.image { context in
context.cgContext.translateBy(x: -expandedBounds.origin.x, y: -expandedBounds.origin.y)
// Render drawView first (background)
drawView.layer.render(in: context.cgContext)
// Ensure each object is rendered only once
var drawnObjects = Set<UIImageView>()
for imageView in objects where !drawnObjects.contains(imageView) {
let convertedFrame = drawView.convert(imageView.frame, from: view)
context.cgContext.translateBy(x: convertedFrame.origin.x, y: convertedFrame.origin.y)
imageView.layer.render(in: context.cgContext)
context.cgContext.translateBy(x: -convertedFrame.origin.x, y: -convertedFrame.origin.y)
drawnObjects.insert(imageView) // Mark as drawn
}
}
}
@objc func handlePanGestured(_ gesture: UIPanGestureRecognizer) {
guard let draggedView = gesture.view else { return }
let translation = gesture.translation(in: view)
draggedView.center = CGPoint(x: draggedView.center.x + translation.x,
y: draggedView.center.y + translation.y)
gesture.setTranslation(.zero, in: view)
// Update the object position in objects array
if let index = objects.firstIndex(of: draggedView as! UIImageView) {
objects[index].frame = draggedView.frame
}
currentView = draggedView
}
@objc func circleBox() {
// Create a UIImageView for the circle
let subview = UIImageView()
// Enable interaction with the subview
subview.isUserInteractionEnabled = true
objects.append(subview)
view.addSubview(subview)
// Set the frame for the circle (must be a square, so equal width and height)
let size: CGFloat = 80 // Define size of the circle
subview.frame = CGRect(x: view.bounds.midX, y: view.bounds.midY + CGFloat(ww), width: size, height: size)
subview.backgroundColor = UIColor.orange
// Make the UIImageView a circle by setting the cornerRadius to half of the width/height
subview.layer.cornerRadius = size / 2
subview.clipsToBounds = true // Ensures the circle shape is maintained
// Add a border to the subview
subview.layer.borderWidth = 2.0 // Set the border width
subview.layer.borderColor = UIColor.black.cgColor // Set the border color
// Add pan and tap gesture recognizers
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:)))
subview.addGestureRecognizer(pan)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:)))
subview.addGestureRecognizer(tapGesture)
// Create and add bottom label for width (initially set to 3)
let bottomLabel = UILabel()
bottomLabel.text = "3"
bottomLabel.textAlignment = .center
bottomLabel.frame = CGRect(
x: (subview.bounds.width - 50) / 2, // Center horizontally
y: subview.bounds.height - 20, // Align at the bottom
width: 50,
height: 20
)
subview.addSubview(bottomLabel)
// Create and add left label for height (initially set to 1)
let leftLabel = UILabel()
leftLabel.text = "1"
leftLabel.textAlignment = .center
leftLabel.frame = CGRect(
x: 0, // Align to the left edge
y: (subview.bounds.height - 20) / 2, // Center vertically
width: 50,
height: 20
)
subview.addSubview(leftLabel)
// Automatically select the new circle
currentView = subview
}
func createToolbar() -> UIToolbar {
let toolbar = UIToolbar()
toolbar.sizeToFit()
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTapped))
toolbar.items = [flexSpace, doneButton]
return toolbar
}
@objc func libraryBUttonFunction() {
print("Library Button Selected")
// Replace `YourViewController` with the name of the view controller you want to present
let destinationVC = Second()
// Customize the modal presentation style (optional)
destinationVC.modalPresentationStyle = .fullScreen // or .overFullScreen, .pageSheet, etc.
// Present the view controller modally
self.present(destinationVC, animated: true, completion: nil)
}
@objc func doneButtonTapped() {
view.endEditing(true)
}
@objc func saveData() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let context = appDelegate.persistentContainer.viewContext
guard let nameText = txt.text, !nameText.isEmpty else {
print("Text field is empty")
return
}
// Capture the drawing from drawView as an image
let drawingImage = captureFullScreenshot()
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Name")
fetchRequest.predicate = NSPredicate(format: "nameOfPic == %@", nameText)
do {
let results = try context.fetch(fetchRequest)
if let existingEntry = results.first {
// Update the existing entry
existingEntry.setValue(nameText, forKey: "nameOfPic")
existingEntry.setValue(drawingImage.pngData(), forKey: "pic")
} else {
// Create a new entry
let entity = NSEntityDescription.entity(forEntityName: "Name", in: context)!
let newEntry = NSManagedObject(entity: entity, insertInto: context)
newEntry.setValue(nameText, forKey: "nameOfPic")
newEntry.setValue(drawingImage.pngData(), forKey: "pic")
}
try context.save()
print("Data saved successfully.")
// Save image to the photo gallery
UIImageWriteToSavedPhotosAlbum(drawingImage, self, #selector(imageSaved(_:didFinishSavingWithError:contextInfo:)), nil)
// Notify Second about the save and update its list
libraryBUttonFunction()
} catch {
print("Failed to save data: \(error.localizedDescription)")
}
print("Saving screenshot with \(objects.count) objects.")
}
// Completion handler for image saving
@objc func imageSaved(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
print("Error saving image: \(error.localizedDescription)")
} else {
print("Image saved to photo gallery successfully.")
}
}
@objc func handleTapGestured(_ gesture: UITapGestureRecognizer) {
currentView = gesture.view
// Set slider value to match the size of the selected box
}
}
extension UIView {
/// Takes a screenshot of a UIView, with an option to clip to view bounds and place a waterwark image
/// - Parameter rect: offset and size of the screenshot to take
/// - Parameter clipToBounds: Bool to check where self.bounds and rect intersect and adjust size so there is no empty space
/// - Parameter watermark: UIImage of the watermark to place on top
func screenshot(for rect: CGRect, clipToBounds: Bool = true, with watermark: UIImage? = nil) -> UIImage {
var imageRect = rect
if clipToBounds {
imageRect = bounds.intersection(rect)
}
return UIGraphicsImageRenderer(bounds: imageRect).image { _ in
drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
watermark?.draw(in: CGRect(x: 0, y: 0, width: 32, height: 32))
}
}
}
Share
Improve this question
edited Mar 16 at 22:54
Sam Burns
asked Mar 13 at 0:55
Sam BurnsSam Burns
271 silver badge13 bronze badges
1 Answer
Reset to default 0 +50Sounds like the screenshot is picking up duplicated UIImageView
copies because drawHierarchy
renders everything in the view hierarchy, even what you don’t see on screen. Try switching to layer.render
and ensure copied views are fresh instances rather t cloned references.
Try this:
func takeScreenshot() -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: view.bounds)
return renderer.image { ctx in
view.layer.render(in: ctx.cgContext) // Renders what’s actually there
}
}
@objc func copyButtonTapped() {
guard let orig = objects.first else { return }
let copy = UIImageView(image: orig.image) // Fresh copy, no baggage
copy.frame = orig.frame.offsetBy(dx: 20, dy: 20)
view.addSubview(copy)
objects.append(copy)
}
@objc func saveButtonTapped() {
let shot = takeScreenshot()
UIImageWriteToSavedPhotosAlbum(shot, nil, nil, nil)
}
本文标签: swiftScreenshot duplicating copied imagesStack Overflow
版权声明:本文标题:swift - Screenshot duplicating copied images - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744724132a2621870.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论