You are right, I am creating a new instance of the object, ProfileController, but I thought that it would be a self contained instance, and the existing would not be touched by the new one?
Post
Replies
Boosts
Views
Activity
Here is my search view controller which initialises a new ProfileController(...)
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let user = self.users[indexPath.row]
let controller = ProfileController(viewModel: self.viewModel, user: user, isEditable: false)
self.navigationController?.pushViewController(controller, animated: true)
}
in full
import JGProgressHUD
import PromiseKit
class SearchUserController: UIViewController, FollowUnfollowUserDelegate, UICollectionViewDelegate {
fileprivate let viewModel: ViewModel
fileprivate var users = [User]() {
didSet {
print("Users set: \(users)")
self.updateDataSourceWith(users: users)
}
}
var delegate: RefreshPostsDelegate?
enum Section: CaseIterable {
case main
}
fileprivate var collectionView: UICollectionView! = nil
fileprivate var datasource: UICollectionViewDiffableDataSource<Section, User>! = nil
override func viewDidLoad() {
super.viewDidLoad()
setupComponents()
configureDataSource()
}
override func viewWillAppear(_ animated: Bool) {
let hud = JGProgressHUD(style: .dark)
hud.textLabel.text = "Loading..."
hud.show(in: self.view)
self.viewModel.searchForUsers { result in
switch result {
case .success(let users):
self.users = users
case .failure(let error):
print("Error retrieving users: \(error)")
}
hud.dismiss(animated: true)
self.viewModel.getFollowingPosts { (result) in
switch result {
case .success(let post):
print(post)
case .failure(let error):
print("Failed to retrieve following: \(error)")
}
}
}
}
init(viewModel: ViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
private func createLayout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(50))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
fileprivate func setupComponents() {
self.navigationItem.title = "Search"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
self.collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: self.createLayout())
self.collectionView.backgroundColor = .systemBackground
self.collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.collectionView.alwaysBounceVertical = true
self.collectionView.isScrollEnabled = true
self.collectionView.register(SearchUserCell.self, forCellWithReuseIdentifier: SearchUserCell.reuseIdentifier)
self.collectionView.delegate = self
self.view.addSubview(collectionView)
}
fileprivate func configureDataSource() {
self.datasource = UICollectionViewDiffableDataSource<Section, User>(collectionView: self.collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, user: User) -> UICollectionViewCell? in
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SearchUserCell.reuseIdentifier, for: indexPath) as? SearchUserCell else { fatalError("Cannot create cell")}
cell.nameLabel.text = self.users[indexPath.row].fullName
cell.item = user
cell.delegate = self
return cell
}
}
fileprivate func updateDataSourceWith(users: [User]) {
var snapshot = NSDiffableDataSourceSnapshot<Section, User>()
snapshot.appendSections([.main])
snapshot.appendItems(users)
self.datasource.apply(snapshot, animatingDifferences: true)
}
func handleFollow(cell: UICollectionViewCell) {
let hud = JGProgressHUD(style: .dark)
hud.textLabel.text = "Following..."
hud.show(in: self.view)
print("Handle Follow")
guard let indexPath = self.collectionView.indexPath(for: cell) else { return }
let user = self.users[indexPath.row]
self.viewModel.followUnfollow(user: user) { (result) in
switch result {
case .success(let user):
self.users[indexPath.row].isFollowing = user.isFollowing
self.delegate?.refreshPosts()
hud.dismiss()
self.dismiss(animated: true)
case .failure(let error):
print("Failed to follow / unfollow user: \(error)")
}
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let user = self.users[indexPath.row]
let controller = ProfileController(viewModel: self.viewModel, user: user, isEditable: false)
self.navigationController?.pushViewController(controller, animated: true)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Hi, this is my tab view controller which initialises ProfileController(...)
// MainTabBarController.swift
// AWSFullStackSocial
//
// Created by Develoment on 20/07/2020.
// Copyright © 2020 Develoment. All rights reserved.
//
import UIKit
class MainTabBarController: UITabBarController, UITabBarControllerDelegate, UINavigationControllerDelegate {
let viewModel: ViewModel
//lazy load so we can inject our viewModel
private lazy var homeController = HomeController(viewModel: self.viewModel)
private let imagePickerController = UIViewController()
lazy var profileController = ProfileController(viewModel: self.viewModel, user: self.viewModel.currentUser.value)
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
setupComponents()
}
fileprivate func setupComponents() {
let homeTabBarController = UINavigationController(rootViewController: self.homeController)
homeTabBarController.tabBarItem.image = imageLiteral(resourceName: "home")
let imagePickerTabBarController = UINavigationController(rootViewController: self.imagePickerController)
imagePickerTabBarController.tabBarItem.image = imageLiteral(resourceName: "plus")
let profileTabBarController = UINavigationController(rootViewController: self.profileController)
profileTabBarController.tabBarItem.image = imageLiteral(resourceName: "home")
self.viewControllers = [homeTabBarController, imagePickerTabBarController, profileTabBarController]
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if self.viewControllers?.firstIndex(of: viewController) == 1 {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
self.present(imagePicker, animated: true)
return false
}
// if self.viewControllers?.firstIndex(of: viewController) == 2 {
// if let user = self.viewModel.currentUser.value {
// self.profileController.user = user
// }
// }
return true
}
init(viewModel: ViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
func refreshPosts() {
self.homeController.refreshPosts()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}