swift - 索引路径在被调用后不放置图像
问题描述
我的 swifts 代码目标是当用户从照片库导入照片时,将图像放置在 customtv 类的 imageview pic 中。如果您按两次导入按钮,则代码可以工作,但在第一次代码不起作用并且没有任何反应时,您可以看到我在下面的 gif 中测试代码。我试图从 1 开始索引,但这不起作用。我认为 imagePickerController 是导致问题的原因。
import UIKit
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource, UIImagePickerControllerDelegate & UINavigationControllerDelegate {
var selectedIndexPath = IndexPath(row: 0, section: 0)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 118
}
@objc func importPhoto(_ button: UIButton) {
selectedIndexPath = IndexPath(row: button.tag , section: 0)
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary
present(imagePicker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let selectedImage = info[.originalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
guard let cell = tableview.cellForRow(at: selectedIndexPath) as? customtv else { return }
cell.pic.image = selectedImage
tableview.reloadRows(at: [selectedIndexPath], with: .automatic)
dismiss(animated: true, completion: nil)
}
@objc func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
// we got back an error!
let ac = UIAlertController(title: "Save error", message: error.localizedDescription, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
} else {
let ac = UIAlertController(title: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
present(ac, animated: true)
}
}
var tableview = UITableView()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! customtv
cell.btn.tag = indexPath.row
cell.btn.addTarget(self, action: #selector(importPhoto), for: .touchDown)
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableview.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
view.addSubview(tableview)
tableview.register(customtv.self, forCellReuseIdentifier: "cell")
tableview.delegate = self
tableview.dataSource = self
}
}
class customtv: UITableViewCell {
lazy var backView : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width , height: 110))
view.backgroundColor = .green
print(self.frame.width)
return view
}()
override func layoutSubviews() {
backView.frame = CGRect(x: 0, y: 6, width: bounds.maxX , height: 110)
}
lazy var btn : UIButton = {
let press = UIButton(frame: CGRect(x: 180, y: 40, width: 120 , height: 50))
press.backgroundColor = .blue
press.setTitle("Import", for: .normal)
return press
}()
lazy var pic : UIImageView = {
let press = UIImageView(frame: CGRect(x: 20, y: 40, width: 120 , height: 50))
press.backgroundColor = .red
return press
}()
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(animated, animated: true)
addSubview(backView)
backView.addSubview(pic)
backView.addSubview(btn)
}
}
解决方案
您以错误的方式使用表格视图。表视图使用 UITableViewDataSource 方法通过调用来检索数据tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
。在那个函数中——而且只有在那里——你用适当的数据填充单元格。当您在 中设置图像时imagePickerController(_:, didFinishPickingMediaWithInfo:)
,会发生下一次用户滚动或表格视图决定需要重新显示单元格时,它会调用cellForRowAt
它将重置您刚刚设置的图像。
因此,您需要保留对用户在属性中选择的图像的引用
class ViewController {
var selectedImages = [IndexPath:UIImage]()
var selectedRow:Int?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// ...
// set the image if there is one, otherwise set to nil
cell.imageView?.image = selectedImages[indexPath]
}
@objc func importPhoto(_ button: UIButton) {
selectedRow = button.tag
// ...
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
guard let selectedImage = info[.originalImage] as? UIImage else {
fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
}
guard let selectedRow = self.selectedRow else {
fatalError("selectedRow is nil, which is unexpected")
}
let selectedIndexPath = IndexPath(row:selectedRow, section:0)
selectedImages[selectedIndexPath] = selectedImage
tableview.reloadRows(at: [selectedIndexPath], with: .automatic)
dismiss(animated: true, completion: nil)
}
}
除了将(二进制图像)数据存储在 中selectedImages
,您还可以只存储对相机胶卷的引用。有关详细信息,请参阅存储对相机胶卷图像的引用 - Swift 4
推荐阅读
- javascript - 如何在显示 div 时强制内容不被下推?
- reactjs - 使用带有自定义输入字段的 React Dropzone Uploader
- javascript - 给定一个全局 JavaScript 函数,如何导出到 React 组件?
- javascript - 遇到无法读取 lodash 的 reduce 函数中未定义的属性“push”
- file - 文件修改时间对于缓存失效是否可靠?
- javascript - 如何使用 axios 下载包含多种类型文件的 zip
- python-3.x - 如何使用 Python 的日志记录模块仅将调试消息记录到文件并启用调试模式作为选项?
- oracle - 如何计算记录,通过 Oracle 中的 JDBC executeBatch 删除
- python - 如何在 Flask 中访问 MongoDB 实例
- c# - 创建json字符串时如何使用变量名