Intended Outcome
A generic private method for creating tabbbar icons in a custom tabbar controller. Should successfully paint the tabbar icons for each indicated controller.
Result
Fails with
Cannot Call Value of Non-Function Type 'UICollectionView'
Failing (Generic) Code:
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
}
Working (non-generic) Code
let userLayout = UICollectionViewFlowLayout()
let userController = UserController(collectionViewLayout: userLayout)
let navController = UINavigationController(rootViewController: userController)
navController.tabBarItem.image = UIImage(named: "loc-map-route")
Related
class UserController : UICollectionViewController, UICollectionViewDelegateFlowLayout
{
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = UIColor.green
}
}
Environment
ios 10 swift 3 xcode 8
Thanks.
In your definition of createNavController
your parameter controllerName
is of type UICollectionViewController
and that is not a function type so you cannot call it as a function, ie controllerName(...)
.
If you replace
let viewController = controllerName(collectionViewLayout: layout)
with
let viewController = UserController(collectionViewLayout: layout)
from your working code, it compiles fine. Also, you don't need the controllerName
parameter anymore. I don't quite understand what this is for anyway. Did you want to be able to specify the controller type ? Then you could do it like dan suggests (although this code requires a UICollectionViewController
because you would be using init(collectionViewLayout:)
).
You could also pass an instance of the view controller you want embedded in the navigation controller like this:
private func createNavController(imageName: String, rootViewController: UIViewController) -> UINavigationController
{
let navController = UINavigationController(rootViewController: rootViewController)
navController.tabBarItem.image = UIImage(named: imageName)
return navController
}
and call it like this:
let navController = createNavController(
imageName: "loc-map-route",
rootViewController: UserController(collectionViewLayout: UICollectionViewFlowLayout()))
This would indeed not require a UICollectionViewController
because UINavigationController.init(rootViewController:)
takes a UIViewController
. It all depends on what you want to achieve.
Do you want something like this?
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
}
Then you can do: let nav = createNavController(imageName: "loc-map-route", UserCollectionController.self)
and nav will have a UserCollectionController
as its root.
I think that controllerName is an instance of UICollectionViewController, so it is an already initialized UICollectionViewController. It is not the name of the UICollectionViewController subclass. So if you just want to set the collectionViewLayout of that UICollectionViewController, I'd do:
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
}
The you would call it like this:
let navController = createNavController(imageName: "my_image", myCreatedUserController)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.