如何使用自定义 UITableView 上传图片
Posted
技术标签:
【中文标题】如何使用自定义 UITableView 上传图片【英文标题】:How To Upload Image Using Custom UITableView 【发布时间】:2020-06-15 05:40:27 【问题描述】:我对 ios 开发比较陌生。我想知道如何允许用户单击表格中的一行并提示他们上传图像?我知道如何创建图像选择器,但我不确定如何启动它?
下面是我创建的 UITableView。我想在用户点击“图片”行时创建一个动作。
UITableView
这是我想要在用户单击“图像”行时启动的图像选择器示例。
ImagePicker
非常感谢任何帮助!
下面是视图控制器/表视图代码:
//
// AddAssetTableViewController.swift
// ItemizePro
//
// Created by Tyler Wasick on 5/27/20.
// Copyright © 2020 Tyler Wasick. All rights reserved.
//
import UIKit
class AddAssetTableViewController: UITableViewController
// TODO: Add image IBOutlet
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var descriptionTextField: UITextField!
@IBOutlet weak var datePurchasedTextField: UITextField!
@IBOutlet weak var manufactureTextField: UITextField!
@IBOutlet weak var modelTextField: UITextField!
@IBOutlet weak var serialNumberTextField: UITextField!
@IBOutlet weak var costTextField: UITextField!
@IBOutlet weak var roomTextField: UITextField!
@IBOutlet weak var notesTextView: UITextView!
@IBOutlet weak var receiptTextField: UITextField!
@IBOutlet weak var addUIButton: UIButton!
// Set variables
var newAsset = Asset()
let datePicker = UIDatePicker()
var dateAdded = Date()
var cost = 0
// Setup number formater
lazy var numberFormatter: NumberFormatter =
// Setup Currency Formatter
let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
// localize to your grouping and decimal separator
currencyFormatter.locale = Locale.current
return currencyFormatter
()
override func viewDidLoad()
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
// Setup Date Picker
createDatePicker()
// Use input data for cost field and update the cost data and formatting automatically
costTextField.delegate = self
costTextField.placeholder = updateCostField()
// MARK: - Table view data source
/*
override func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return 0
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete implementation, return the number of rows
return 0
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell", for: indexPath)
// Configure the cell...
return cell
*/
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
// Return false if you do not want the specified item to be editable.
return true
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
else if editingStyle == .insert
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath)
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
// Return false if you do not want the item to be re-orderable.
return true
*/
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
//if let detinationVC = segue.description as? RoomListViewController
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
if let target = segue.destination as? RoomListViewController
target.selectionDelegate = self
// MARK: - Functions
// Date picker
func createDatePicker()
// Setup the UIToolbar
let toolbar = UIToolbar()
toolbar.sizeToFit()
// Setup "Done" button
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneTapped))
toolbar.setItems([doneButton], animated: true)
// Format date text field
datePurchasedTextField.inputAccessoryView = toolbar
datePurchasedTextField.inputView = datePicker
datePicker.datePickerMode = .date
// Obj-C Date Picker Action
@objc func doneTapped()
// Format date field
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
let dateString = formatter.string(from: datePicker.date)
dateAdded = formatter.date(from: dateString)!
// Set the date text field
datePurchasedTextField.text = dateString
// Close date picker
self.view.endEditing(true)
func updateCostField() -> String
// Format number into currency data
let num = cost
let decimalNum = Double(num) / 100
let numString = numberFormatter.string(from: NSNumber(value: decimalNum))
// Return formatted number
return numString!
func showActionSheet(title:String)
// Create the action sheet
let actionSheet = UIAlertController(title: title, message: "Select a source to upload an image", preferredStyle: .actionSheet)
// Create camera action if available
if UIImagePickerController.isSourceTypeAvailable(.camera)
let cameraAction = UIAlertAction(title: "Camera", style: .default) (action) in
// Set the camera action
self.showImagePicker(type: .camera)
// Add action to the action sheet
actionSheet.addAction(cameraAction)
// Create photo library action
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary)
let photoAction = UIAlertAction(title: "Select From Photo Library", style: .default) (action) in
// Set photo library action
self.showImagePicker(type: .photoLibrary)
// Add action to the action sheet
actionSheet.addAction(photoAction)
// Create cancel actions
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
// Add the cancel action
actionSheet.addAction(cancelAction)
// Present action sheet
present(actionSheet, animated: true, completion: nil)
func showImagePicker(type:UIImagePickerController.SourceType)
// Create the image picker
let imagePicker = UIImagePickerController()
imagePicker.sourceType = type
// Setup delegate
imagePicker.delegate = self
// Present it
present(imagePicker, animated: true, completion: nil)
// MARK: - IBAction outlets
@IBAction func addButtonTapped(_ sender: UIButton)
// Name text field
if nameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.name = nameTextField.text!
else if nameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.name = ""
// Description text field
if descriptionTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.description = descriptionTextField.text!
else if descriptionTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.description = ""
// Date text field
if datePurchasedTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.datePurchased = dateAdded
else if datePurchasedTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.datePurchased = Date()
// Manufacture text field
if manufactureTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.manufacture = manufactureTextField.text!
else if manufactureTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.manufacture = ""
// Model text field
if modelTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.model = modelTextField.text!
else if modelTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.model = ""
// Serial number text field
if serialNumberTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.serialnumber = serialNumberTextField.text!
else if serialNumberTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.serialnumber = ""
// Cost text field
if costTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines) != ""
let cost = costTextField.text!
newAsset.cost = cost
else if costTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == ""
newAsset.cost = "$0.00"
// Room text field
if roomTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.room = roomTextField.text!
else if roomTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.room = ""
// Notes text field
if notesTextView.text?.trimmingCharacters(in: .whitespacesAndNewlines) != nil
newAsset.notes = notesTextView.text!
else if notesTextView.text?.trimmingCharacters(in: .whitespacesAndNewlines) == nil
newAsset.notes = ""
// TODO: - Receipt
// TODO: - Image
// Add to firebase
let result = FirebaseDB.addAssets(asset: newAsset)
print(result)
// MARK: - Extensions
// Table delegate extension
extension AddAssetTableViewController : RoomDelegate
func tappedOnRoom(room: String)
roomTextField.text = room
// Cost text field delegate
extension AddAssetTableViewController : UITextFieldDelegate
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
// Check if num is <= 1 billion
if cost < 1000000000
// Add new digit to the cost var
if let num = Int(string)
cost = cost * 10 + num
print(cost)
costTextField.text = updateCostField()
// If the user removes a digit, remove it from the cost var
if string == ""
cost = cost / 10
print(cost)
costTextField.text = updateCostField()
// Return false for return (return is unused)
return false
// Image picker extension
extension AddAssetTableViewController : UIImagePickerControllerDelegate & UINavigationControllerDelegate
func imagePickerControllerDidCancel(_ picker: UIImagePickerController)
// TODO: User cancelled, dismiss image picker
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any])
// TODO: If image was selected successfully, set the image to "selectImage" object
if let selectImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage
// Dismiss the picker
picker.dismiss(animated: true, completion: nil)
【问题讨论】:
【参考方案1】:使用didSelectRow
方法,您已经拥有需要在代码中调用的方法。方法如下:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) -> Int
if indexPath.row == 0
showActionSheet(title: "Your title")
【讨论】:
以上是关于如何使用自定义 UITableView 上传图片的主要内容,如果未能解决你的问题,请参考以下文章