How to achieve PIP Effect in iOS Swift app. I tried it but results are not accurate in case of placing and movement of internal picture.
Here is my attempt:
#IBOutlet var galleryImageView: UIImageView!
#IBOutlet var background: UIImageView!
#IBOutlet var behindView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImage(named: "ph3")
let maskingImage = UIImage(named: "mask")
galleryImageView.image = maskImage(image: image!, mask: maskingImage!)
galleryImageView.contentMode = .scaleAspectFill
background.image = UIImage(named: "ph3")?.stackBlur(10)
let maskingLayer = CALayer()
maskingLayer.frame = behindView.bounds
maskingLayer.contents = (galleryImageView.image?.cgImage! as Any)
behindView.layer.mask = maskingLayer
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.panGestureDetected))
panGestureRecognizer.delegate = self
self.galleryImageView.addGestureRecognizer(panGestureRecognizer)
}
func maskImage(image:UIImage, mask:(UIImage))->UIImage{
let imageReference = image.cgImage
let maskReference = mask.cgImage
let imageMask = CGImage(maskWidth: maskReference!.width,
height: maskReference!.height,
bitsPerComponent: maskReference!.bitsPerComponent,
bitsPerPixel: maskReference!.bitsPerPixel,
bytesPerRow: maskReference!.bytesPerRow,
provider: maskReference!.dataProvider!, decode: nil, shouldInterpolate: true)
let maskedReference = imageReference!.masking(imageMask!)
let maskedImage = UIImage(cgImage:maskedReference!)
return maskedImage
}
galleryImageView is the internal imageView
Result should be like:
Related
I'm creating a wallpaper app for iOS. I've created a UIImageView, but am stuck on saving the image. I have solved the permissions but am unable to have the user save the image. I created the save button itself, but I don't know to make save any image from the image array in the user's image gallery.
Here is my code so far:
class ViewController: UIViewController {
#IBOutlet var imageview: [UIScrollView]!
#IBOutlet weak var saveButton: UIButton!
#IBAction func saveButtonPressed(_ sender: UIButton) {
// TODO: - How to save the image here
}
let scrollView: UIScrollView = {
let scroll = UIScrollView()
scroll.isPagingEnabled = true
scroll.showsVerticalScrollIndicator = false
scroll.showsHorizontalScrollIndicator = false
scroll.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
return scroll
}()
var imageArray = [UIImage]()
func setupImages(_ images: [UIImage]){
for i in 0..<images.count {
let imageView = UIImageView()
imageView.image = images[i]
let xPosition = UIScreen.main.bounds.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: 0, width: scrollView.frame.width, height: scrollView.frame.height)
imageView.contentMode = .scaleAspectFit
scrollView.contentSize.width = scrollView.frame.width * CGFloat(i + 1)
scrollView.addSubview(imageView)
//scrollView.delegate = (self as! UIScrollViewDelegate)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.addSubview(scrollView)
imageArray = [#imageLiteral(resourceName: "1"),#imageLiteral(resourceName: "10"),#imageLiteral(resourceName: "9"),#imageLiteral(resourceName: "8"),#imageLiteral(resourceName: "3")]
setupImages(imageArray)
}
}
You will need to add a saveImage function:
func saveImage(image: UIImage) -> Bool {
guard let data = UIImageJPEGRepresentation(image, 1) ?? UIImagePNGRepresentation(image) else {
return false
}
guard let directory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) as NSURL else {
return false
}
do {
try data.write(to: directory.appendingPathComponent("fileName.png")!)
return true
} catch {
print(error.localizedDescription)
return false
}
}
And then in saveButtonPressed:
let success = saveImage(image: imageArray[0])
print("Did \(success ? "" : "not ")store image successfully")
You'll need to add some logic to actually select the image.
I have a small app, a SimpleCamera that shows a live (video) preview, with a button on the screen to take a photo. The photo is then displayed and you can save it or discard it. It all works, and I have used this code to draw a grey border around the screen preview. That too works fine. But that's all I can draw on that preview screen? I can't work out how to add the next bit of code shown below this first code block?
// Provide a camera preview
cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
view.layer.addSublayer(cameraPreviewLayer!)
cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer?.frame = view.layer.frame
//Add preview layer for drawing
let previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
previewLayer.frame = self.view.layer.frame
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.view.layer.addSublayer(previewLayer)
//Add Rectangle
let cgRect = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
let myView = UIImageView()
myView.frame = cgRect
myView.backgroundColor = UIColor.clear
myView.isOpaque = false
myView.layer.cornerRadius = 10
myView.layer.borderColor = UIColor.lightGray.cgColor
myView.layer.borderWidth = 3
myView.layer.masksToBounds = true
previewLayer.addSublayer(myView.layer)
// Bring the camera button to front
view.bringSubview(toFront: cameraButton)
captureSession.startRunning()
No matter where I put this code, it simply doesn't show up.
//Add circles
let midX = screenWidth / 2
let midY = screenHeight / 2
let w = screenWidth
var circlePath = UIBezierPath(arcCenter: CGPoint(x: midX,y: midY), radius: CGFloat(w * 0.010), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)
let circleRads = [ 0.07, 0.13, 0.17, 0.22, 0.29, 0.36, 0.40, 0.48, 0.60, 0.75 ]
for pct in circleRads {
let rad = w * CGFloat(pct)
circlePath = UIBezierPath(arcCenter: CGPoint(x: midX, y: midY), radius: CGFloat(rad), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)
circlePath.lineWidth = 2.5
circlePath.stroke()
}
// draw text time stamp on image
let now = Date()
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let dateString = formatter.string(from: now)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attrs = [NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Thin", size: 26)!, NSAttributedStringKey.paragraphStyle: paragraphStyle]
let string = dateString
string.draw(with: CGRect(x: 12, y: 38, width: 448, height: 448), options: .usesLineFragmentOrigin, attributes: attrs, context: nil)
Part answered. I can draw a Border around the entire screen. This is the SimpleCamera app from the AppCoda Swift 4 Intermediate iOS 11 Book. This is the code for the CameraController.swift file, and the Border drawing section is Line 176 to Line 192 when opened in XCode.
But I still can't figure out how to make the commented section draw a set of circles, and put a date stamp on the image, and save it.
//
// CameraController.swift
// Camera
//
// Created by Simon Ng on 16/10/2016.
// Copyright © 2016 AppCoda. All rights reserved.
//
import UIKit
import AVFoundation
import Foundation
class CameraController: UIViewController {
#IBOutlet var cameraButton:UIButton!
//===================================
#IBOutlet weak var navigationBar: UINavigationBar!
#IBOutlet weak var imgOverlay: UIImageView!
#IBOutlet weak var btnCapture: UIButton!
#IBOutlet weak var btnInfo: UIButton!
#IBOutlet weak var btnSocial: UIButton!
#IBOutlet weak var shapeLayer: UIView!
#IBOutlet weak var btnRed: UIButton!
#IBOutlet weak var btnGreen: UIButton!
#IBOutlet weak var btnBlue: UIButton!
#IBOutlet weak var btnYellow: UIButton!
#IBOutlet weak var btnWhite: UIButton!
//===================================
var backFacingCamera: AVCaptureDevice?
var frontFacingCamera: AVCaptureDevice?
var currentDevice: AVCaptureDevice!
var stillImageOutput: AVCapturePhotoOutput!
var stillImage: UIImage?
var cameraPreviewLayer: AVCaptureVideoPreviewLayer?
let captureSession = AVCaptureSession()
var toggleCameraGestureRecognizer = UISwipeGestureRecognizer()
var zoomInGestureRecognizer = UISwipeGestureRecognizer()
var zoomOutGestureRecognizer = UISwipeGestureRecognizer()
//===============================
//let stillImageOutput = AVCaptureStillImageOutput()
var previewLayer : AVCaptureVideoPreviewLayer?
let screenWidth = UIScreen.main.bounds.size.width
let screenHeight = UIScreen.main.bounds.size.height
var aspectRatio: CGFloat = 1.0
var viewFinderHeight: CGFloat = 0.0
var viewFinderWidth: CGFloat = 0.0
var viewFinderMarginLeft: CGFloat = 0.0
var viewFinderMarginTop: CGFloat = 0.0
var lineColor : UIColor?
var color: Int = 0
//==============================
override func viewDidLoad() {
super.viewDidLoad()
configure()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Action methods
#IBAction func capture(sender: UIButton) {
// Set photo settings
let photoSettings = AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])
photoSettings.isAutoStillImageStabilizationEnabled = true
photoSettings.isHighResolutionPhotoEnabled = true
photoSettings.flashMode = .off
stillImageOutput.isHighResolutionCaptureEnabled = true
stillImageOutput.capturePhoto(with: photoSettings, delegate: self)
}
// MARK: - Segues
#IBAction func unwindToCameraView(segue: UIStoryboardSegue) {
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "showPhoto" {
let photoViewController = segue.destination as! PhotoViewController
photoViewController.image = stillImage
}
}
// MARK: - Helper methods
private func configure() {
// Preset the session for taking photo in full resolution
captureSession.sessionPreset = AVCaptureSession.Preset.photo
// Get the front and back-facing camera for taking photos
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .unspecified)
for device in deviceDiscoverySession.devices {
if device.position == .back {
backFacingCamera = device
} else if device.position == .front {
frontFacingCamera = device
}
}
currentDevice = backFacingCamera
guard let captureDeviceInput = try? AVCaptureDeviceInput(device: currentDevice) else {
return
}
// Configure the session with the output for capturing still images
stillImageOutput = AVCapturePhotoOutput()
// Configure the session with the input and the output devices
captureSession.addInput(captureDeviceInput)
captureSession.addOutput(stillImageOutput)
// Provide a camera preview
cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
view.layer.addSublayer(cameraPreviewLayer!)
cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
cameraPreviewLayer?.frame = view.layer.frame
//////////////
//Add circles
// red circles - radius in %
/*
let midX = screenWidth / 2
let midY = screenHeight / 2
let w = screenWidth
//let h = screenHeight
var circlePath = UIBezierPath(arcCenter: CGPoint(x: midX,y: midY), radius: CGFloat(w * 0.010), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)
let circleRads = [ 0.07, 0.13, 0.17, 0.22, 0.29, 0.36, 0.40, 0.48, 0.60, 0.75 ]
for pct in circleRads {
let rad = w * CGFloat(pct)
circlePath = UIBezierPath(arcCenter: CGPoint(x: midX, y: midY), radius: CGFloat(rad), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)
circlePath.lineWidth = 2.5
circlePath.stroke()
}
// draw text time stamp on image
let now = Date()
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let dateString = formatter.string(from: now)
// print(dateString)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attrs = [NSAttributedStringKey.font: UIFont(name: "HelveticaNeue-Thin", size: 26)!, NSAttributedStringKey.paragraphStyle: paragraphStyle]
let string = dateString
string.draw(with: CGRect(x: 22, y: 18, width: 448, height: 448), options: .usesLineFragmentOrigin, attributes: attrs, context: nil)
print("Did the date")
*/
//Add Rectangular border
let previewLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
previewLayer.frame = self.view.layer.frame
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.view.layer.addSublayer(previewLayer)
let cgRect = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height)
let myView = UIImageView()
myView.frame = cgRect
myView.backgroundColor = UIColor.clear
myView.isOpaque = false
myView.layer.cornerRadius = 10
myView.layer.borderColor = UIColor.lightGray.cgColor
myView.layer.borderWidth = 3
myView.layer.masksToBounds = true
previewLayer.addSublayer(myView.layer)
///////////////
// Bring the camera button to front
view.bringSubview(toFront: cameraButton)
captureSession.startRunning()
print("so far 2")
// Toggle Camera recognizer
toggleCameraGestureRecognizer.direction = .up
toggleCameraGestureRecognizer.addTarget(self, action: #selector(toggleCamera))
view.addGestureRecognizer(toggleCameraGestureRecognizer)
// Zoom In recognizer
zoomInGestureRecognizer.direction = .right
zoomInGestureRecognizer.addTarget(self, action: #selector(zoomIn))
view.addGestureRecognizer(zoomInGestureRecognizer)
// Zoom Out recognizer
zoomOutGestureRecognizer.direction = .left
zoomOutGestureRecognizer.addTarget(self, action: #selector(zoomOut))
view.addGestureRecognizer(zoomOutGestureRecognizer)
}
#objc func toggleCamera() {
captureSession.beginConfiguration()
// Change the device based on the current camera
guard let newDevice = (currentDevice?.position == AVCaptureDevice.Position.back) ? frontFacingCamera : backFacingCamera else {
return
}
// Remove all inputs from the session
for input in captureSession.inputs {
captureSession.removeInput(input as! AVCaptureDeviceInput)
}
// Change to the new input
let cameraInput:AVCaptureDeviceInput
do {
cameraInput = try AVCaptureDeviceInput(device: newDevice)
} catch {
print(error)
return
}
if captureSession.canAddInput(cameraInput) {
captureSession.addInput(cameraInput)
}
currentDevice = newDevice
captureSession.commitConfiguration()
}
#objc func zoomIn() {
if let zoomFactor = currentDevice?.videoZoomFactor {
if zoomFactor < 5.0 {
let newZoomFactor = min(zoomFactor + 1.0, 5.0)
do {
try currentDevice?.lockForConfiguration()
currentDevice?.ramp(toVideoZoomFactor: newZoomFactor, withRate: 1.0)
currentDevice?.unlockForConfiguration()
} catch {
print(error)
}
}
}
}
#objc func zoomOut() {
if let zoomFactor = currentDevice?.videoZoomFactor {
if zoomFactor > 1.0 {
let newZoomFactor = max(zoomFactor - 1.0, 1.0)
do {
try currentDevice?.lockForConfiguration()
currentDevice?.ramp(toVideoZoomFactor: newZoomFactor, withRate: 1.0)
currentDevice?.unlockForConfiguration()
} catch {
print(error)
}
}
}
}
}
extension CameraController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
guard error == nil else {
return
}
// Get the image from the photo buffer
guard let imageData = photo.fileDataRepresentation() else {
return
}
stillImage = UIImage(data: imageData)
performSegue(withIdentifier: "showPhoto", sender: self)
}
}
You need a CAShapeLayer to add the bezierpath to.
let circleLayer = CAShapeLayer()
circleLayer.path = circlePath.cgPath
self.view.layer.addSublayer(circleLayer)
Right now my code displays a image like this
It would work if I could just rotate the image clockwise 90 degrees. How would I do this. Code is listed below. I took out some of the unnecessary lines of code for this.
import UIKit
class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var screenView: UIImageView!
var image1 = UIImage(named: "w")
func cropImageIntoQuarterSquare(image: UIImage) -> UIImage? {
//shape of mask
let image = photoDispaly.image
let maskingImage = UIImage(named: "mask5")
//where the masking code starts
photoDispaly.image = maskImage(image: image!, mask: maskingImage!)
photoDispaly.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleBottomMargin, .flexibleRightMargin, .flexibleLeftMargin, .flexibleTopMargin]
photoDispaly.contentMode = .scaleAspectFit // OR .scaleAspectFill
photoDispaly.clipsToBounds = true
let originalImageSize: CGSize = image!.size
let smallImageSize = CGSize(width: (originalImageSize.width + 40), height: (originalImageSize.height + 40))
UIGraphicsBeginImageContext(smallImageSize)
image?.draw(at: CGPoint.zero)
let imageResult = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return imageResult
}
#IBOutlet var photoDispaly: UIImageView!
func maskImage(image:UIImage, mask:(UIImage))->UIImage{
let imageReference = image.cgImage
let maskReference = mask.cgImage
let imageMask = CGImage(maskWidth: maskReference!.width,
height: maskReference!.height,
bitsPerComponent: maskReference!.bitsPerComponent,
bitsPerPixel: maskReference!.bitsPerPixel,
bytesPerRow: maskReference!.bytesPerRow,
provider: maskReference!.dataProvider!, decode: nil, shouldInterpolate: true)
let maskedReference = imageReference!.masking(imageMask!)
let maskedImage = UIImage(cgImage:maskedReference!)
return maskedImage
}
func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
return
} else {
return
}
}
you could run a transform on your UIImageView in your ViewDidLoad function
photoDispaly.transform = CGAffineTransform(rotationAngle: M_PI/4)
also you may want to rename Dispaly to Display ;)
Trying to achieve something like below picture. Where the image has a mask to display certain portion of the image. Here is the code to create the shape
let shape = CAShapeLayer()
shape.opacity = 0.5
shape.lineWidth = 2
shape.lineJoin = kCALineJoinMiter
let path = UIBezierPath()
path.moveToPoint(CGPointMake(0 , 0))
path.addLineToPoint(CGPointMake(200, 0))
path.addLineToPoint(CGPointMake(160, 200))
path.addLineToPoint(CGPointMake(0, 200))
path.closePath()
shape.path = path.CGPath
Is there a way to add image into this layer. so its bound are set respective to the shape? BEFORE/AFTER image can be ignored.
Any leads would be appreciated. Thanks!
This is the solution I came up with. You need to have proper mask image.
import UIKit
import SnapKit
class TestScreenController: UIViewController {
let beforeView = UIImageView()
let afterView = UIImageView()
let maskView = UIImageView()
let divider = UIImageView(image: UIImage(named: "before_after_image"))
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setup()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setup(){
self.view.addSubview(maskView)
self.maskView.addSubview(beforeView)
self.maskView.addSubview(afterView)
self.maskView.addSubview(divider)
maskView.snp_makeConstraints { (make) in
make.top.equalTo(self.view).offset(50)
make.width.equalTo(300)
make.height.equalTo(110)
make.centerX.equalTo(self.view)
}
maskView.layer.cornerRadius = 15
maskView.layer.masksToBounds = true
let image = UIImage(named: "beforeWash-min.png")
let maskingImage = UIImage(named: "beforeImageM-1")
beforeView.image = maskImage(image!, mask: maskingImage!)
beforeView.contentMode = .ScaleToFill
beforeView.snp_makeConstraints { (make) in
make.top.left.height.equalTo(self.maskView)
make.width.equalTo(self.maskView).multipliedBy(0.50).offset(12)
}
let imageA = UIImage(named: "afterWash-min.png")
let maskingImageA = UIImage(named: "afterImageM-1")
afterView.image = maskImage(imageA!, mask: maskingImageA!)
afterView.contentMode = .ScaleToFill
afterView.snp_makeConstraints { (make) in
make.top.right.height.equalTo(self.maskView)
make.width.equalTo(self.maskView).multipliedBy(0.50).offset(10)
}
divider.snp_makeConstraints { (make) in
make.center.equalTo(maskView)
make.height.equalTo(maskView)
}
}
func maskImage(image:UIImage, mask:(UIImage))->UIImage{
let imageReference = image.CGImage
let maskReference = mask.CGImage
let imageMask = CGImageMaskCreate(CGImageGetWidth(maskReference),
CGImageGetHeight(maskReference),
CGImageGetBitsPerComponent(maskReference),
CGImageGetBitsPerPixel(maskReference),
CGImageGetBytesPerRow(maskReference),
CGImageGetDataProvider(maskReference), nil, true)
let maskedReference = CGImageCreateWithMask(imageReference, imageMask)
let maskedImage = UIImage(CGImage:maskedReference!)
return maskedImage
}
}
I want to build a facebook-like image gallery but don't know where to start from.
Here's what i think i should do:
CollectionView that shows thumbnails based on an array
On row-click, i modally open a pageViewController based on the same array of images
On Swipe left-right, i go to the next or previous image
On Swipe up-down, i close this view and go back to my collectionview
Is this logic correct/the best practice?
Maybe it's been already done by someone.
You can use banana library for showing images in slider view in Swift
get banana from https://github.com/gauravkatoch007/banana
import banana
#IBOutlet weak var imageScrollView: UIScrollView!
// Here imageArray can be a string array of Image URLs
var imageArray = [String]()
//or imageArray can be a array of UIImages
var imageArray = [UIImage]()
var imageScroll = banana( imageScrollView :self.imageScrollView )
//Load to load images in memory and display them in User Interface
imageScroll!.load(imageArray)
//Call startScroll for autoScrolling. Default scrolling timer is 8 seconds
imageScroll!.startScroll()
//Call this function to stop autoScrolling on touch or swipe.
imageScroll!.assignTouchGesture()
Update I resolved in this way:
Gallery is a collection view
On cell selected, i modally segue to another view, which contains a scrollview in which i put 5 images one (right) after the other, and handle paginating.
My image will always be the third in the middle, after every scroll, i choose the 5 images of my entire array which centers the index, or the 5 which contain this.
here's my class PhotoViewController: UIViewController, UIScrollViewDelegate {
var screenSize: CGRect = UIScreen.mainScreen().bounds
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var blackView: UIView!
#IBOutlet weak var doneButton: UIButton!
#IBOutlet weak var photoActions: UIImageView!
var img1:UIImageView = UIImageView(image: UIImage())
var img2:UIImageView = UIImageView(image: UIImage())
var img3:UIImageView = UIImageView(image: UIImage())
var img4:UIImageView = UIImageView(image: UIImage())
var img5:UIImageView = UIImageView(image: UIImage())
var w1: UIImage!
var w2: UIImage!
var w3: UIImage!
var w4: UIImage!
var w5: UIImage!
var pageIndex: Int!
var currentPage: Int!
var oldPage: Int!
var endFrame: CGRect!
var arrayIndex: Int!
// placeholder for if the image frame is scrolled
var scrolledPhotoFrame: CGRect!
override func viewDidLoad() {
super.viewDidLoad()
RightSize()
LoadData()
}
func LoadData(){
// data passed from feedViewController gets stored here
img1.image = w1
img2.image = w2
img3.image = w3
img4.image = w4
img5.image = w5
// set the right endFrame based on the selectedImage
switch pageIndex {
case 0:
img1.frame = endFrame
img1.frame.origin.x = 0
case 1:
img2.frame = endFrame
img2.frame.origin.x = screenSize.width
case 2:
img3.frame = endFrame
img3.frame.origin.x = (screenSize.width * 2)
case 3:
img4.frame = endFrame
img4.frame.origin.x = (screenSize.width * 3)
case 4:
img5.frame = endFrame
img5.frame.origin.x = (screenSize.width * 4)
default:
break
}
currentPage = pageIndex
oldPage = pageIndex
scrollView.contentSize = CGSize(width: screenSize.width*5, height: screenSize.height)
scrollView.contentOffset.x = CGFloat(pageIndex * Int(screenSize.width))
println(scrollView.contentOffset.x)
// default value of scrolledPhotoFrame is unscrolled position of photoImageView
scrolledPhotoFrame = endFrame
// required for registering scroll events
scrollView.delegate = self
// RightSize()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func doneDidPress(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
// called while scrolling
func scrollViewDidScroll(scrollView: UIScrollView) {
currentPage = Int(scrollView.contentOffset.x / screenSize.width)
if (currentPage != oldPage){
//Ho cambiato pagina
if (currentPage>oldPage){
//Sono andato di 1 foto avanti
println("Avanti")
arrayIndex = arrayIndex+1
CambioPagina()
}else{
//Sono andato di 1 foto indietro
arrayIndex = arrayIndex-1
println("indietro")
}
oldPage=currentPage
}
var alpha = CGFloat(1 - abs(scrollView.contentOffset.y) / 100)
var alpha2 = CGFloat(1 - abs(scrollView.contentOffset.y) / 20)
blackView.alpha = alpha
doneButton.alpha = alpha2
photoActions.alpha = alpha2
}
// This method is called right as the user lifts their finger
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
var offsetY = scrollView.contentOffset.y
var alpha = CGFloat(1 - abs(scrollView.contentOffset.y) / 240)
if (abs(offsetY) > 100) {
scrolledPhotoFrame.origin.y = scrolledPhotoFrame.origin.y - offsetY
blackView.hidden = true
scrollView.hidden = true // could be wrong
doneButton.hidden = true
dismissViewControllerAnimated(true, completion: nil)
}
}
// selecting the view to zoom
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
switch currentPage {
case 0:
return img1
case 1:
return img2
case 2:
return img3
case 3:
return img4
case 4:
return img5
default:
return nil
}
}
func scrollViewWillBeginZooming(scrollView: UIScrollView, withView view: UIView!) {
img2.hidden = true
img3.hidden = true
img4.hidden = true
img5.hidden = true
}
func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView!, atScale scale: CGFloat) {
}
//Controllo per cambio pagina..! chissa!
func CambioPagina(){
switch arrayIndex{
case 0:
w1 = UIImage(named: arrayFoto[arrayIndex])
w2 = UIImage(named: arrayFoto[arrayIndex+1])
w3 = UIImage(named: arrayFoto[arrayIndex+2])
w4 = UIImage(named: arrayFoto[arrayIndex+3])
w5 = UIImage(named: arrayFoto[arrayIndex+4])
pageIndex = 0
case 1:
w1 = UIImage(named: arrayFoto[arrayIndex-1])
w2 = UIImage(named: arrayFoto[arrayIndex])
w3 = UIImage(named: arrayFoto[arrayIndex+1])
w4 = UIImage(named: arrayFoto[arrayIndex+2])
w5 = UIImage(named: arrayFoto[arrayIndex+3])
pageIndex = 1
case (arrayFoto.count-2):
w1 = UIImage(named: arrayFoto[arrayIndex-3])
w2 = UIImage(named: arrayFoto[arrayIndex-2])
w3 = UIImage(named: arrayFoto[arrayIndex-1])
w4 = UIImage(named: arrayFoto[arrayIndex])
w5 = UIImage(named: arrayFoto[arrayIndex+1])
pageIndex = 3
case (arrayFoto.count-1):
w1 = UIImage(named: arrayFoto[arrayIndex-4])
w2 = UIImage(named: arrayFoto[arrayIndex-3])
w3 = UIImage(named: arrayFoto[arrayIndex-2])
w4 = UIImage(named: arrayFoto[arrayIndex-1])
w5 = UIImage(named: arrayFoto[arrayIndex])
pageIndex = 4
default:
w1 = UIImage(named: arrayFoto[arrayIndex-2])
w2 = UIImage(named: arrayFoto[arrayIndex-1])
w3 = UIImage(named: arrayFoto[arrayIndex])
w4 = UIImage(named: arrayFoto[arrayIndex+1])
w5 = UIImage(named: arrayFoto[arrayIndex+2])
pageIndex = 2
}
LoadData()
}
func RightSize(){
img1.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img1)
img2.frame = CGRect(x: screenSize.width, y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img2)
img3.frame = CGRect(x: (screenSize.width*2), y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img3)
img4.frame = CGRect(x: (screenSize.width*3), y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img4)
img5.frame = CGRect(x: (screenSize.width*4), y: 0, width: screenSize.width, height: screenSize.height)
scrollView.addSubview(img5)
img1.contentMode = .ScaleAspectFit
img2.contentMode = .ScaleAspectFit
img3.contentMode = .ScaleAspectFit
img4.contentMode = .ScaleAspectFit
img5.contentMode = .ScaleAspectFit
}
Any better approach will be great, for example, i cannot handle image zoom