ios - 无法从第二个数据源动态添加自定义单元格

标签 ios swift uitableview custom-cell

我已经花了 20 多个小时来搜索/尝试针对这个特定问题的不同解决方案,但无法解决问题。我刚开始学习 Swift,所以要温和一点……在寻求帮助之前,我确保已经用尽了所有选项。

我有 3 个 View Controller (VC1:具有 5 个文本字段的表单,VC2:用于显示收集的数据的 TableView ,VC3:具有 3 个文本字段和一个图像选择器的第二个表单)

screen shot of storyboard

VC1 收集文本字段数据,传递给 VC2,并使用自定义单元格 #1 添加到 TableView 。我使用完全相同的方法对 VC3 执行相同的操作(更改单元格标识符,并使用 if/else 确定要添加到哪个部分)但无法获得任何结果。起初我以为我的数据没有被传递,但是检查出来(“完成并发送”按钮设置为警报并打印变量的文本)接下来我认为这是我的逻辑,但是自定义单元格 #1 工作......我'我已经盯着这段代码看了很长时间了,我对它做了可怕的梦。我觉得这应该可以通过我正在应用的技术获得,但想知道我是否正在进入 Core Data 领域但只是不知道。

tableview with only 1 custom cell

我的意图是让 VC1 在 indexPath.row 0 添加一个单元格(自定义单元格 1),VC3 添加(自定义单元格 2)indexPath.row >= 1。除了添加tableview 的第二个自定义单元格。

添加工作 View Controller

import UIKit
import MapKit
import CoreLocation

class mainVC: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CLLocationManagerDelegate, UITextFieldDelegate {

    @IBOutlet weak var scrollviewWORK: UIScrollView!
    @IBOutlet weak var typeWORK: UISegmentedControl!
    @IBOutlet weak var locationWORK: UITextField!
    @IBOutlet weak var positionWORK: UISegmentedControl!
    @IBOutlet weak var priceWORK: UITextField!
    @IBOutlet weak var photo1WORK: UIImageView!
    @IBOutlet weak var descriptionWORK: UITextView!



/// Prepare Segues

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        switch segue.destination {

        case is WorkOverview:

                let workDest: WorkOverview = segue.destination as! WorkOverview
                var cost = ""
                var snap = UIImage()

                if (priceWORK.text == nil) {
                    cost = ""
                } else {
                    cost = priceWORK.text!
                }

                if (photo1WORK.image == nil) {
                    snap = UIImage()
                } else {
                    snap = photo1WORK.image!
                }

                workDest.workLocation = locationWORK.text!
                workDest.workDescription = descriptionWORK.text!
                workDest.workPrice = cost
                workDest.workPhoto = snap


            case is PlantList:

                let plantDest: PlantList = segue.destination as! PlantList
                plantDest.placeholder = ""

            default:
                break
        }
      }

/// END Segue Preparation

/// Save to List Button
    @IBAction func saveToListBTN(_ sender: UIButton) {
        performSegue(withIdentifier: "unwindToList", sender: self)
    }
/// END Save to List Button

/// Insert Plant

    @IBAction func insertPlant(_ sender: UIButton) {
        performSegue(withIdentifier: "toPlantListSegue", sender: self)
    }

    var addedPlant: String? = ""

/// END Insert Plant

/// Clear All Button

    @IBAction func clearAllBTN(_ sender: UIButton) {


    }

/// END Clear All Button


/// Segmented Controller - Work Type


    @IBAction func positionChanged(_ sender: UISegmentedControl) {
        switch positionWORK.selectedSegmentIndex {
        case 0:
            locationWORK.text? += " - Front"

        case 1:
            locationWORK.text? += " - Back"

        case 2:
            locationWORK.text? += " - Side"

        default:
            break
        }
    }


    @IBAction func indexChanged(_ sender: UISegmentedControl) {
        switch typeWORK.selectedSegmentIndex {
        case 0:
            descriptionWORK.text = "Provide and install "

        case 1:
            descriptionWORK.text = "Replace "

        case 2:
            descriptionWORK.text = "Remove and dispose of "

        default:
            break
        }
    }

