从数据源方法中使用的完成块/闭合返回值

时间:2018-10-26 18:21:24

标签: swift closures datasource

我有一个自定义视图,该视图将显示在集合视图中。视图将被添加到嵌入在视图控制器中的堆栈视图中。公开了一种数据源方法以提供视图对象。

现在是问题所在,在将我的自定义视图添加到堆栈之前,我需要先进行网关调用,以检查是否允许显示该视图。 由于网关调用是异步的,因此会在回调中返回响应。基于回调,我需要实例化视图并返回提供的数据源回调。

这里是演示代码,目的是为了更好地理解。原谅我糟糕的命名约定。

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类,但无法实现我的目标。

有人可以建议我如何解决这个问题

谢谢

2 个答案:

答案 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
})