首页 > 解决方案 > 领域 selectedRowAtIndexPath 使用 segue 显示不同的结果

问题描述

这是我第一次使用段控制和领域。所以目前我正在使用 segue 对 Add/EditVC 执行 segue 以修改数据。

当 segue 执行并将数据添加/EditVC 到变量 selectedTransaction 时,我希望相应地填充以下数据

/* selectedTransaction print statement Results */
print("selectedTransaction = \(selectedTransaction!)")

selectedTransaction = Transaction {
    categoryType = Category {
        type = expense;
        name = EXPENSE 3;
    };
    amount = 1000;
    date = April 2;
}

  1. amountTF.text = selectedTransaction.amount (完成且正确)
  2. categorySCoutlet.selectedSegmentIndex = selectedTransaction.categoryType.type (无法在 selectedTransaction.categoryType.type 处显示段索引)
  3. categoryTF.text = selectedTransaction.categoryType.name (名称显示正确,但是如果用户没有再次重新选择将返回 nil)

我期待所有数据都像创建一样显示。

但是,我在完成它时遇到了两个问题

  1. SegmentControl 选定索引始终为 0 而不是 selectedTransaction.categoryType.name (我希望段控件位于创建时的索引处)

  2. categoryTF.text 显示正确,但如果我没有再次选择并保持原样。当我按下保存按钮时,它会自动返回零结果。:我希望 categoryTF.text 会按创建返回,即使我没有触摸它并单击 saveButton,值也不会改变

在下面显示的 gif 中,我选择了 row2 作为示例。并且 Realm Browser 中的结果按原样显示。我只是将 amountTF.text 信息从 1200 更改为 2000,在结果域浏览器中将段控件中 cateogoryType 的结果设置为“收入”,类别将返回 nil

工作流程示例


//Data Model
//MARK: - Transaction Category Section
 enum CategoryType : String, CaseIterable {
     case income = "income"
     case expense = "expense"

     init?(id : Int) {
         if id < CategoryType.allCases.count {
             self = CategoryType.allCases[id]
         } else {
             return nil
         }
     }
 }



class Category : Object {
    @objc dynamic var type : String = CategoryType.income.rawValue
    @objc dynamic var name : String = ""

//    let parentCategory = LinkingObjects(fromType: Transaction.self, property: "ofCategory")
    convenience init(type:CategoryType, name: String) {
        self.init()
        self.type = type.rawValue
        self.name = name
    }

}
/* VC that should read and load all data to required place */

 //edit
    var selectedTransaction : Transaction!
 @IBOutlet weak var amountTF: UITextField!

    //PickerView for keyboard
    lazy var pickerView : UIPickerView = UIPickerView()
    //Segment Control
    @IBOutlet weak var categorySCoutlet: UISegmentedControl!
    @IBOutlet weak var categoryTF: UITextField!

 override func viewDidLoad() {
        super.viewDidLoad()
        amountTF.text! = selectedTransaction.amount
        categoryTF.text! = selectedTransaction.categoryType!.name

setupPicker()

    }

    @IBAction func categoryTypeSC(_ sender: UISegmentedControl) {
        guard let type = CategoryType(id: sender.selectedSegmentIndex) else {
            fatalError("error")
        }
        currentCategories = categories.filter("type == %@", type.rawValue)
        categoryTF.text = currentCategories.first?.name
        pickerView.reloadAllComponents()
        pickerView.selectRow(1, inComponent: 0, animated: true)
    }

 //MARK:- Add Transaction Btn
    @IBAction func addTransButtonTapped(_ sender: UIButton) {


    }



    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        if touches.first?.view == view {
            categoryTF.resignFirstResponder()
        }
    }


    //MARK:- Picker Helper
    func setupPicker() {
        currentCategories = categories.filter("type == %@", CategoryType.income.rawValue)
        categoryTF.inputView = pickerView

        pickerView.delegate = self
        pickerView.dataSource = self

        categorySCoutlet.setTitle("Income", forSegmentAt: 0)
        categorySCoutlet.setTitle("Expense", forSegmentAt: 1)
        categorySCoutlet.addTarget(self, action: #selector(categoryTypeSC(_:)), for: .valueChanged)

    }

标签: swiftrealmsegueuisegmentedcontrol

解决方案


你正在调用tableView.deselectRow(at: indexPath, animated: false)你的tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)方法。

这导致返回不正确indexPath的 in prepareForSegue。您应该从方法
中删除deselectRow调用, 或者您应该创建一个属性来保存. 像这样的东西: didSelectRowAtIndexPath
indexPath

// somewhere in your class
var selectedIndexPath: IndexPath?

然后

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let selectedRowForTrans : Transaction = getTransactions[indexPath.row]
    selectedIndexPath = indexPath // set the value of selectedIndexPath
    tableView.deselectRow(at: indexPath, animated: false)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
   if (segue.identifier == "editTrans") {
        if let indexPath = selectedIndexPath { // check if there is a valid indexPath
            let editTransVC = segue.destination as! AddTransactionTableViewController
            let selectedRowForTrans : Transaction = getTransactions[indexPath.row]
            editTransVC.selectedTransaction = selectedRowForTrans

        }
    }

}

希望这可以帮助


推荐阅读