Кнопка «Отмена» не будет отображаться при выборе изображения из галереи / библиотеки, если я сначала выберу камеру / видео? - PullRequest
0 голосов
/ 14 ноября 2018

Мое приложение позволяет пользователю выбрать камеру, чтобы сделать снимок или создать видео, или выбрать из библиотеки / галереи добавить наклейку (наложение изображения).

Если я сначала выберу «Камера», коснусь кнопки «Отмена» и выберите библиотеку / галерею, параметр «Отмена» не отображается.

Если я сначала выберу библиотеку / галерею, кнопка Отмена будет видна.

Вот код для файла ViewController.swift:

import UIKit
import MobileCoreServices
import Photos

class ViewController: UIViewController {

var imagePicker:UIImagePickerController!

override func viewDidLoad() {
    super.viewDidLoad()
    self.imagePicker = UIImagePickerController()
    self.imagePicker.delegate=self
    self.imagePicker.mediaTypes = ["public.image", "public.movie"]
}
@IBAction func camera(_ sender: Any) {
    self.imagePicker.sourceType = .camera
    self.present(self.imagePicker, animated: true, completion: nil)

}

@IBAction func gallery(_ sender: Any) {
    self.imagePicker.sourceType = .photoLibrary
    self.present(self.imagePicker, animated: true, completion: nil)
    }

}

extension ViewController:UIImagePickerControllerDelegate, UINavigationControllerDelegate{

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
    let video = info[UIImagePickerController.InfoKey.mediaURL] as? URL
    let editController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "edit") as! EditViewController

    self.dismiss(animated: true) {
        editController.image = image
        editController.video = video
       self.present(editController, animated: true, completion: nil)
    }
    }

}

Вот код для EditViewController.swift:

import UIKit
import SwiftyImage
import Photos
import MediaWatermark
import Firebase
import Kingfisher
import MBProgressHUD

class EditViewController: UIViewController,UIScrollViewDelegate {

@IBOutlet weak var colorPalletButton: UIButton!
@IBOutlet weak var frameImageView: UIImageView!
@IBOutlet weak var frameButton: UIButton!
@IBOutlet weak var collection: UICollectionView!
@IBOutlet weak var canvasView: UIView!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var orignalImage: UIImageView!
@IBOutlet weak var indicator: UIImageView!

var image:UIImage?
var video:URL?

private var stickerView: UIImageView!
private var stickerViewNeedsFirstResetPose = true

var stickerPanGesture:UIPanGestureRecognizer!
var stickerPinchGesture:UIPinchGestureRecognizer!
var stickerRotateGesture:UIRotationGestureRecognizer!
var stickerTapGesture:UITapGestureRecognizer!

private var frames = ["frames-1","frames-2","frames-3","frames-4"]
private var colors = ColorPallet.colors
private var stickers = [String]()
private var message:String?
private var selection = 1
private var stickersArray = [UIImageView]()
private var transparentImage:UIImage?


var playerLayer:AVPlayerLayer!
var player: AVPlayer! = nil

override func viewDidLoad() {
    super.viewDidLoad()
    self.collection.isHidden = true
    self.indicator.alpha=0
    scrollView.backgroundColor = UIColor.black
    scrollView.contentOffset = CGPoint(x: 500, y: 1200)
    scrollView.delegate = self


    self.collection.register(UINib(nibName: "Frame", bundle: nil), forCellWithReuseIdentifier: "frame")
    self.collection.layer.cornerRadius = 5
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    layout.itemSize = CGSize(width: self.view.frame.width/3, height: self.view.frame.width/3)
    layout.minimumInteritemSpacing = 10
    layout.minimumLineSpacing = 10
    layout.scrollDirection = .horizontal
    collection.collectionViewLayout = layout


    //for video
    if self.image == nil{
        print(self.video!)
        let img = self.getThumbnailFrom(path: self.video!)
        self.orignalImage.image = img
        self.frameButton.isHidden = true
        self.colorPalletButton.isHidden=true
    }else{
        self.orignalImage.image = self.image
    }

    Database.database().reference().child("stickers").observe(.childAdded) { (snap) in
        let obj = snap.value as! [String:String]
        let stickerUrl = obj["stickerURL"]
        self.stickers.append(stickerUrl!)
        self.collection.reloadData()
    }
    Database.database().reference().child("message").observe(.value) { (snap) in
        let obj = snap.value as! [String:String]
        let message = obj["message"]
        self.message = message
    }
}

func playVideo(url: URL, view: UIView) {
    player = AVPlayer(url: url)
    playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = view.bounds
    view.layer.addSublayer(playerLayer)
    player.play()
}

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return self.orignalImage!
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.setZoomScale()
    if stickerViewNeedsFirstResetPose {
        stickerViewNeedsFirstResetPose = false
    }
}