/// END Segmented Controller - Work Type



    /// ScrollView Keyboard Adjust

    func textFieldDidBeginEditing(_ textField: UITextField) {
        if (textField == priceWORK){
            scrollviewWORK.setContentOffset(CGPoint(x: 0, y: 205), animated: true)
        } else {}
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        scrollviewWORK.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
    }

    /// END Scrollview Keyboard Adjust


/// VIEWDIDLOAD
    override func viewDidLoad() {
        super.viewDidLoad()

        // Toolbar
        let toolBar = UIToolbar()
        toolBar.sizeToFit()


        let backArrow = UIBarButtonItem.init(image: #imageLiteral(resourceName: "backArrow"), style: .plain, target: nil, action: #selector(backArrowClicked))

        let spacerA = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

        let workDoneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneBtnClicked))

        let spacerB = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

        let nextArrow = UIBarButtonItem.init(image: #imageLiteral(resourceName: "nextArrow"), style: .plain, target: nil, action: #selector(nextArrowClicked))

        toolBar.setItems([backArrow, spacerA, workDoneBtn, spacerB, nextArrow], animated: false)


        toolBar.setItems([backArrow, spacerA, workDoneBtn, spacerB, nextArrow], animated: false)
        locationWORK.inputAccessoryView = toolBar
        priceWORK.inputAccessoryView = toolBar
        descriptionWORK.inputAccessoryView = toolBar

    }
/// END VIEWDIDLOAD


/// Toolbar - Done Button
    @objc func doneBtnClicked() {
        view.endEditing(true)
    }
/// END Toolbar - Done Button

/// Arrow to Next TextField
    @objc func nextArrowClicked() {

        if (locationWORK.isFirstResponder) {
            descriptionWORK.becomeFirstResponder()
        } else if (descriptionWORK.isFirstResponder) {
            priceWORK.becomeFirstResponder()
        } else if (priceWORK.isFirstResponder) {
            view.endEditing(true)
            scrollviewWORK.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
        }
    }
/// END Arrow to Next TextField

/// Arrow to Previous TextField
    @objc func backArrowClicked() {

        if (locationWORK.isFirstResponder) {
            view.endEditing(true)
            scrollviewWORK.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
        } else if (descriptionWORK.isFirstResponder) {
           locationWORK.becomeFirstResponder()
        } else if (priceWORK.isFirstResponder) {
            descriptionWORK.becomeFirstResponder()
        }
    }
/// END Arrow to Previous TextField



/// Image Select from Library & Camera

    @IBAction func takePhotoONE(_ sender: UIButton) {

        let imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self

        let actionSheet = UIAlertController(title: "Want to add a photo?", message: "Please choose a source.", preferredStyle: .actionSheet)

        actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (action:UIAlertAction) in

            if UIImagePickerController.isSourceTypeAvailable(.camera) {
                imagePickerController.sourceType = .camera
                self.present(imagePickerController, animated: true, completion: nil)
            }else{
                print("Camera is not available")
            }

        }))

        actionSheet.addAction(UIAlertAction(title: "Photo Library", style: .default, handler: { (action:UIAlertAction) in imagePickerController.sourceType = .photoLibrary
            self.present(imagePickerController, animated: true, completion: nil)
        }))

        actionSheet.addAction(UIAlertAction(title: "Remove Photo", style: .destructive, handler: { (action:UIAlertAction) in self.photo1WORK.image = nil}))

        actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

        self.present(actionSheet, animated: true, completion: nil)

    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        photo1WORK.image = image
        picker.dismiss(animated: true, completion: nil)
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }

/// END Image Select from Library & Camera

/// GPS Location

        let addressManager = CLLocationManager()

        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

            let streetAddress = locations[0]
            CLGeocoder().reverseGeocodeLocation(streetAddress) { (placemark, error) in
                if error != nil
                {
                    print ("Sorry, there has been an error.")
                }
                else
                {
                    if let place = placemark?[0]
                    {
                        if place.subThoroughfare != nil
                        {
                            self.locationWORK.text = "\(place.subThoroughfare!) \(place.thoroughfare!)"
                            }
                        }
                    }
                }
            }

    @IBAction func getGPS(_ sender: UIButton) {

        // Address
        addressManager.delegate = self
        addressManager.desiredAccuracy = kCLLocationAccuracyBest
        addressManager.requestWhenInUseAuthorization()
        addressManager.startUpdatingLocation()

    }

 /// END GPS Location


}

