迄今为止的成功:我有一个远程数据源。数据被动态拉入 View Controller 。该数据用于命名每个可重用自定义单元格上的 .title 和 .subtitle。此外,每个自定义单元格都有一个 UISwitch,我已经能够使用它来发送推送通知的“订阅”信号(对于由单元格的标题/副标题标识的给定组)和“取消订阅”信号。
我剩下的一个问题:每当用户“重新访问”设置 VC 时,当我的代码“重置”UISwitches 时,它会在 Xcode 9.2 中导致以下警告:
- UISwitch.on 必须在主线程中使用
- UISwitch.setOn(_:animated:) 只能在主线程中使用
- -[UISwitch setOn:animated:notifyingVisualElement:] 必须在主线程中使用
下面的代码“有效”——但是所需的结果发生得相当慢(确实应该“打开”的 UISwitches 需要很长时间才能最终翻转到“打开”)。
更多详细信息: 需要什么:每当 VC 显示或“重新显示”时,如果用户订阅了给定组,我需要将自定义单元格的 UISwitch“重置”为“打开”,如果用户订阅了给定组,则需要“重置”为“关闭”未订阅。理想情况下,每次显示 VC 时,都应该有东西接触 OneSignal 服务器,并使用 OneSignal.getTags() 函数找出每个组的用户“订阅状态”。我有那部分工作。这段代码是在VC中的。但我需要以正确的方式做到这一点,以适应有关线程的正确协议(protocol)。
- VC 文件“ViewController_13_Settings.swift”包含一个带有可重用自定义单元格的 TableView 。
- TableView 文件名为“CustomTableViewCell.swift”
- 自定义单元格称为“customCell”(我知道,我的名字都很有创意)。
自定义单元格(在 XIB 中设计)内部只有三个项目:
- 标题 – 要订阅或取消订阅的“组”的显示“友好名称”。从远程数据源设置
- 副标题 – 上述组的隐藏“数据库名称”。对用户隐藏。从远程数据源设置。
- UISwitch - 名为“switchMinistryGroupList”
如何以编程方式正确设置 UISwitch?
这是 ViewController_13_Settings.swift 中似乎相关的代码:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomTableViewCell
// set cell's title and subtitle
cell.textLabelMinistryGroupList?.text = MinistryGroupArray[indexPath.row]
cell.textHiddenUserTagName?.text = OneSignalUserTagArray[indexPath.row]
// set the custom cell's UISwitch.
OneSignal.getTags({ tags in
print("tags - \(tags!)")
self.OneSignalUserTags = String(describing: tags)
print("OneSignalUserTags, from within the OneSignal func, = \(self.OneSignalUserTags)")
if self.OneSignalUserTags.range(of: cell.textHiddenUserTagName.text!) != nil {
print("The \(cell.textHiddenUserTagName.text!) UserTag exists for this device.")
cell.switchMinistryGroupList.isOn = true
} else {
cell.switchMinistryGroupList.isOn = false
}
}, onFailure: { error in
print("Error getting tags - \(String(describing: error?.localizedDescription))")
// errorWithDomain - OneSignalError
// code - HTTP error code from the OneSignal server
// userInfo - JSON OneSignal responded with
})
viewWillAppear(true)
return cell
}
}
在 VC 代码的上面部分中,这部分(下面)是正在运行的部分,但显然没有正确使用线程:
if OneSignalUserTags.range(of: cell.textHiddenUserTagName.text!) != nil {
print("The \(cell.textHiddenUserTagName.text!) UserTag exists for this device.")
cell.switchMinistryGroupList.isOn = true
} else {
cell.switchMinistryGroupList.isOn = false
}
最佳答案
尚不完全清楚您的代码在做什么,但似乎有一些事情需要整理,这将帮助您解决问题。
1) 改进对象的命名。这有助于其他人在提问时了解发生了什么。
不要将您的单元格命名为 CustomTableViewCell
- 例如,将其命名为 MinistryCell
或代表其显示数据的名称。而不是 textLabelMinistryGroupList
和 textHiddenUserTagName
树 ministryGroup
和 userTagName
等。
2) 让单元格自行填充。将单元格中的 IBOutlets
设置为 private
,这样您就无法直接在 View Controller 中分配给它们。这是一个坏习惯!
3) 创建一个与您分配给单元格的数据相对应的对象(例如,Ministry)。将其分配给单元格,并让单元格分配给它的 Outlet。
4) 永远不要调用viewWillAppear
,或者类似的东西!这些由系统调用。
你最终会得到这样的结果:
在 View Controller 中
struct Ministry {
let group: String
let userTag: String
var tagExists: Bool?
}
您应该创建一个数组 var ministries: [Ministry]
并在开始时填充它,而不是分别处理 MinistryGroupArray
和 OneSignalUserTagArray
.
在您的牢房中
class MinistryCell: UITableViewCell {
@IBOutlet private weak var ministryGroup: UILabel!
@IBOutlet private weak var userTagName: UILabel!
@IBOutlet private weak var switch: UISwitch!
var ministry: Ministry? {
didSet {
ministryGroup.text = ministry?.group
userTagName.text = ministry?.userTag
if let tagExists = ministry?.tagExists {
switch.isEnabled = false
switch.isOn = tagExists
} else {
// We don't know the current state - disable the switch?
switch.isEnabled = false
}
}
}
}
然后你的 dataSource 方法将看起来像......
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! MinistryCell
let ministry = ministries[indexPath.row]
cell.ministry = ministry
if ministry.tagExists == nil {
OneSignal.getTags { tags in
// Success - so update the corresponding ministry.tagExists
// then reload the cell at this indexPath
}, onFailure: { error in
print("Error")
})
}
return cell
}
关于ios - 需要帮助在自定义单元格中设置 UISwitch(XIB、Swift 4、Xcode 9),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50036401/