func setZoomScale() {
    var minZoom = min(self.view.bounds.size.width / self.orignalImage!.bounds.size.width, self.view.bounds.size.height / self.orignalImage!.bounds.size.height);

    if (minZoom > 1.0) {
        minZoom = 1.0;
    }
    scrollView.minimumZoomScale = minZoom;
    scrollView.zoomScale = minZoom;

}
@IBAction func frameButton(_ sender: UIButton) {
    self.selection = 1
    self.collection.isHidden = false
    self.indicator.alpha=1
    UIView.animate(withDuration: 0.1) {
        self.indicator.center.x = sender.frame.midX
    }
    self.collection.reloadData()
}
@IBAction func colorPalletButton(_ sender: UIButton) {
    self.selection = 2
    self.collection.isHidden = false
    self.indicator.alpha=1
    UIView.animate(withDuration: 0.1) {
        self.indicator.center.x = sender.frame.midX
    }
    self.collection.reloadData()
}
@IBAction func stickersButton(_ sender: UIButton) {
    self.selection = 3
    self.collection.isHidden = false
    self.indicator.alpha=1
    UIView.animate(withDuration: 0.1) {
        self.indicator.center.x = sender.frame.midX
    }
    self.collection.reloadData()
}

@IBAction func tap(_ sender: Any) {
    self.collection.isHidden = true
    self.indicator.alpha=0
}

@IBAction func close(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
}

@IBAction func done(_ sender: Any) {
    //for video
    if self.image == nil {
        let hud = MBProgressHUD.showAdded(to: self.view, animated: true)
        hud.label.text = "Loading..."
        let img = self.getThumbnailFrom(path: self.video!)
        self.transparentImage =  UIImage.size(width: img!.size.width, height: img!.size.height)
            .color(.clear)
            .image
        let resultImage = self.mergedImage()!
        if let item = MediaItem(url: self.video!) {
            let logoImage = resultImage
            let firstElement = MediaElement(image: logoImage)
            firstElement.frame = CGRect(x: 0, y: 0, width: logoImage.size.width, height: logoImage.size.height)
            item.add(elements: [firstElement])
            let mediaProcessor = MediaProcessor()
            mediaProcessor.processElements(item: item) { [weak self] (result, error) in
                encodeVideo(videoUrl: result.processedUrl!, resultClosure: { (convertedUrl) in
                    DispatchQueue.main.async {
                        hud.hide(animated: true)
                        self?.showAlert(title: "Share", message: "Please select to share with ?", completion: { (press) in
                            if press == "Instagram" {
                                self?.shareBackgroundImage(video: convertedUrl!)
                            }else if press == "Others"{
                                let activity = UIActivityViewController(activityItems: [convertedUrl!,self!.message!], applicationActivities: [])
                                self?.present(activity, animated: true, completion: nil)
                            }
                        })
                    }

                })
            }
        }
    }else{
        //for image

        self.showAlert(title: "Share", message: "Please select to share with ?", completion: { (press) in
            let processedImage = self.canvasView.takeScreenshot()
            if press == "Instagram" {
                self.shareBackgroundImage( image: processedImage)
            }else if press == "Others"{
                let activity = UIActivityViewController(activityItems: [processedImage,self.message!], applicationActivities: [])
                self.present(activity, animated: true, completion: nil)
            }
        })
    }
}

