我有一个带有CollectionReusableView标头的UICollectionView。我想将一个字符串从collecitonview传递到标头,以便标头根据字符串知道要加载哪些数据。我正在尝试使用委托/协议来执行此操作,但在解开可选值时不断意外地发现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!)
}
}
}
以下是Header视图的代码:
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
}
}
我对委托/协议的理解是:如果要将数据(即字符串)传递到另一个视图,则使接收字符串的视图符合协议。此协议包含一个用于传递字符串的函数,当调用该函数时,它会通知另一个视图该字符串现在可供使用,然后您可以编写所需的代码并使用该字符串。那是准确的吗?
答案 0 :(得分:1)
在ProfileHeader
中,您有一个变量controller
,它正在创建一个新 Profile
实例, NOT 故事板中的Profile
视图控制器。这就是self.delegate!
中nil
为Profile.viewDidLoad()
的原因。
我将假设ProfileHeader
是Profile
视图控制器中的视图。在viewDidLoad
中,您应该将代理设置为ProfileHeader
。请参阅下面的示例代码(我假设ProfileHeader
视图的出口):
编辑:ProfileHeader
不是出口,如评论中所述。更新了我的回答以反映出来。
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!)
}
}
}
}
作为一般流程,视图控制器应该保持对视图的引用,而不是相反。因此,请从controller
视图中删除ProfileHeader
媒体资源。视图不应该关心控制器控制它的是什么。
答案 1 :(得分:0)
您对协议/委托有一些误解,但在开始iOS开发时这是正常的。
首先,为什么应用程序崩溃:
变量delegate
是可选的UserQuery
。委托是可选的,但它永远不会在你的代码中设置,所以当你打电话时:
self.delegate!.thisUser(username!)
你试图强制展开一个nil变量,这会导致崩溃。
<强>协议强>
现在,让我们谈谈协议/委托关系。
您有一个UICollectionViewController
子类,它嵌入了一个UICollectionView
对象。这个UICollectionView
将包含页眉,页脚和单元格的混合。因此,您的ProfileHeader
课程将显示在UICollectionView
。
为了填充UICollectionView
,您不需要创建自己的协议:已经有两个协议:
UICollectionViewDataSource
是符合的主要协议,因为它允许您填充集合视图UICollectionViewDelegate
用于进一步自定义您的tableview,即自定义外观和处理事件。由于您的Profile
类继承自UICollectionViewController
,因此您不必在类名后命名这些协议,因为UICollectionViewController
已符合Apple docs中所述的协议
您必须覆盖委托和协议方法才能显示某些数据。我的建议是,在使用页眉和页脚之前,只能使用UICollectionViewCell
个对象轻松启动。
通过覆盖方法-collectionView:numberOfItemsInSection:
和- collectionView:cellForItemAtIndexPath:
,您将能够填充集合视图。