Add "filter" buttons to Scrollview - ios

I'm new to swift and i'm learning the language with re-creating an Instagram kind of app. I have a problem with the filters. When i run it on the simulator everything works fine except of the scrollview. it should show all the filters like it is on the Instagram app. but it only shows 1 filter (the last one of CIFilternames) how can i get the other filters as a button next to the one which is there?
in the Scrollview should be more filters than one
var CIFilterNames = [
"CIPhotoEffectChrome",
"CIPhotoEffectFade",
"CIPhotoEffectInstant",
"CIPhotoEffectNoir",
"CIPhotoEffectProcess",
"CIPhotoEffectTonal",
"CIPhotoEffectTransfer",
"CISepiaTone",
"CIPhotoEffectInstant",
]
override func viewDidLoad() {
super.viewDidLoad()
imageview.image = receivedImage
var xCoord: CGFloat = 5
let yCoord: CGFloat = 10
let buttonWidth:CGFloat = 70
let gapBetweenButtons: CGFloat = 5
var itemCount = 0
for i in 0..<CIFilterNames.count {
itemCount = i
// Button properties
let filterButton = UIButton(type: .custom)
filterButton.frame = CGRect(x: 5, y: 10, width: 70, height: 70)
filterButton.tag = itemCount
filterButton.addTarget(self, action: #selector(secendTestViewController.filterButtonTapped(sender:)), for: .touchUpInside)
filterButton.layer.cornerRadius = 6
filterButton.clipsToBounds = true
// Create filters for each button
let ciContext = CIContext(options: nil)
let coreImage = CIImage(image: receivedImage)
let filter = CIFilter(name: "\(CIFilterNames[i])" )
filter!.setDefaults()
filter!.setValue(coreImage, forKey: kCIInputImageKey)
let filteredImageData = filter!.value(forKey: kCIOutputImageKey) as! CIImage
let filteredImageRef = ciContext.createCGImage(filteredImageData, from: filteredImageData.extent)
let imageForButton = UIImage(cgImage: filteredImageRef!);
filterButton.setBackgroundImage(imageForButton, for: .normal)
// Add Buttons in the Scroll View
xCoord += buttonWidth + gapBetweenButtons
filterScrollView.addSubview(filterButton)
} // END FOR LOOP
// Resize Scroll View
filterScrollView.contentSize = CGSize(buttonWidth * CGFloat(itemCount + 2), yCoord)
}
func filterButtonTapped(sender: UIButton) {
let button = sender as UIButton
imageToFilter.image = button.backgroundImage(for: UIControlState.normal)
}

I think your problem is filterButton frame.
try this
filterButton.frame = CGRect(x: xCoord, y: 10, width: 70, height: 70)

Related

How to define CAAnimation repeat count correctly in the UIView?

I want to create animations that includes a few UIImage objects. In the light of out investigations I am trying to add animations to layer of UIImages.
As you can see below codes, I created animations for each UIImages and added these animations to UIImages layers. And after that I added all of these UIImages to UIView to be a subviews.
The problem is that when I added this animation class(It inherited from a UIView) to another view, it works according to determined animations properties. But the animation works only one time. Actually I want that the animation repeats until I stop it. If I want to determine repeat count for each animations, they are working asynchronous. It doesn't animate in the right order.
Finally I have to refresh all animations in related view or I have to calculate animation duration, I don't know may be I used wrong way.
How can I solve this problem? Or may you share with me, if is there any different approach?
import UIKit
class ActivityIndicator: UIView {
// MARK: - Initialization
init()
{
super.init(frame: CGRect(x: 50, y: 300, width: 144, height: 124))
self.setupLayers()
}
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
self.setupLayers()
}
// MARK: - I added some UIImage and their animations. Begin times are nested.
private func setupLayers() {
let repeatCount:Float = 0
let yellowBubble = UIImageView(image: #imageLiteral(resourceName: "yellowBubble"))
yellowBubble.frame = CGRect(x: 11.8, y: 0, width: 132.084549, height: 104.150719)
yellowBubble.contentMode = .scaleAspectFill
yellowBubble.layer.contentsGravity = CALayerContentsGravity.center
let blackBubble = UIImageView(image: #imageLiteral(resourceName: "blackBubble"))
blackBubble.frame = CGRect(x: 0, y: 17.685972, width:132.084549, height: 104.150719)
blackBubble.contentMode = .scaleAspectFill
blackBubble.layer.contentsGravity = CALayerContentsGravity.center
let shadowLine = UIImageView(image: #imageLiteral(resourceName: "shadowBubble"))
shadowLine.frame = CGRect(x: 0, y: 17.685972, width: 132.084549, height: 86.464752)
shadowLine.contentMode = .scaleAspectFill
shadowLine.layer.contentsGravity = CALayerContentsGravity.center
let textAndSign = UIImageView(image: #imageLiteral(resourceName: "logoAndSign"))
textAndSign.frame = CGRect(x: 28.82774, y: 44.301903, width: 81, height: 44)
textAndSign.contentMode = .scaleAspectFill
textAndSign.layer.contentsGravity = CALayerContentsGravity.center
// Animations have a few properties that includes duration,beginTime etc.
let allLogoAnimation = CASpringAnimation()
allLogoAnimation.beginTime = self.layer.convertTime(CACurrentMediaTime(), from: nil) + 2
allLogoAnimation.duration = 3
allLogoAnimation.repeatCount = repeatCount
allLogoAnimation.fillMode = CAMediaTimingFillMode.forwards
allLogoAnimation.keyPath = "transform.rotation.z"
allLogoAnimation.toValue = 0
allLogoAnimation.fromValue = 15
self.layer.add(allLogoAnimation, forKey: "allLogoAnimation")
let yellowBubbleAnimation = CASpringAnimation()
yellowBubbleAnimation.beginTime = self.layer.convertTime(CACurrentMediaTime(), from: nil)
yellowBubbleAnimation.duration = 3
yellowBubbleAnimation.repeatCount = repeatCount
yellowBubbleAnimation.speed = 1.2
yellowBubbleAnimation.fillMode = CAMediaTimingFillMode.forwards
yellowBubbleAnimation.keyPath = "transform.translation.y"
yellowBubbleAnimation.toValue = 0
yellowBubbleAnimation.fromValue = -70
yellowBubble.layer.add(yellowBubbleAnimation, forKey: "yellowBubbleAnimation")
let blackBubbleAnimation = CASpringAnimation()
blackBubbleAnimation.beginTime = self.layer.convertTime(CACurrentMediaTime(), from: nil) + 0.3
blackBubbleAnimation.duration = 3
yellowBubbleAnimation.repeatCount = repeatCount
blackBubbleAnimation.speed = 1.2
blackBubbleAnimation.fillMode = CAMediaTimingFillMode.forwards
blackBubbleAnimation.keyPath = "transform.translation.x"
blackBubbleAnimation.toValue = 0
blackBubbleAnimation.fromValue = -70
blackBubble.layer.add(blackBubbleAnimation, forKey: "blackBubbleAnimation")
let shadowLineAnimation = CASpringAnimation()
shadowLineAnimation.beginTime = self.layer.convertTime(CACurrentMediaTime(), from: nil) + 0.6
shadowLineAnimation.duration = 3
shadowLineAnimation.repeatCount = repeatCount
shadowLineAnimation.speed = 1.2
shadowLineAnimation.fillMode = CAMediaTimingFillMode.forwards
shadowLineAnimation.keyPath = "transform.translation.x"
shadowLineAnimation.toValue = 0
shadowLineAnimation.fromValue = 70
shadowLine.layer.add(shadowLineAnimation, forKey: "shadowLineAnimation")
let textAndSignScaleAnimation = CASpringAnimation()
textAndSignScaleAnimation.beginTime = self.layer.convertTime(CACurrentMediaTime(), from: nil) + 1
textAndSignScaleAnimation.duration = 3
textAndSignScaleAnimation.repeatCount = repeatCount
textAndSignScaleAnimation.fillMode = CAMediaTimingFillMode.forwards
textAndSignScaleAnimation.keyPath = "transform.scale.xy"
textAndSignScaleAnimation.toValue = 1
textAndSignScaleAnimation.fromValue = 3
textAndSign.layer.add(textAndSignScaleAnimation, forKey: "textAndSignScaleAnimation")
let textAndSignOpacityAnimation = CASpringAnimation()
textAndSignOpacityAnimation.beginTime = self.layer.convertTime(CACurrentMediaTime(), from: nil) + 1
textAndSignOpacityAnimation.duration = 3
textAndSignOpacityAnimation.repeatCount = repeatCount
textAndSignOpacityAnimation.fillMode = CAMediaTimingFillMode.forwards
textAndSignOpacityAnimation.keyPath = "opacity"
textAndSignOpacityAnimation.toValue = 1
textAndSignOpacityAnimation.fromValue = 0
textAndSign.layer.add(textAndSignOpacityAnimation, forKey: "textAndSignOpacityAnimation")
self.layer.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.layer.contentsGravity = CALayerContentsGravity.center
self.backgroundColor = .clear
// I added all UIImages to ActivityIndicatorView
self.addSubviews(yellowBubble,blackBubble,shadowLine,textAndSign)
}
}
After that I added a animation view to my view controller.
override func viewWillAppear(_ animated: Bool) {
let activityView = ActivityIndicator()
activityView.backgroundColor = .clear
self.view.addSubview(activityView)
}

CAEmitterLayer not timing correctly with CACurrentMediaTime() and sometimes not showing at all

I am currently making a particle emitter using CAEmitterLayer and ran into the issue of the layer preloading the animation when I start it and hence the particles all over the place when I show it.
Many answers have said the culprit is CAEmitterLayer being preloaded and we simply have to set its beginTime to CACurrentMediaTime() on the emitter.
See:
CAEmitterLayer emits random unwanted particles on touch events
Initial particles from CAEmitterLayer don't start at emitterPosition
iOS 7 CAEmitterLayer spawning particles inappropriately
For me this solution has not worked, when running it on device, iPad Air running iOS 12.1, the emitter often does not show and sometimes it is showed with a great delay.
To illustrate this issue I made a project on github:
https://github.com/roodoodey/CAEmitterLayer/tree/master/CAEmitterLayerApp
Here is the main code, I have 7 different images for particles chosen at random and a button to show the emitter when pressed.
import UIKit
class ViewController: UIViewController {
var particleImages = [UIImage]()
var emitter: CAEmitterLayer?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.backgroundColor = UIColor.black
// Populate the random images array for the particles
for index in 1..<8 {
if let image = UIImage(named: "StarParticle00\(index)") {
particleImages.append(image)
}
}
// Button pressed to make the emitter emit the particles
let button = UIButton(frame: CGRect(x: view.frame.width * 0.5 - 60, y: view.frame.height * 0.5 - 40, width: 120, height: 80))
button.setTitle("Emit!", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.backgroundColor = UIColor.blue
button.addTarget(self, action: #selector(changeButton(sender:)), for: .touchDown)
button.addTarget(self, action: #selector(addEmitter(sender:)), for: .touchUpInside)
view.addSubview(button)
}
#objc func changeButton(sender: UIButton) {
sender.alpha = 0.5
}
#objc func addEmitter(sender: UIButton) {
sender.alpha = 1.0
// IF an emitter already exists remove it.
if emitter?.superlayer != nil {
emitter?.removeFromSuperlayer()
}
emitter = CAEmitterLayer()
emitter?.emitterShape = CAEmitterLayerEmitterShape.point
emitter?.position = CGPoint(x: self.view.frame.width * 0.5, y: self.view.frame.height * 0.5)
// So that the emitter starts now, and is not preloaded.
emitter?.beginTime = CACurrentMediaTime()
var cells = [CAEmitterCell]()
for _ in 0..<40 {
let cell = CAEmitterCell()
cell.birthRate = 1
cell.lifetime = 3
cell.lifetimeRange = 0.5
cell.velocity = 500
cell.velocityRange = 100
cell.emissionRange = 2 * CGFloat(Double.pi)
cell.contents = getRandomImage().cgImage
cell.scale = 1
cell.scaleRange = 0.5
cells.append(cell)
}
emitter?.emitterCells = cells
view.layer.addSublayer( emitter! )
}
func getRandomImage() -> UIImage {
let upperBound = UInt32(particleImages.count)
let randomIndex = Int(arc4random_uniform( upperBound ))
return particleImages[randomIndex]
}
}
Here is a short 20 second video of the app running on device, iPad Air running iOS 12.1, not run through xcode. https://www.dropbox.com/s/f9uol3yot67drm8/ScreenRecording_11-25-2018%2013-19-29.MP4?dl=0
If somebody could see if they can reproduce this issue or shed some light on this strange behavior it would be greatly appreciated.
I have a ton of experience with Core Animation although I have to admit not a lot with CAEmitterLayer. Everything looks right and for a person that knows CALayer pretty well, setting the beginTime with CACurrentMediaTime() makes sense. However, I ran your project and saw it was not working. For me setting the beginTime on the cell had the effect I would expect.
Meaning
//delay for 5.0 seconds
cell.beginTime = CACurrentMediaTime() + 5.0
cell.beginTime = CACurrentMediaTime() //immediate
cell.beginTime = CACurrentMediaTime() - 5.0 //5 seconds ago
Entire File
import UIKit
class ViewController: UIViewController {
var particleImages = [UIImage]()
var emitter: CAEmitterLayer?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.backgroundColor = UIColor.black
// Populate the random images array for the particles
for index in 1..<8 {
if let image = UIImage(named: "StarParticle00\(index)") {
particleImages.append(image)
}
}
// Button pressed to make the emitter emit the particles
let button = UIButton(frame: CGRect(x: view.frame.width * 0.5 - 60, y: view.frame.height * 0.5 - 40, width: 120, height: 80))
button.setTitle("Emit!", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.backgroundColor = UIColor.blue
button.addTarget(self, action: #selector(changeButton(sender:)), for: .touchDown)
button.addTarget(self, action: #selector(addEmitter(sender:)), for: .touchUpInside)
view.addSubview(button)
}
#objc func changeButton(sender: UIButton) {
sender.alpha = 0.5
}
#objc func addEmitter(sender: UIButton) {
sender.alpha = 1.0
// IF an emitter already exists remove it.
if emitter?.superlayer != nil {
emitter?.removeFromSuperlayer()
}
emitter = CAEmitterLayer()
emitter?.emitterShape = CAEmitterLayerEmitterShape.point
emitter?.position = CGPoint(x: self.view.frame.width * 0.5, y: self.view.frame.height * 0.5)
// So that the emitter starts now, and is not preloaded.
var cells = [CAEmitterCell]()
for _ in 0..<40 {
let cell = CAEmitterCell()
cell.birthRate = 1
cell.lifetime = 3
cell.lifetimeRange = 0.5
cell.velocity = 500
cell.velocityRange = 100
cell.emissionRange = 2 * CGFloat(Double.pi)
cell.contents = getRandomImage().cgImage
cell.scale = 1
cell.scaleRange = 0.5
cell.beginTime = CACurrentMediaTime()
cells.append(cell)
}
emitter?.emitterCells = cells
view.layer.addSublayer( emitter! )
}
func getRandomImage() -> UIImage {
let upperBound = UInt32(particleImages.count)
let randomIndex = Int(arc4random_uniform( upperBound ))
return particleImages[randomIndex]
}
}

Running CAEmitterLayer only once

I want to run CAEmitterLayer only once, I was thinking of stopping birthRate but I can't do it. What I want is for it to run only once when tapping on the screen. I've been trying with delegates but I can't get it to work. And could you please tell me if my code is efficient.
import UIKit
import PlaygroundSupport
class Emitter {
static func get(with image: UIImage) -> CAEmitterLayer {
let emitter = CAEmitterLayer()
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterCells = generateEmitterCells(image: image)
print("emit")
emitter.setValue(0.0, forKey: "em")
return emitter
}
static func generateEmitterCells(image: UIImage) -> [CAEmitterCell] {
var cells = [CAEmitterCell]()
let cell = CAEmitterCell()
cell.contents = image.cgImage
cell.birthRate = 0.1
cell.lifetime = 20
cell.velocity = 250
cell.emissionRange = (10 * (.pi/180))
cell.scale = 0.9
cell.scaleRange = 0.3
cell.velocityRange = 100
cells.append(cell)
print("cells")
return cells
}
}
class ViewController : UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
let view2 = UIView(frame: self.view.frame)
self.view.frame = CGRect(x: 0, y: 0, width: 320, height: 580)
super.view.backgroundColor = UIColor.white
self.view.addSubview(view2)
}
#objc func handleTap() {
rain()
}
func rain() {
let emitter = Emitter.get(with: UIImage(named: "Group 1493")!)
emitter.emitterPosition = CGPoint(x: view.frame.width / 2, y: view.frame.height + 25)
emitter.emitterSize = CGSize(width: view.frame.width, height: 2)
self.view.layer.addSublayer(emitter)
}
}
let controller = ViewController()
PlaygroundPage.current.liveView = controller.view
You could set lifetime propertie to 0 after first splash
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
emitter.lifetime = 0
}
You need to do a few things.
You need to CAEmitterLayer's beginTime: emitter.beginTime = CACurrentMediaTime()
To stop new particles birth you need to set emitter.birthRate = 0. You can delay it using GCD to create this splash effect.

