我有一个带有two controllers,
的简单应用程序,其导航是通过UITabBarController进行的。当应用程序启动时,首次初始化时一切正常,但是当我在第一个VC中更改某些内容并切换到第二个VC,然后再次尝试返回第一个VC时-它不会出现。
ViewWillAppear()
的添加不起作用,因为调试器甚至没有显示ViewDidLoad()
或ViewWillAppear()
函数在第一个VC中起作用。
Thats how its look (CloudApp record)
MainTabBarController代码:
class MainTabBarController: UITabBarController {
var photosVC: PhotosCollectionViewController!
var likesVC: LikesCollectionViewController!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
photosVC = PhotosCollectionViewController(collectionViewLayout: WaterfallLayout())
likesVC = LikesCollectionViewController(collectionViewLayout: UICollectionViewFlowLayout())
viewControllers = [
generateNavigationController(rootViewController: photosVC,title: "Photos",image: #imageLiteral(resourceName: "photos")),generateNavigationController(rootViewController: likesVC,title: "Favourites",image: #imageLiteral(resourceName: "heart"))
]
}
override func tabBar(_ tabBar: UITabBar,didSelect item: UITabBarItem) {
if (self.selectedViewController?.isKind(of: UINavigationController.self))!
{
let nav = self.selectedViewController as! UINavigationController
nav.poptoRootViewController(animated: false)
}
}
private func generateNavigationController(rootViewController: UIViewController,title: String,image: UIImage) -> UIViewController {
let navigationVC = UINavigationController(rootViewController: rootViewController)
navigationVC.tabBarItem.title = title
navigationVC.tabBarItem.image = image
return navigationVC
}
}
PhotosCollectionVC代码:
import UIKit
class PhotosCollectionViewController: UICollectionViewController {
var networkDataFetcher = NetworkDataFetcher()
private var timer: Timer?
private var photos = [UnsplashPhoto]()
private var selectedImages = [UIImage]()
// private let itemsPerRow: CGFloat = 2 // относится к UICollectionViewDelegateFlowLayout
// private let sectionInserts = UIEdgeInsets(top: 20,left: 20,bottom: 20,right: 20) // относится к UICollectionViewDelegateFlowLayout
private lazy var addBarButtonItem: UIBarButtonItem = {
return UIBarButtonItem(barButtonSystemItem: .add,target: self,action: #selector(addBarButtonTapped))
}()
private lazy var actionBarButtonItem: UIBarButtonItem = {
return UIBarButtonItem(barButtonSystemItem: .action,action: #selector(actionBarButtonTapped))
}()
private var numberOfselectedPhotos: Int {
return collectionView.indexPathsForSelectedItems?.count ?? 0
}
private let enterSearchTermLabel: UILabel = {
let label = UILabel()
label.text = "Please enter search term above..."
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 20)
label.translatesAutoresizingMaskintoConstraints = false
return label
}()
private let spinner: uiactivityIndicatorView = {
let spinner = uiactivityIndicatorView(style: .gray)
spinner.translatesAutoresizingMaskintoConstraints = false
return spinner
}()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupNavigationBar()
setupCollectionView()
setupSearchBar()
setupEnterLabel()
setupSpinner()
}
private func undateNavButtonsState() {
addBarButtonItem.isEnabled = numberOfselectedPhotos > 0
actionBarButtonItem.isEnabled = numberOfselectedPhotos > 0
}
func refresh() {
self.selectedImages.removeAll()
self.collectionView.selectItem(at: nil,animated: true,scrollPosition: [])
undateNavButtonsState()
}
// MARK: - NavigationItems action
@objc private func addBarButtonTapped() {
print(#function)
let selectedPhotos = collectionView.indexPathsForSelectedItems?.reduce([],{ (photosss,indexPath) -> [UnsplashPhoto] in
var mutablePhotos = photosss
let photo = photos[indexPath.item]
mutablePhotos.append(photo)
return mutablePhotos
})
let alertController = UIAlertController(title: "",message: "\(selectedPhotos!.count) фото будут добавлены в альбом",preferredStyle: .alert)
let add = UIAlertaction(title: "Добавить",style: .default) { (action) in
let tabbar = self.tabBarController as! MainTabBarController
let navVC = tabbar.viewControllers?[1] as! UINavigationController
let likesVC = navVC.topViewController as! LikesCollectionViewController
likesVC.photos.append(contentsof: selectedPhotos ?? [])
likesVC.collectionView.reloadData()
self.refresh()
}
let cancel = UIAlertaction(title: "Отменить",style: .cancel) { (action) in
}
alertController.addaction(add)
alertController.addaction(cancel)
present(alertController,animated: true)
}
@objc private func actionBarButtonTapped(sender: UIBarButtonItem) {
print(#function)
let shareController = uiactivityViewController(activityItems: selectedImages,applicationactivities: nil)
shareController.completionWithItemsHandler = { _,bool,_,_ in
if bool {
self.refresh()
}
}
shareController.popoverPresentationController?.barButtonItem = sender
shareController.popoverPresentationController?.permittedArrowDirections = .any
present(shareController,completion: nil)
}
// MARK: - Setup UI Elements
private func setupCollectionView() {
collectionView.backgroundColor = .white
collectionView.register(UICollectionViewCell.self,forCellWithReuseIdentifier: "CellId")
collectionView.register(PhotosCell.self,forCellWithReuseIdentifier: PhotosCell.reuseId)
collectionView.layoutMargins = UIEdgeInsets(top: 0,left: 16,bottom: 0,right: 16)
collectionView.contentInsetadjustmentBehavior = .automatic
collectionView.allowsMultipleSelection = true
if let waterfallLayout = collectionViewLayout as? WaterfallLayout {
waterfallLayout.delegate = self
}
}
private func setupEnterLabel() {
collectionView.addSubview(enterSearchTermLabel)
enterSearchTermLabel.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isactive = true
enterSearchTermLabel.topAnchor.constraint(equalTo: collectionView.topAnchor,constant: 50).isactive = true
}
private func setupSpinner() {
view.addSubview(spinner)
spinner.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isactive = true
spinner.centerYAnchor.constraint(equalTo: collectionView.centerYAnchor).isactive = true
}
private func setupNavigationBar() {
let titleLabel = UILabel(text: "PHOTOS",font: .systemFont(ofSize: 15,weight: .medium),textColor: #colorLiteral(red: 0.5019607843,green: 0.4980392157,blue: 0.4980392157,alpha: 1))
navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: titleLabel)
navigationItem.rightBarButtonItems = [actionBarButtonItem,addBarButtonItem]
navigationController?.hidesBarsOnSwipe = true
actionBarButtonItem.isEnabled = false
addBarButtonItem.isEnabled = false
}
private func setupSearchBar() {
let seacrhController = UISearchController(searchResultsController: nil)
navigationItem.searchController = seacrhController
navigationItem.hidesSearchBarWhenScrolling = false
seacrhController.hidesnavigationBarDuringPresentation = false
seacrhController.obscuresBackgroundDuringPresentation = false
seacrhController.searchBar.delegate = self
}
// MARK: - UICollecionViewDataSource,UICollecionViewDelegate
override func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
enterSearchTermLabel.isHidden = photos.count != 0
return photos.count
}
override func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PhotosCell.reuseId,for: indexPath) as! PhotosCell
let unspashPhoto = photos[indexPath.item]
cell.unsplashPhoto = unspashPhoto
return cell
}
override func collectionView(_ collectionView: UICollectionView,didSelectItemAt indexPath: IndexPath) {
undateNavButtonsState()
let cell = collectionView.cellForItem(at: indexPath) as! PhotosCell
guard let image = cell.photoImageView.image else { return }
selectedImages.append(image)
}
override func collectionView(_ collectionView: UICollectionView,didDeselectItemAt indexPath: IndexPath) {
undateNavButtonsState()
let cell = collectionView.cellForItem(at: indexPath) as! PhotosCell
guard let image = cell.photoImageView.image else { return }
if let index = selectedImages.firstIndex(of: image) {
selectedImages.remove(at: index)
}
}
}
// MARK: - UISearchBarDelegate
extension PhotosCollectionViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar,textDidChange searchText: String) {
print(searchText)
self.spinner.startAnimating()
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 0.5,repeats: false,block: { (_) in
self.networkDataFetcher.fetchImages(searchTerm: searchText) { [weak self] (searchResults) in
guard let fetchedPhotos = searchResults else { return }
self?.spinner.stopAnimating()
self?.photos = fetchedPhotos.results
self?.collectionView.reloadData()
self?.refresh()
}
})
}
}
// MARK: - WaterfallLayoutDelegate
extension PhotosCollectionViewController: WaterfallLayoutDelegate {
func waterfallLayout(_ layout: WaterfallLayout,sizeForItemAt indexPath: IndexPath) -> CGSize {
let photo = photos[indexPath.item]
return CGSize(width: photo.width,height: photo.height)
}
}
LikesCollectionVC代码:
import UIKit
class LikesCollectionViewController: UICollectionViewController {
var photos = [UnsplashPhoto]()
private lazy var trashBarButtonItem: UIBarButtonItem = {
return UIBarButtonItem(barButtonSystemItem: .trash,action: nil)
}()
private let enterSearchTermLabel: UILabel = {
let label = UILabel()
label.text = "You haven't add a photos yet"
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 20)
label.translatesAutoresizingMaskintoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
collectionView.register(LikesCollectionViewCell.self,forCellWithReuseIdentifier: LikesCollectionViewCell.reuseId)
collectionView.contentInset = UIEdgeInsets(top: 0,left: 0,right: 0)
let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.minimumInteritemSpacing = 1
layout.minimumLinespacing = 1
setupEnterLabel()
setupNavigationBar()
}
// MARK: - Setup UI Elements
private func setupEnterLabel() {
collectionView.addSubview(enterSearchTermLabel)
enterSearchTermLabel.centerXAnchor.constraint(equalTo: collectionView.centerXAnchor).isactive = true
enterSearchTermLabel.topAnchor.constraint(equalTo: collectionView.topAnchor,constant: 50).isactive = true
}
private func setupNavigationBar() {
let titleLabel = UILabel(text: "FAVOURITES",textColor: #colorLiteral(red: 0.5,green: 0.5,blue: 0.5,alpha: 1))
navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: titleLabel)
navigationItem.rightBarButtonItem = trashBarButtonItem
trashBarButtonItem.isEnabled = false
}
// MARK: - UICollectionViewDataSource
override func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
enterSearchTermLabel.isHidden = photos.count != 0
return photos.count
}
override func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: LikesCollectionViewCell.reuseId,for: indexPath) as! LikesCollectionViewCell
let unsplashPhoto = photos[indexPath.item]
cell.unsplashPhoto = unsplashPhoto
return cell
}
}
// MARK: - UICollectionViewDelegateFlowLayout
extension LikesCollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.frame.width
return CGSize(width: width/3 - 1,height: width/3 - 1)
}
}