表格 View Controller

import UIKit


class WorkOverview: UIViewController {


    @IBOutlet weak var listTableView: UITableView!

    @IBAction func addWorkBTN(_ sender: UIButton) {
    performSegue(withIdentifier: "overviewToWorkSegue", sender: self)
}

@IBAction func unwindToList(segue:UIStoryboardSegue) { }

    @IBAction func finishedBTN(_ sender: UIButton) {

        let alertController = UIAlertController(title: "Data Pass Test", message:
            workLocation, preferredStyle: UIAlertControllerStyle.alert)
        alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))

        self.present(alertController, animated: true, completion: nil)
    }

override func viewDidLoad() {
    super.viewDidLoad()

    property = createArray()
    workPJs = workArray()

    listTableView.delegate = self
    listTableView.dataSource = self

}

var propForm = String()
var propName = String()
var propCity = String()
var propDate = String()
var propDue = String()
var propRep = String()

    var workLocation = String()
    var workDescription = String()
    var workPrice = String()
    var workPhoto = UIImage()

var workPJs: [WorkManager] = []
var property: [TaskManager] = []

func workArray() -> [WorkManager] {

    var tempWork: [WorkManager] = []

    let work1 = WorkManager(location: workLocation, description: workDescription, price: workPrice, photo: workPhoto)
    tempWork.append(work1)
    return tempWork
}


func createArray() -> [TaskManager] {

    var tempProperty: [TaskManager] = []

    let prop1 = TaskManager(title: propForm, property: propName, city: propCity, date: propDate, due: propDue, rep: propRep)
    tempProperty.append(prop1)
    return tempProperty
}


}

extension WorkOverview: UITableViewDataSource, UITableViewDelegate {


    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if section == 0 {
            return property.count
        } else {
            return workPJs.count
        }

    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.section == 0 {
            let prop = property[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: "PropertyCell", for: indexPath) as! PropertyCell
            cell.setProperty(prop: prop)
            return cell
        } else if indexPath.section == 1 {
            let wrk = workPJs[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: "WorkCell", for: indexPath) as! WorkCell
            cell.setWork(wrk: wrk)
            return cell
        }
        return UITableViewCell()

     }



}

工作单元类

import UIKit

class WorkCell: UITableViewCell {

    @IBOutlet weak var theLocation: UILabel!
    @IBOutlet weak var theDescription: UILabel!
    @IBOutlet weak var thePrice: UILabel!
    @IBOutlet weak var thePhoto: UIImageView!

    func setWork(wrk: WorkManager) {

        theLocation.text = wrk.location
        theDescription.text = wrk.description
        thePrice.text = wrk.price
        thePhoto.image = wrk.photo
    }
}

工作管理器类

import UIKit


class WorkManager {

    var location: String
    var description: String
    var price: String
    var photo: UIImage


    init(location: String, description: String, price: String, photo: UIImage){
        self.location = location
        self.description = description
        self.price = price
        self.photo = photo
    }



}

最佳答案

ViewDidLoad中根据你的单元格名称添加这段代码

tableView.registerNib(UINib(nibName: "cell xib", bundle: nil), forCellReuseIdentifier: "cell name")

在您的情况下,您必须注册自定义单元格的两个 Nib 。

如果其他情况有误,我对您的部分有感觉。更好地调试。

关于ios - 无法从第二个数据源动态添加自定义单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51718311/

相关文章:

ios - CoreData+mogenerator - 如何防止中间数据模型中的 `setValue(forKey:)` 引用最终数据模型中实体的 'human' 类?

ios - UITableViewDataSource 无法附加到类,swift-ios 中编译错误

ios - 分发 iOS 5 应用程序

ios - 在 xib、界面生成器中创建 UIView,而不使用 UIViewController 将其附加到窗口

ios - Storyboard segue 在 UITableView 的 didSelectRow 之前被调用

ios - 横向键盘问题 - Xcode - Swift

swift - 在 Chat App 中为每个用户创建 Realm DB

swift - 使用 coredata 时,在搜索栏取消按钮后 tableview.reloaddata() 不起作用

ios - 一次在 Firebase 中填充 UITableView 一组单元格

objective-c - UITableViewCell awakeFromNib 帧大小错误