我有一个带有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, target: self, 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, animated: true, 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, target: self, 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, bottom: 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", font: .systemFont(ofSize: 15, weight: .medium), 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)
}
}
答案 0 :(得分:0)
之间的导航是通过UITabBarController进行的。
不,那不是您在做什么。您的标签栏控制器不会在两个视图控制器之间导航。它在两个导航控制器之间导航。
这就是问题所在。您无法在viewDidAppear中检测到任何内容,因为您的视图控制器不是选项卡控制器切换时出现的视图控制器。出现的是导航控制器。