我有一个自定义视图,该视图将显示在集合视图中。视图将被添加到嵌入在视图控制器中的堆栈视图中。公开了一种数据源方法以提供视图对象。
现在是问题所在,在将我的自定义视图添加到堆栈之前,我需要先进行网关调用,以检查是否允许显示该视图。 由于网关调用是异步的,因此会在回调中返回响应。基于回调,我需要实例化视图并返回提供的数据源回调。
这里是演示代码,目的是为了更好地理解。原谅我糟糕的命名约定。
library(magrittr)
library(dplyr)
m<- read.csv("~/df55testR.csv",
stringsAsFactors=FALSE, header=T)
m<-m%>%select(2:6)
ml <- reshape2::melt(data = m, id.vars="Firm", variable.name = "year", value.name="bin")
ml
ml$Test_Gr <- apply(ml[,2:3], 1, paste0, collapse="_")
mw <- reshape2::dcast(ml, Firm ~ bin, fun.aggregate = length)
mwm<-as.matrix(mw[,-1])
mwm
mcm <- t(mwm) %*% mwm
colnames(mcm) <- colnames(mw)[-1]
rownames(wc) <- colnames(xw)[-1]
gplots::heatmap.2(mcm, trace="none", col = rev(heat.colors(15)))
我读到的所有建议都是关于使用闭包传递值,但是由于数据源方法和网关调用中的回调,我需要使用老式的return语句。
编辑1
我已更新代码段,以更好地理解。 我无法更改函数签名,因为它是框架和数据源方法的一部分。
此方法在不同功能之间共享。我的意思是,要在堆栈视图中添加不同的视图,并且它们有自己的条件检查是否可以添加它们。 因此,基本上我想要达到的目标是直到我没有收到网关操作的响应,程序执行才应该继续进行。 我尝试使用DispatchGroup类,但无法实现我的目标。
有人可以建议我如何解决这个问题
谢谢
答案 0 :(得分:1)
关于这一点,正确的解决方案是不要从函数中返回某些内容,而应该对该函数进行补全。
func customeViewInStack(customView: UIView, completion: @escaping ([UIView]?) -> Void) {
self.checkIfViewShouldBeShown(onCompletionHandler: { shouldDisplayView in
completion(shouldDisplayView ? [...(put the stack of views to return here))] : nil)
})
}
编辑:我第一次读得不好,所以我提高了答案。
当您需要将其传递到集合视图时,建议您将其存储起来,然后重新加载集合:
private var viewsForCollection: [UIView] = []
customeViewInStack(customView: UIView(), completion: { [weak self] views in
self?.viewsForCollection = views ?? [] // I guess optionality for array is unnecessary
self?.collectionView.reloadData()
})
起初,您将有一个空集合,但是一旦视图准备就绪,就可以重新加载它。
答案 1 :(得分:0)
您将需要声明自己的完成块并使用它来获取新视图:
这是声明的样子:
// Declaration
func customeViewInStack(customView: UIView, completion: @escaping ([UIView]? -> ()) {
self.checkIfViewShouldBeShown(onCompletionHandler: { shouldDisplayView in
if shouldDisplayView
// Call the completion block with the views
completion(views)
else
// Call the completion block with nil
completion(nil)
})
}
然后在使用时,就像使用checkIfViewShouldBeShown
方法一样使用它:
customViewInStack(customView: customView, completion: { views in
guard let views = views else {
// Views are nil
}
// Do what you need to do with views
})