private func makeStickerView(with image: UIImage, center: CGPoint) -> UIImageView {
    let heightOnWidthRatio = image.size.height / image.size.width
    let imageWidth: CGFloat = 100
    let view = UIImageView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageWidth * heightOnWidthRatio))
    view.image = image
    view.clipsToBounds = true
    view.contentMode = .scaleAspectFit
    view.isUserInteractionEnabled = true


    //for video
    if self.image == nil{
        self.frameImageView.bringSubviewToFront(view)
//            view.center = CGPoint(x: self.orignalImage.image!.size.width/2, y: self.orignalImage.image!.size.height/2)
        view.transform = CGAffineTransform(translationX: self.frameImageView.center.x, y:  self.frameImageView.center.y)
    }else{
        view.center = self.frameImageView.center
    }
    return view
}

func shareBackgroundImage(image:UIImage?=nil,video:URL?=nil) {

    if let img = image{
        if let pngImage = img.pngData() {
            backgroundImage(pngImage, attributionURL: "")
        }
    }

    if let v = video {
        if let videoHolder = try? Data(contentsOf: v){
            self.backgroundVideo(videoHolder, attributionURL: "")
        }
    }

}

func backgroundImage(_ backgroundImage: Data, attributionURL: String) {
    guard let urlScheme = URL(string: "instagram-stories://share"),
        UIApplication.shared.canOpenURL(urlScheme) else {
            return
    }
    let pasteboardItems = [["com.instagram.sharedSticker.backgroundImage": backgroundImage,
                            "com.instagram.sharedSticker.contentURL": attributionURL]]
    let pasteboardOptions: [UIPasteboard.OptionsKey: Any] = [.expirationDate: Date().addingTimeInterval(60 * 5)]
    UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions)
    UIApplication.shared.open(urlScheme)
}
func backgroundVideo(_ backgroundVideo: Data, attributionURL: String) {
    guard let urlScheme = URL(string: "instagram-stories://share"),
        UIApplication.shared.canOpenURL(urlScheme) else {
            return
    }
    let pasteboardItems = [["com.instagram.sharedSticker.backgroundVideo": backgroundVideo,
                            "com.instagram.sharedSticker.contentURL": attributionURL]]
    let pasteboardOptions: [UIPasteboard.OptionsKey: Any] = [.expirationDate: Date().addingTimeInterval(60 * 5)]
    UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions)
    UIApplication.shared.open(urlScheme)
}

private func addGestures(to stickerView: UIImageView) {
     stickerPanGesture = UIPanGestureRecognizer(target: self, action: #selector(stickerDidMove))
     stickerPinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(stickerDidPinch))
     stickerRotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(stickerDidRotate))
     stickerTapGesture = UITapGestureRecognizer(target: self, action: #selector(stickerDidTap))

    stickerPinchGesture.delegate = self
    stickerRotateGesture.delegate = self
    stickerPanGesture.delegate = self

    stickerView.addGestureRecognizer(stickerPinchGesture)
    stickerView.addGestureRecognizer(stickerRotateGesture)
    stickerView.addGestureRecognizer(stickerPanGesture)
    stickerView.addGestureRecognizer(stickerTapGesture)

}

@objc private func stickerDidTap(tap: UITapGestureRecognizer){
    let imgView = tap.view as! UIImageView
    self.stickersArray = self.stickersArray.filter({$0 != imgView})
    tap.view?.removeFromSuperview()
}



@objc private func stickerDidPinch(pincher: UIPinchGestureRecognizer) {
    guard let stickerView = pincher.view else { return }
    stickerView.transform = stickerView.transform.around(pincher.location(in: stickerView), do: { $0.scaledBy(x: pincher.scale, y: pincher.scale) })
    pincher.scale = 1
    if pincher.state == .began{
        self.scrollView.isScrollEnabled=false
    }else if pincher.state == .ended{
        self.scrollView.isScrollEnabled=true

    }
}

