我在我的应用程序中有以下函数,允许使用Swipe Action清除相关图像(不是删除行,而是一些本地存储的文件)。当尝试它时,它使用默认的"XXX_1.jpg“值,而不是它应该使用的bonusName。
下面是我的swipeAction代码:
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let clearAction = UIContextualAction(style: .normal, title: "Clear Data") { (contextAction: UIContextualAction, sourceView: UIView, completionHandler: (Bool) -> Void) in
print("Clear Action Tapped")
// Delete the created images
let fileNameToDeletePri = "\(self.bonus?.bonusCode ?? "XXX")_1.jpg"
let fileNameToDeleteOpt = "\(self.bonus?.bonusCode ?? "XXX")_2.jpg"
var filePathPri = ""
var filePathOpt = ""
// Find documents directory on device
let dirs : [String] = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true)
if dirs.count > 0 {
let dir = dirs[0] //documents directory
filePathPri = dir.appendingFormat("/" + fileNameToDeletePri)
filePathOpt = dir.appendingFormat("/" + fileNameToDeleteOpt)
print("Local path = \(filePathPri)")
print("Local path = \(filePathOpt)")
} else {
print("Could not find local directory to store file")
return
}
do {
let fileManager = FileManager.default
// Check if primary file exists
if fileManager.fileExists(atPath: filePathPri) {
// Delete file
try fileManager.removeItem(atPath: filePathPri)
} else {
print("Primary image does not exist")
}
// Check if optional file exists
if fileManager.fileExists(atPath: filePathOpt) {
// Delete file
try fileManager.removeItem(atPath: filePathOpt)
} else {
print("Optional image does not exist")
}
}
catch let error as NSError {
print("An error took place: \(error)")
}
completionHandler(true)
}
clearAction.backgroundColor = .blue
let swipeConfig = UISwipeActionsConfiguration(actions: [clearAction])
return swipeConfig
}奇怪的是,我最初在我的UITableDetailView上的unwindAction中添加了上面的代码,它可以工作,但我决定不想在任何时候有人点击取消时删除图像,所以我将其移动到我的UITableView中的一个滑动操作。我怀疑它不知道我在哪一行,因此默认使用XXX选项。
编辑:以下是完整的ViewController,因此您可以在上下文中看到上面的内容:
import UIKit
import os.log
import Foundation
class BonusListViewController: UITableViewController {
var bonuses = [JsonFile.JsonBonuses]()
var bonus: JsonFile.JsonBonuses?
var filteredBonuses = [JsonFile.JsonBonuses]()
var detailViewController: BonusDetailViewController? = nil
var riderNumToH:String = UserDefaults.standard.string(forKey: Constants.RiderData().riderNumToH)!
var pillionNumToH:String = UserDefaults.standard.string(forKey: Constants.RiderData().pillionNumToH)!
var emailDestinationToH:String = UserDefaults.standard.string(forKey: Constants.RallyData().emailDestinationToH)!
struct Constants {
struct RiderData {
let riderNumToH = "riderNumToH"
let pillionNumToH = "pillionNumToH"
}
struct RallyData {
let emailDestinationToH = "emailDestinationToH"
}
}
let defaults = UserDefaults.standard
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
// MARK: Search Support
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Enter two letter state to filter"
navigationItem.searchController = searchController
definesPresentationContext = true
// MARK: Settings Data Struct
struct Constants {
struct RiderData {
let riderNumToH = "riderNumToH"
let pillionNumToH = "pillionNumToH"
}
struct RallyData {
let emailDestinationToH = "emailDestinationToH"
}
}
//MARK: Load the bonuses
print("About to call loadBonuses")
loadBonuses { [weak self] bonuses in
self?.bonuses = bonuses ?? []
DispatchQueue.main.async {
self?.tableView.reloadData()
}
print("loadBonuses called")
}
// MARK: Set Rider Defaults to Initial Values.
let defaults = UserDefaults.standard
print("Setting initial defaults")
if riderNumToH == "" {
print("riderNumToH is blank")
defaults.set("000", forKey: Constants.RiderData().riderNumToH)
} else if riderNumToH == "000" {
print("riderNumToH is 000")
} else {
print("riderNumToH is custom")
}
if pillionNumToH == "" {
print("pillionNumToH is blank")
defaults.set("000", forKey: Constants.RiderData().pillionNumToH)
} else if pillionNumToH == "000" {
print("pillionNumToH is 000")
} else {
print("pillionNumToH is custom")
}
if emailDestinationToH == "" {
print("emailDestinationToH is blank")
defaults.set("photos@tourofhonor.com", forKey: Constants.RallyData().emailDestinationToH)
} else if emailDestinationToH == "photos@tourofhonor.com" {
print("emailDestinationToH is set to default")
} else {
print("emailDestinationToH has been customized")
}
}
// MARK: - Table View Configuration
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
print("Showing \(filteredBonuses.count) Filtered Results")
return filteredBonuses.count
}
print("Found \(bonuses.count) rows in section.")
return bonuses.count
}
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
{
let clearAction = UIContextualAction(style: .normal, title: "Clear Data") { (contextAction: UIContextualAction, sourceView: UIView, completionHandler: (Bool) -> Void) in
print("Clear Action Tapped")
// Delete the created images
print("Selected Bonus is \(self.bonus?.bonusCode ?? "XXX")")
let fileNameToDeletePri = "\(self.bonus?.bonusCode ?? "XXX")_1.jpg"
let fileNameToDeleteOpt = "\(self.bonus?.bonusCode ?? "XXX")_2.jpg"
var filePathPri = ""
var filePathOpt = ""
// Find documents directory on device
let dirs : [String] = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true)
if dirs.count > 0 {
let dir = dirs[0] //documents directory
filePathPri = dir.appendingFormat("/" + fileNameToDeletePri)
filePathOpt = dir.appendingFormat("/" + fileNameToDeleteOpt)
print("Local path = \(filePathPri)")
print("Local path = \(filePathOpt)")
} else {
print("Could not find local directory to store file")
return
}
do {
let fileManager = FileManager.default
// Check if primary file exists
if fileManager.fileExists(atPath: filePathPri) {
// Delete file
try fileManager.removeItem(atPath: filePathPri)
} else {
print("Primary image does not exist")
}
// Check if optional file exists
if fileManager.fileExists(atPath: filePathOpt) {
// Delete file
try fileManager.removeItem(atPath: filePathOpt)
} else {
print("Optional image does not exist")
}
}
catch let error as NSError {
print("An error took place: \(error)")
}
completionHandler(true)
}
clearAction.backgroundColor = .blue
let swipeConfig = UISwipeActionsConfiguration(actions: [clearAction])
return swipeConfig
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "BonusListViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? BonusListViewCell else {
fatalError("The dequeued cell is not an instance of BonusListViewCell.")
}
// let bonus = bonuses[indexPath.row]
let bonus: JsonFile.JsonBonuses
if isFiltering() {
bonus = filteredBonuses[indexPath.row]
} else {
bonus = bonuses[indexPath.row]
}
// Set Primary Image
let documentsUrl = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
let imgUrl = documentsUrl.appendingPathComponent(bonus.bonusCode + "_1.jpg")
if(FileManager.default.fileExists(atPath:imgUrl.path))
{
do
{
let data = try Data.init(contentsOf:imgUrl)
cell.primaryImage.image = UIImage.init(data:data)
}
catch {
print(error)
}
}
else
{
cell.primaryImage.image = #imageLiteral(resourceName: "DefaultImage")
}
//let urlString = "http://tourofhonor.com/appimages/"+(bonus.imageName)
//let url = URL(string: urlString)
//cell.primaryImage.downloadedFrom(url: url!)
cell.nameLabel.text = bonus.name.capitalized
cell.bonusCodeLabel.text = bonus.bonusCode.localizedUppercase
cell.categoryLabel.text = bonus.category
cell.valueLabel.text = "\(bonus.value)"
cell.cityLabel.text = "\(bonus.city.capitalized),"
cell.stateLabel.text = bonus.state.localizedUppercase
return cell
}
// MARK: Functions
// MARK: - Fetch JSON from ToH webserver
func downloadJSON(completed: @escaping ([JsonFile.JsonBonuses]?) -> ()) {
let url = URL(string: "http://tourofhonor.com/BonusData.json")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error == nil, let data = data {
do {
let posts = try JSONDecoder().decode(JsonFile.self, from: data)
completed(posts.bonuses)
self.defaults.set(posts.meta.version, forKey: "jsonVersion")
print("URLSession did not fail")
print("JSON Version Set to \(posts.meta.version)")
} catch {
print("Can't decode JSON: \(error)")
}
} else {
print("downloadJSON completed")
completed(nil)
}
}.resume()
}
func saveBonuses(_ bonuses: [JsonFile.JsonBonuses], to url: URL) {
try? FileManager.default.removeItem(at: url)
do {
let data = try JSONEncoder().encode(bonuses)
try data.write(to: url)
print("saveBonuses successful")
} catch {
print("Error saving bonuses to file:", error)
}
}
func loadBonusesFromFile(_ url: URL) -> [JsonFile.JsonBonuses]? {
do {
let data = try Data(contentsOf: url)
let bonuses = try JSONDecoder().decode([JsonFile.JsonBonuses].self, from: data)
print("loadBonusesFromFile successful")
return bonuses
} catch {
print("Error loading bonuses from file:", error)
return nil
}
}
func loadBonuses(completion: @escaping ([JsonFile.JsonBonuses]?) -> Void) {
let localBonusesURL = try! FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("BonusData.json")
downloadJSON { bonuses in
if let bonuses = bonuses {
completion(bonuses)
self.saveBonuses(bonuses, to: localBonusesURL)
} else {
print("versions did not match")
completion(self.loadBonusesFromFile(localBonusesURL))
}
}
}
func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredBonuses = bonuses.filter({( bonus: JsonFile.JsonBonuses) -> Bool in
return bonus.state.localizedCaseInsensitiveContains(searchText)
})
tableView.reloadData()
}
func isFiltering() -> Bool {
return searchController.isActive && !searchBarIsEmpty()
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? BonusDetailViewController {
destination.bonus = bonuses[(tableView.indexPathForSelectedRow?.row)!]
}
}
}
extension BonusListViewController: UISearchResultsUpdating {
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}https://stackoverflow.com/questions/51352235
复制相似问题