Horizontal ScrollView not fit its sub ImageViews?

I want horizontal scrollview with image view but image is not fitting with the scroll. i am doing this code but not getting the right thing
Here is my code
#IBOutlet weak var upperScroll: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
// Do any additional setup after loading the view.
var logoImage: [UIImage] = [
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
]
upperScroll.isScrollEnabled = true
let scrollWidth: Int = Int(self.view.frame.width)
upperScroll.contentSize = CGSize(width: CGFloat(scrollWidth), height:(self.upperScroll.frame.height))
upperScroll.frame = CGRect(x: 0, y: 51, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height)
upperScroll.backgroundColor = UIColor.red
var xOffset: Int = 0
for index in 0..<logoImage.count {
let img = UIImageView(frame: CGRect(x: CGFloat(xOffset), y: 0, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height))
img.image = logoImage[index]
upperScroll.addSubview(img)
xOffset += 100
}
view.addSubview(upperScroll)
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth + xOffset)), height: 110)
}
but i want this
Can anyone please help me? Thanks
Just remove your appdelegate code and add my fuction
also set scrollview constraint like leading,trailing,top,bottom Zero
func scrollImage() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
// Do any additional setup after loading the view.
var logoImage: [UIImage] = [
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!]
upperScroll.isPagingEnabled = true
upperScroll.isScrollEnabled = true
let scrollWidth: Int = Int(self.view.frame.width)
,
upperScroll.contentSize = CGSize(width: CGFloat(scrollWidth), height:(self.upperScroll.frame.height))
print(upperScroll.frame.size.width)
upperScroll.backgroundColor = UIColor.red
for index in 0..<logoImage.count {
let xPosition = self.view.frame.width * CGFloat(index)
upperScroll.layoutIfNeeded()
let img = UIImageView(frame: CGRect(x: CGFloat(xPosition), y: 0, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height))
img.layoutIfNeeded()
img.image = logoImage[index]
upperScroll.addSubview(img)
}
view.addSubview(upperScroll)
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth) * logoImage.count), height: self.upperScroll.frame.height)
}
I hope it's save your time and working great
According to your requirement, the xOffset += 100 should be changed to xOffset += scrollWidth. And contents size set to:
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth * logoImage.count)), height: 110)
And remember to enable the pagination for scroll view.
First of all, you need two outlet for scroll view and PageControl,
var contentWidth:CGFloat = 0.0
// MARK: - Welcome screen with scroll view use page controll
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
scrollView.delegate = self
let myImages = ["intro1_1.png", "intro2_2.png", "intro3_3.png"] // images which loaded in assets
let imageWidth:CGFloat = view.frame.width
let imageHeight:CGFloat = view.frame.height
var xPosition:CGFloat = 0 //setup your position
var scrollViewSize:CGFloat=0 //setup your position
for image in myImages {
let myImage:UIImage = UIImage(named: image)!
let myImageView:UIImageView = UIImageView()
myImageView.image = myImage
myImageView.frame.size.width = imageWidth
myImageView.frame.size.height = imageHeight
myImageView.frame.origin.x = xPosition
myImageView.frame.origin.y = 0
scrollView.addSubview(myImageView)
xPosition += imageWidth
scrollViewSize += imageWidth
}
scrollView.contentSize = CGSize(width: scrollViewSize, height: imageHeight)
scrollView.contentSize = CGSize(width: view.frame.width * 3, height: view.frame.height) //here you setup how many pages in scroll will
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageWidth:CGFloat = scrollView.frame.width
let currentPage:CGFloat = floor((scrollView.contentOffset.x-pageWidth / 2)/pageWidth)+1
self.pageControll.currentPage = Int(currentPage)
}
hope, i help u

