预期结果
在自定义标签栏控制器中创建标签栏图标的通用私有方法。应成功绘制每个指示控制器的标签栏图标。
结果
失败
无法调用非函数类型的值'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
感谢。
答案 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)