我在扩展程序中使用cropViewController来裁剪图像。结果进入一个快速文件(不是视图控制器)。但是现在需要在另一个视图控制器中设置图像。
正在使用CropViewController:https://github.com/TimOliver/TOCropViewController
我的View Controller 文件具有以下元素
import UIKit
import XLPagerTabStrip
class GetPetViewController: UIViewController, IndicatorInfoProvider {
// Initialize Default Value
let userDefault = UserDefaults.standard
@IBOutlet var bPetImage: UIButton!
@IBAction func bPetImage_TouchUpInside(_ sender: Any) {
// Start Action Sheet
StartImageActionSheet()
}
@IBAction func bSavePet_TouchUpInside(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Set The Default Value
userDefault.set("GetPet", forKey: "senderActivity")
userDefault.synchronize()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// Tab Functionality
func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
return IndicatorInfo(image: UIImage(named: "ic_get_pet"), highlightedImage: UIImage(named: "ic_get_pet"), userInfo: Any?.self)
}
}
我的第二个文件(不是视图控制器)
import CropViewController
import FirebaseAuth
import Foundation
import SwiftyJSON
import UIKit
class ImageFunctions {
}
extension UIViewController {
// Image Action Sheet
func StartImageActionSheet() {
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self as UIImagePickerControllerDelegate & UINavigationControllerDelegate
// Action Sheet To Select Camera Or Photo Library
let actionSheet = UIAlertController(title: "Select Image", message: "Please Choose A Source", preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: {
(_: UIAlertAction!) in
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePickerController.sourceType = .camera
self.present(imagePickerController, animated: true, completion: nil)
} else {
self.uiAlertControllerAction(alertTitle: "Problem With Camera", alertMessage: "Unable To Load Camera", action: "")
}
}))
actionSheet.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: {
(_: UIAlertAction!) in
imagePickerController.sourceType = .photoLibrary
self.present(imagePickerController, animated: true, completion: nil)
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(actionSheet, animated: true, completion: nil)
}
// For Image Upload To Server Using PHP
func myImageUploadRequest(image: UIImage) {
// Initialize User Defaults
let userDefault = UserDefaults.standard
// Get The Sender Activity from User Defaults
let senderActivityValue = userDefault.string(forKey: "senderActivity")
let myUrl = NSURL(string: "someurl")
let request = NSMutableURLRequest(url: myUrl! as URL)
request.httpMethod = "POST"
// Get The Firebase User
guard let user = Auth.auth().currentUser else { return }
let param = [
"desc": user.uid,
"sender": senderActivityValue!,
]
let boundary = generateBoundaryString()
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let imageData = image.jpegData(compressionQuality: 0.75)
if imageData == nil { return }
request.httpBody = createBodyWithParameters(parameters: param, filePathKey: "image", imageDataKey: imageData! as NSData, boundary: boundary) as Data
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, _, error in
if error != nil {
print("error=\(String(describing: error))")
return
}
// You can print out response object
// print("******* response = \(String(describing: response))")
// Print out reponse body
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
// print("****** response data = \(responseString!)")
do {
let jsonResponseObject = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary
// print(jsonResponseObject!)
// Use Swiftly Json to Parse Json Value Into String
let json = JSON(jsonResponseObject as Any)
let fileName = json["url"].stringValue
if param["sender"]! == "GetPet" {
let url = "lit-squad.com/files/images/pets/uploads/" + fileName
print(url)
}
} catch {
print(error)
}
}
task.resume()
}
// For Image Upload To Server Using PHP
func createBodyWithParameters(parameters: [String: String]?, filePathKey: String?, imageDataKey: NSData, boundary: String) -> NSData {
let body = NSMutableData()
if parameters != nil {
for (key, value) in parameters! {
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString(string: "\(value)\r\n")
}
}
let filename = "myfile.jpg"
let mimetype = "image/jpg"
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(imageDataKey as Data)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body
}
// For Image Upload To Server Using PHP
func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}
}
// For Image Upload To Server Using PHP
extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}
// Image Picker
extension UIViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
// Image Picker Controller Set Selected Image Into Image View
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage]! as! UIImage
// Dismiss The Image Picker And Set The Image
picker.dismiss(animated: true, completion: {
// Call The Image Cropper
self.presentCropViewController(image: image)
})
}
// Image Picker Cancel
public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
}
// Image Cropper
extension UIViewController: CropViewControllerDelegate {
// Image CropperView Function
func presentCropViewController(image: UIImage) {
let cropViewController = CropViewController(croppingStyle: .default, image: image)
// Commenting This Because It Was Leading To Function Being Run Twice
// cropViewController.delegate = self
// CropperView Attributes
cropViewController.title = "Crop Image"
cropViewController.aspectRatioPreset = .presetSquare
cropViewController.aspectRatioLockEnabled = true
cropViewController.aspectRatioPickerButtonHidden = true
present(cropViewController, animated: true, completion: nil)
}
// Image CropperView Finish Cropping
public func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
// bPetImage.setImage(image, for: UIControl.State.normal)
// Call Function To Upload Image To Server
myImageUploadRequest(image: image)
cropViewController.dismiss(animated: true, completion: nil)
}
}
基本上,这在swift文件(我已在其中注释过)中不起作用,但如果我在视图控制器本身中使用此扩展程序函数而没有扩展名,则它将起作用。
bPetImage.setImage(image, for: UIControl.State.normal)
我正在myImageUploadRequest(image: image)
之前尝试以下操作
let viewController = GetPetViewController(nibName: nil, bundle: nil)
viewController.bPetImage.setImage(image, for: UIControl.State.normal)
navigationController?.pushViewController(viewController, animated: true)
但出现错误:Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
答案 0 :(得分:1)
因此,如果我正确理解了这一点,则可以使用另一个名为MyViewController
的视图控制器,其中包含按钮bPetImage
。并且此按钮现在应该获取图像。但是您所做的是将协议设置为无法访问按钮的超类UIViewController: CropViewControllerDelegate
。
针对您的情况的快速简便的解决方案可能是
(self as? MyViewController)?.bPetImage.setImage(image, for: UIControl.State.normal)
至少在您看来,self
是MyViewController
实例。通常,这不是一个很好的过程。我将创建一个特定的协议,而不是一个通用的协议。而是这样:
extension MyViewController: CropViewControllerDelegate {
在这种情况下,您可以直接调用它(您注释掉的代码)。
但是,如果您真的想要它,让UIViewController
响应CropViewControllerDelegate
,那么我只是建议您添加一个新协议。考虑这样的事情:
protocol SetCroppedImageDelegate {
func setCroppedImage(_ image: UIImage)
}
现在您键入委托而不是具体的类了:
public func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
(self as? SetCroppedImageDelegate)?.setCroppedImage(image)
// Call Function To Upload Image To Server
myImageUploadRequest(image: image)
cropViewController.dismiss(animated: true, completion: nil)
}
现在您将扩展MyViewController
:
extension MyViewController : SetCroppedImageDelegate {
func setCroppedImage(_ image: UIImage) {
bPetImage.setImage(image, for: UIControl.State.normal)
}
}