Annotation(Image & Text) subviews changes position after saving

I have created a PDF based application. Firstly, I get the PDF from document directory then convert it to Images and then programmatically set all images to vertically by using UIImageView & ScrollView.
Then I set different type of annotation like sign, text etc. When I finalised it to images and convert them to PDF with good result. I get different results as shown in below images.
Screen 1: convert original image size to UIImageView Size with aspect to fit ( because i have look like this type of screen) when i have convert original size to screen size at that time i have stored image original size and its used to when i have convert images to pdf after add annotation looking in screen 2.
Screen 2. when i have finalise or convert to pdf. result look in screen 2, change annotation or sign position.
let drawImage = jotViewController.renderImage() //sign image
signImg = drawImage
gestureView = UIView(frame: CGRect(x: 50, y: 300, width: 200, height: 110))
counter = counter + 1
gestureView.tag = counter
annotationImg = UIImageView(frame: CGRect(x: 0, y: 0, width:170, height: 80))
annotationImg.image = signImg
annotationImg.layer.cornerRadius = 5.0
// gestureView.frame = annotationImg.frame
cancelBtn.frame = CGRect(x: (annotationImg.frame.minX-10), y: (annotationImg.frame.maxY-10), width: 20, height: 20)
cancelBtn.setImage(#imageLiteral(resourceName: "cancel.png"), for: .normal)
cancelBtn.addTarget(self, action: #selector(cancelBtnAction), for: .touchUpInside)
gestureView.addSubview(cancelBtn)
zoomBtn.frame = CGRect(x: (annotationImg.frame.width-10), y: (annotationImg.frame.height-10), width: 20, height: 20)
zoomBtn.setImage(#imageLiteral(resourceName: "zoom.png"), for: .normal)
gestureView.addSubview(zoomBtn)
let zoomBtnpanGesture: UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(ViewController.zoomBtnPanGesture(_:)))
zoomBtnpanGesture.minimumNumberOfTouches = 1
zoomBtnpanGesture.maximumNumberOfTouches = 1
zoomBtn.addGestureRecognizer(zoomBtnpanGesture)
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.handlePanGesture))
panGesture.minimumNumberOfTouches = 1
panGesture.maximumNumberOfTouches = 1
annotationImg.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
gestureView.addGestureRecognizer(panGesture)
annotationImg.clipsToBounds = true
gestureView.addSubview(annotationImg)
for getUIImageView in pdfUIImageViewArr {
if tag==0 {
let alert = UIAlertController(title: "Alert!!", message: "Please Select Signature Page.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: nil)
}
if getUIImageView.tag == tag && tag != 0 {
getUIImageView.addSubview(gestureView)
}
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(gestureViewTapped(sender:)))
tapGesture.numberOfTapsRequired = 1
gestureView.addGestureRecognizer(tapGesture)
imageViewArr.append(annotationImg)
gestureViewArr.append(gestureView)
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
#IBAction func storeAsPdfAction(_ sender: AnyObject) {
self.storeToDocumentDir()
let userObj = self.storyboard?.instantiateViewController(withIdentifier: "DocumentVC") as? DocumentVC
self.navigationController?.pushViewController(userObj!, animated: true)
}
func storeToDocumentDir(){
print(pdfImage.frame)
print(view.frame)
print(gestureView.frame)
for getTextViewLbl in textViewLabelArr{
getTextViewLbl.backgroundColor = UIColor.clear
}
gestureViewArr.removeFirst()
for gestureView in gestureViewArr {
print(gestureView.frame)
zoomBtn.isHidden = true
cancelBtn.isHidden = true
// pdfImage.addSubview(gestureView)
}
pdfUIImageViewArr.remove(at: 0)
var i = 1
for getPDFImage in pdfUIImageViewArr {
getPDFImage.frame = CGRect(x: 0, y: 0, width: pdfImage.frame.size.width, height: pdfImage.frame.size.height)
getPDFImage.frame = CGRect(x: 0, y: 0, width: pageRect.size.width, height: pageRect.size.height)
getPDFImage.contentMode = UIViewContentMode.scaleToFill
//
let getImage = self.imageWithView(getPDFImage)
let fileManager = FileManager.default
let paths = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("img\(i).jpg")
i += 1
let image = getImage
print(paths)
let imageData = UIImageJPEGRepresentation(image, 0.5)
fileManager.createFile(atPath: paths as String, contents: imageData, attributes: nil)
setPdfImgArr.append(getImage)
}
self.createPdfFromView(pdfImage, imageArrAdd: setPdfImgArr, saveToDocumentsWithFileName: "\((setFileName)!)")
let pdfUrl = URL(fileURLWithPath:documentsFileName)
self.setImagesInScrollView(pdfUrl)
}
Problem Solved :
By Using UIScrollView Zoom:
override func viewWillLayoutSubviews() {
self.configureZoomScale()
}
func configureZoomScale() {
var xZoomScale: CGFloat = self.scrollView.bounds.size.width / self.pdfImage.bounds.size.width
var yZoomScale: CGFloat = self.scrollView.bounds.size.height / self.pdfImage.bounds.size.height
var minZoomScale: CGFloat = min(xZoomScale, yZoomScale)
//set minimumZoomScale to the minimum zoom scale we calculated
//this mean that the image cant me smaller than full screen
self.scrollView.minimumZoomScale = minZoomScale
//allow up to 4x zoom
self.scrollView.maximumZoomScale = 4
//set the starting zoom scale
self.scrollView.zoomScale = minZoomScale
}
func viewForZooming(in scrollView: UIScrollView) -> UIView?{
return pdfFinalImage
}

Resources