@objc private func stickerDidRotate(rotater: UIRotationGestureRecognizer) {
    guard let stickerView = rotater.view else { return }
    stickerView.transform = stickerView.transform.around(rotater.location(in: stickerView), do: { $0.rotated(by: rotater.rotation) })
    rotater.rotation = 0

    if rotater.state == .began{
        self.scrollView.isScrollEnabled=false
    }else if rotater.state == .ended{
        self.scrollView.isScrollEnabled=true

    }
}

@objc private func stickerDidMove(panner: UIPanGestureRecognizer) {
    guard let stickerView = panner.view else { return }

    let offset = panner.translation(in: stickerView)
    stickerView.transform = stickerView.transform.translatedBy(x: offset.x, y: offset.y)
    panner.setTranslation(.zero, in: stickerView)
    if panner.state == .began{
        self.scrollView.isScrollEnabled=false
    }else if panner.state == .ended{
        self.scrollView.isScrollEnabled=true

    }

}

private func mergedImage() -> UIImage? {

    var images: [(image: UIImage, viewSize: CGSize, transform: CGAffineTransform)] = []

    for img in self.stickersArray{
        if let stickerViewImage = img.image {
            images.append((image: stickerViewImage, viewSize: img.bounds.size, transform: img.transform))
        }
    }

    return self.transparentImage!.merge(in: self.transparentImage!.size, with: images)
}

func getThumbnailFrom(path: URL) -> UIImage? {
    do {
        let asset = AVURLAsset(url: path , options: nil)
        let imgGenerator = AVAssetImageGenerator(asset: asset)
        imgGenerator.appliesPreferredTrackTransform = true
        let cgImage = try imgGenerator.copyCGImage(at: CMTimeMake(value: 0, timescale: 1), actualTime: nil)
        let thumbnail = UIImage(cgImage: cgImage)
        return thumbnail

    } catch let error {
        print("*** Error generating thumbnail: \(error.localizedDescription)")
        return nil
    }
}

} 
//
    extension EditViewController: UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return gestureRecognizer is UIPanGestureRecognizer || gestureRecognizer is UIRotationGestureRecognizer
}

}

extension EditViewController:UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout{

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return self.selection == 1 ? self.frames.count : (self.selection == 2 ? self.colors.count : self.stickers.count)

}


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "frame", for: indexPath) as! FrameCollectionViewCell

    switch self.selection {
    case 1:
        cell.frameImage.layer.borderWidth = 0
        cell.frameImage.image = UIImage(named: self.frames[indexPath.row])

    case 2:
        cell.frameImage.image=nil
        cell.frameImage.layer.borderWidth = 15
        cell.frameImage.layer.borderColor = self.colors[indexPath.row].cgColor
    default:
        cell.frameImage.layer.borderWidth = 0
        cell.frameImage.kf.indicatorType = .activity
        let image = UIImage(named: "default")
        cell.frameImage.kf.setImage(with: URL(string: self.stickers[indexPath.row]), placeholder: image)
    }
    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    switch self.selection {
    case 1:
        self.frameImageView.layer.borderWidth = 0
        self.frameImageView.image = UIImage(named: self.frames[indexPath.row])
    case 2:
        self.frameImageView.image=nil
        self.frameImageView.layer.borderWidth = 30
        self.frameImageView.layer.borderColor = self.colors[indexPath.row].cgColor
    default:
        let cell = collection.cellForItem(at: indexPath) as! FrameCollectionViewCell
        stickerView = makeStickerView(with: cell.frameImage.image! , center: self.canvasView.center)
        addGestures(to: stickerView)
        //for video
        if self.image == nil{
            self.orignalImage.addSubview(stickerView)
        }else{
            //for image
            self.canvasView.addSubview(stickerView)
        }
        self.stickersArray.append(stickerView)
        break;
    }

}
}

Я попытался добавить этот код

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { dismiss(animated: true, completion: nil)

но это не влияет на операцию.

...