问题描述
我有一个委托方法,它将对象从详细视图控制器传递到主视图控制器,它是一个表视图控制器。然后该对象用于更新表视图的数据:
var filters = [Filter]()
func didSelectFilter(selectedFilter: Filter) {
// finds the relevant data from the array and updates it
for case var filter in filters where filter.title == selectedFilter.title {
filter.setting = selectedFilter.setting
}
tableview.reloadData()
}
我能够确认对象被正确传递。对象如下:
struct Filter {
let title: FilterType
var setting: String
}
但是,更新后的数据并没有反映在表格视图中。
我尝试为每个数据分配索引路径并更新特定单元格,但仍然没有反映更改:
if let indexPath = filter.indexPath {
let foundindexPath = IndexPath(row: indexPath.row,section: indexPath.section)
if let cell = tableView.cellForRow(at: foundindexPath) {
cell.textLabel?.text = filter.setting
}
}
我如何在细节视图控制器中使用委托方法:
override func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
let selectedData = parsedData[indexPath.row]
// update the data to be passed
filter.setting = selectedData
// pass the data to the master view controller
delegate?.didSelectFilter(selectedFilter: filter)
self.navigationController?.popViewController(animated: true)
}
class Filter {
var title: FilterType!
var setting: String!
init(title: FilterType,setting: String) {
self.title = title
self.setting = setting
}
}
换句话说,Filter
对象在主视图控制器中创建,传递给详细视图控制器,被修改,然后传递回主视图控制器。问题是更改没有反映在主视图控制器的表视图中。
解决方法
由于您的模型是 def diffs(arr,axis):
a,b = np.tril_indices(arr.shape[axis],-1)
ind1 = [slice(None) for _ in range(arr.ndim)]
ind2 = ind1.copy()
ind1[axis] = a
ind2[axis] = b
return arr[tuple(ind1)] - arr[tuple(ind2)]
,即值类型,因此在 struct
中创建变量时,您实际上是在创建副本,而不是自行修改数据源。
您可以做的是将您的模型转换为一个类,以便您只是创建对数据源中对象的引用,或者替换索引路径中的对象。例如:
for case var filter...
,
有多种方法可以做到这一点 - 您可以先仅使用您的数据来处理它,然后在您的多个控制器中实现它。
假设你有这样的东西:
enum FilterType {
case TypeA,TypeB,TypeC,TypeD
}
struct Filter {
let title: FilterType
var setting: String
}
这是一个可以作为简单视图控制器运行的示例:
class MasterViewController: UIViewController {
var filters: [Filter] = []
override func viewDidLoad() {
super.viewDidLoad()
// init array with 7 Filter objects,various "title" types
filters.append(Filter(title: .TypeA,setting: "1"))
filters.append(Filter(title: .TypeB,setting: "2"))
filters.append(Filter(title: .TypeC,setting: "3"))
filters.append(Filter(title: .TypeD,setting: "4"))
filters.append(Filter(title: .TypeB,setting: "5"))
filters.append(Filter(title: .TypeC,setting: "6"))
filters.append(Filter(title: .TypeB,setting: "7"))
print("array before update")
filters.forEach {
print($0)
}
print() // blank line
// create "selected" Filter - this would come from your Detail VC
let selFilter = Filter(title: .TypeB,setting: "Change Me")
didSelectFilter(selectedFilter: selFilter)
print("array after update")
filters.forEach {
print($0)
}
print() // blank line
}
func didSelectFilter(selectedFilter: Filter) {
// change .setting on each array element where .title == selectedFilter.title
filters.indices.filter { filters[$0].title == selectedFilter.title } .forEach {
filters[$0].setting = selectedFilter.setting
}
// tableView.reloadData()
}
}
调试控制台输出如下所示:
before
Filter(title: TestApp.FilterType.TypeA,setting: "1")
Filter(title: TestApp.FilterType.TypeB,setting: "2")
Filter(title: TestApp.FilterType.TypeC,setting: "3")
Filter(title: TestApp.FilterType.TypeD,setting: "4")
Filter(title: TestApp.FilterType.TypeB,setting: "5")
Filter(title: TestApp.FilterType.TypeC,setting: "6")
Filter(title: PanZoom.FilterType.TypeB,setting: "7")
after
Filter(title: TestApp.FilterType.TypeA,setting: "Change Me")
Filter(title: TestApp.FilterType.TypeC,setting: "Change Me")
如您所见,.title == .TypeB
的元素更新了 .setting
属性。
如果您知道,您的数组将只有每个“标题”类型的一个元素,而不是获取该类型的所有元素的索引,您可以这样做:
if let idx = filters.firstIndex(where: { $0.title == selectedFilter.title }) {
filters[idx].setting = selectedFilter.setting
}