我在扩展中使用 cropViewController 来裁剪图像。结果出现在一个 swift 文件中(不是 View Controller )。但是现在需要在另一个 View Controller 中设置图像。
正在使用 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)
}
}
我的第二个文件(不是 View Controller )
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 文件中不起作用(我在其中对其进行了评论),但如果我在 View Controller 本身中使用没有扩展名的裁剪器功能,它将起作用。
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
最佳答案
因此,如果我的理解正确,您还有其他一些名为 MyViewController
的 View Controller ,它包含按钮 bPetImage
。这个按钮现在应该得到图像。但是您所做的是将协议(protocol)设置为父类(super class) UIViewController: CropViewControllerDelegate
,它无权访问按钮。
针对您的情况,快速简便的解决方案可能是
(self as? MyViewController)?.bPetImage.setImage(image, for: UIControl.State.normal)
至少我希望在您的情况下 self
是 MyViewController
实例。一般来说,这不是一个很好的程序。我会创建一个特定的协议(protocol),而不是一个通用的协议(protocol)。所以宁愿有:
extension MyViewController: CropViewControllerDelegate {
在这种情况下,您可以直接调用它(您注释掉的代码)。
但是如果你真的想要它的方式,让 UIViewController
响应 CropViewControllerDelegate
那么我只是建议你添加一个新协议(protocol)。考虑这样的事情:
protocol SetCroppedImageDelegate {
func setCroppedImage(_ image: UIImage)
}
现在您对委托(delegate)而不是具体类进行类型转换:
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)
}
}
关于ios - 将图像从 Swift 文件(不是 ViewController)传递到 ViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56930994/