在Swift 3中无法调用非函数类型'UICollectionView'的值

时间:2017-03-16 14:51:15

标签: ios swift3 uicollectionview

预期结果

在自定义标签栏控制器中创建标签栏图标的通用私有方法。应成功绘制每个指示控制器的标签栏图标。

结果

失败
  

无法调用非函数类型的值'UICollectionView'

失败(通用)代码:

private func createNavController(imageName: String, _ controllerName: UICollectionViewController) -> UINavigationController {

               let layout = UICollectionViewFlowLayout()
Thrown Here->  let viewController = controllerName(collectionViewLayout: layout)
               let navController = UINavigationController(rootViewController: viewController)
               navController.tabBarItem.image = UIImage(named: imageName)

               return navController


       }

工作(非通用)代码

 let userLayout = UICollectionViewFlowLayout()
let userController = UserController(collectionViewLayout: userLayout)
let navController = UINavigationController(rootViewController: userController)
navController.tabBarItem.image = UIImage(named: "loc-map-route")

相关

class UserController : UICollectionViewController, UICollectionViewDelegateFlowLayout
{
    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView?.backgroundColor = UIColor.green

    }
}

环境

  

ios 10 swift 3 xcode 8

感谢。

3 个答案:

答案 0 :(得分:1)

createNavController的定义中,您的参数controllerName的类型为UICollectionViewController且不是函数类型,因此您无法将其称为函数,即controllerName(...)

如果您更换

let viewController = controllerName(collectionViewLayout: layout)

let viewController = UserController(collectionViewLayout: layout)

从您的工作代码,它编译好。此外,您不再需要controllerName参数。无论如何,我不太明白这是什么。您是否希望能够指定控制器类型?那么你可以像dan建议那样做(虽然这段代码需要UICollectionViewController,因为你将使用init(collectionViewLayout:))。

您还可以传递要嵌入导航控制器的视图控制器实例,如下所示:

private func createNavController(imageName: String, rootViewController: UIViewController) -> UINavigationController
{
           let navController = UINavigationController(rootViewController: rootViewController)
           navController.tabBarItem.image = UIImage(named: imageName)
           return navController
}

并将其称为:

let navController = createNavController(
    imageName: "loc-map-route",
    rootViewController: UserController(collectionViewLayout: UICollectionViewFlowLayout()))

这确实不需要UICollectionViewController因为UINavigationController.init(rootViewController:)需要UIViewController。这一切都取决于你想要达到的目标。

答案 1 :(得分:1)

你想要这样的东西吗?

private func createNavController<T: UICollectionViewController>(imageName: String, _ controllerName: T.Type) -> UINavigationController {
    let layout = UICollectionViewFlowLayout()
    let viewController = controllerName.init(collectionViewLayout: layout)
    let navController = UINavigationController(rootViewController: viewController)
    navController.tabBarItem.image = UIImage(named: imageName)
    return navController
}

然后你可以这样做:let nav = createNavController(imageName: "loc-map-route", UserCollectionController.self)并且导航将以UserCollectionController为根。

答案 2 :(得分:0)

我认为controllerName是UICollectionViewController的一个实例,所以它是一个已经初始化的UICollectionViewController。它不是UICollectionViewController子类的名称。因此,如果您只想设置该UICollectionViewController的collectionViewLayout,我会这样做:

private func createNavController(imageName: String, _ controllerName: UICollectionViewController) -> UINavigationController
{
    let layout = UICollectionViewFlowLayout()
    let viewController = controllerName.collectionViewLayout = layout
    let navController = UINavigationController(rootViewController: viewController)
    navController.tabBarItem.image = UIImage(named: imageName)

    return navController
}

你会这样称呼它:

let navController = createNavController(imageName: "my_image", myCreatedUserController)