Cells and UIStackView Layouts
AppStore JSON APIs
In this lesson, we'll further improve the look and feel of our application by implementing the cells that belong in our Search Controller view. We do this by first registering a cell class for our AppsSearchController component. Then we return these cells by overriding numberOfItems:section and cellForItem:indexPath. Finally we go through how to construct our cell layout using a UIStackView component. To get things centered in our UIStackView, we set it's alignment property to .center. Playing around with these properties can really make the layout process a lot easier depending on how you want your components to look.

Comments (9)
Ally Makongo
4 years ago
I find it weird the cells are not showing in emulator. import UIKit class BaseTabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() viewControllers = [ createNavController(viewController: AppSearchController(), title: "Search", imageName: "search"), createNavController(viewController: UIViewController(), title: "Today", imageName: "today_icon"), createNavController(viewController: UIViewController(), title: "Apps", imageName: "apps")] } fileprivate func createNavController(viewController: UIViewController, title: String, imageName: String) -> UIViewController { let navController = UINavigationController(rootViewController: viewController) navController.tabBarItem.title = title viewController.view.backgroundColor = .white viewController.navigationItem.title = title navController.tabBarItem.image = UIImage(named: imageName) navController.navigationBar.prefersLargeTitles = true return navController } } import UIKit class AppSearchController: UICollectionViewController, UICollectionViewDelegateFlowLayout { fileprivate let cellId = "cellId" override func viewDidLoad() { super.viewDidLoad() collectionView.backgroundColor = .white collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: view.frame.width, height: 250) } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 5 } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) cell.backgroundColor = .red return cell } init(){ super.init(collectionViewLayout: UICollectionViewLayout()) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window?.rootViewController = BaseTabBarController() return true } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } }
Brian Voong
4 years ago
Ally Makongo
4 years ago
Thanks a lot brother!
ezechinwa
4 years ago
Please why is UICollectionViewFlowLayout better than UICollectionViewLayout ?
Brian Voong
4 years ago
ezechinwa
4 years ago
Thanks Alot Brian :)
Ally Makongo
4 years ago
what am I doing wrong here? The cells are not showing
Phsartech
4 years ago
You might forget to register the custom cell you might have created
Conte.Ab
4 years ago
or you might forget to set the background color of the cell or collectionViewCell. It does happen to me too
adam_rich
4 years ago
For some reason, I cannot figure out the challenge of getting the padding on the sides of the stack view I printed the code and went through it all with a highlighter what am I overlooking?
Igor Tkach
4 years ago
for trailing anchor use stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16).isActive = true for leading anchor use stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16).isActive = true
Tokyojogo
4 years ago
Hi Brian, how come for the imageView you didn't have to set the translatesAutoresizingMaskIntoConstraints = false? Is it because you've already set it for the stackView so everything inside gets it too? Thanks.
Brian Voong
4 years ago
Conte.Ab
4 years ago
YodaVN
4 years ago
"Controller" but "Views" >.>
adslwy
4 years ago
Hi Brian, I wonder what's the reason we need to add image height anchor when using stack alignment so it can show up correctly? And why if I add the image height anchor constrain without enable stack alignment, the compiler will complain: "Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. " Thanks
dclawson
3 years ago
Not Brian, but I think it uses the intrinsic height to know where to place things. If it's unconstrained, then it just kind of guesses, and in this case, it just guesses "zero". With the warning on the constraints, you'd have to think through logically/geometrically to find out which ones were in conflict. Autolayout chooses a priority, and I think it's based on which one is most recent. It can be tricky. I think there's a way to show the constraints in the UI somehow, but I forget where I saw it.
Brian Voong
3 years ago
pdefilippi
4 years ago
Hey Brian, What are you hitting after you type .bold to get .boldSystemFont to auto complete?
dclawson
3 years ago
You probably already figured this out, but it must have been an XCode bug for you. I just tried it, and it worked for me on two separate occasions. I have noticed that if there's anything else wrong with your code that prevents it from compiling, sometimes XCode autocomplete just kind of fails until you get other stuff sorted out.
Niketan Shah
3 years ago
Hey Brian, For search listing, Why you are using UICollectionView instead of using UITableView? Is UICollectionView faster than UITableView? I saw your other tutorials too, I see that you usually prefer UICollectionView over UITableView. I am very curious about it.
Brian Voong
3 years ago
Niketan Shah
3 years ago
Thank you :) Also I would like to know one thing, Is there any reason of doing design programmatically rather than doing directly in StoryBoard? Which is preferable more?
Brian Voong
3 years ago
Niketan Shah
3 years ago
My concern is regarding app performance and speed. Does app becomes slow if done designing through storyboards? Or may I know which things to be taken into consideration to increase the performance and speed?
Brian Voong
3 years ago
JoevegaCoding
3 years ago
Hey Brian, I prefer using storyboard instead of programatic UI. Will I be able to follow up throughout the course if I use the latter? Thanks!
HELP & SUPPORT