我有一个带有 CollectionReusableView header 的 UICollectionView。我想将一个字符串从 collecitonview 传递到 header ,以便 header 根据该字符串知道要加载哪些数据。我正在尝试使用委托(delegate)/协议(protocol)来执行此操作,但不断“在展开可选值时意外发现 nil”。这是我的代码:
protocol UserToQuery {
func thisUser(x: String)
}
class Profile: UICollectionViewController {
var ownProfile = true
var delegate:UserToQuery?
override func viewDidLoad() {
super.viewDidLoad()
if self.ownProfile == true {
let username = PFUser.currentUser()?.username
self.delegate!.thisUser(username!)
}
}
}
这是标题 View 的代码:
class ProfileHeader: UICollectionReusableView, UserToQuery {
var id1 = String()
var controller = Profile()
override func awakeFromNib() {
print(id1)
controller.delegate? = self
}
func thisUser(x: String) {
self.id1 = x
getProfileInfo()
}
func getUserData() {
// code here uses the id1 value to get data
}
}
我对委托(delegate)/协议(protocol)的理解是这样的:如果你想将数据(即字符串)传递到另一个 View ,你可以使接收字符串的 View 符合协议(protocol)。该协议(protocol)包括一个用于传递字符串的函数,当调用该函数时,它会通知另一个 View 该字符串现在可供使用,然后您可以编写所需的代码并使用该字符串。准确吗?
最佳答案
在 ProfileHeader
中,您有一个变量 controller
,它正在创建 Profile
的新实例,它不是 Storyboard中的Profile
View Controller 。这就是 Profile.viewDidLoad()
中 self.delegate!
为 nil
的原因。
我将假设 ProfileHeader
是 Profile
View Controller 中的 View 。在 viewDidLoad
中,您应该将委托(delegate)设置为 ProfileHeader
。请参阅下面的示例代码(我假设 ProfileHeader
View 有一个导出):
编辑:ProfileHeader
不是一个 socket ,如评论中所述。更新了我的答案以反射(reflect)这一点。
class Profile: UICollectionViewController {
var ownProfile = true
var delegate:UserToQuery?
override func viewDidLoad() {
super.viewDidLoad()
// Set the delegate!
self.delegate = ProfileHeader()
if self.ownProfile == true {
let username = PFUser.currentUser()?.username
// Delegate won't be nil now
self.delegate!.thisUser(username!)
}
}
}
}
作为一般流程, View Controller 应该保留对 View 的引用,而不是相反。因此,请从 ProfileHeader
View 中删除 controller
属性。 View 不应该关心哪个 View Controller 正在控制它。
关于ios - 使用委托(delegate)/协议(protocol)传递数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34091835/