首页 > 解决方案 > 索引路径在被调用后不放置图像

问题描述

我的 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)
    }
    
    
    
}

标签: swiftimagetableviewuiimagepickercontrollerindexpath

解决方案


您以错误的方式使用表格视图。表视图使用 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


推荐阅读