I have a problem.
When I select cell
of UICollectionView
, I must go to next ViewController
, but it not works.
NavigationController
, pushed ViewController
, my object
are initialized, but I stay at current controller
What goes wrong?
Why NavigationController after pushing don't know about RoomViewController? it's absent in ViewControllers list:
StoryBoard screenshot:
initial ViewController, which push MainViewController code:
func showMainViewController(house: NLHouse) {
let mainController = self.storyboard?.instantiateViewController(withIdentifier: "MainViewController") as? MainViewController
if let mainController = mainController {
mainController.house = house
self.navigationController?.pushViewController(mainController, animated: true)
print()
}
}
MainViewController, which push RoomViewController code:
class MainViewController: UIViewController {
@IBOutlet weak var devicesCollectionView: UICollectionView!
var house: NLHouse?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print()
devicesCollectionView.reloadData()
}
}
extension MainViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return house?.rooms?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let roomCell = devicesCollectionView.dequeueReusableCell(withReuseIdentifier: "roomCell", for: indexPath) as? RoomsCollectionViewCell
if let roomCell = roomCell, let rooms = house?.rooms {
roomCell.setRoomInfoInCell(room: rooms[indexPath.item])
}
return roomCell ?? UICollectionViewCell()
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let roomController = self.storyboard?.instantiateViewController(withIdentifier: "RoomViewController") as? RoomViewController, let rooms = house?.rooms {
roomController.room = rooms[indexPath.item]
self.navigationController?.pushViewController(roomController, animated: true)
print()
}
}
}
push code:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if let roomController = self.storyboard?.instantiateViewController(withIdentifier: "RoomViewController") as? RoomViewController, let rooms = house?.rooms {
roomController.room = rooms[indexPath.item]
self.navigationController?.pushViewController(roomController, animated: true)
print()
}
pushed class code:
import UIKit
class RoomViewController: UIViewController {
@IBOutlet weak var roomNameLabel: UILabel!
@IBOutlet weak var devicesCollectionView: UICollectionView!
var room: NLRoom?
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
if let room = room {
if let roomName = room.roomName {
roomNameLabel.text = roomName
}
devicesCollectionView.reloadData()
}
}
}
extension RoomViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return room?.devices?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let deviceCell = devicesCollectionView.dequeueReusableCell(withReuseIdentifier: "deviceCell", for: indexPath) as? DevicesCollectionViewCell
if let deviceCell = deviceCell, let devices = room?.devices {
deviceCell.setDeviceInfoInCell(device: devices[indexPath.item])
}
return deviceCell ?? UICollectionViewCell()
}
}
What i see on your screenshot: you have viewController that is root for your navigation controller. Two additional view controllers: main
and room
.
Tell me, how you present your MainViewController
?
I assume that you push your MainViewController
from ViewController
with creation new UINavigationController
and setting MainViewController
as root viewController for it. Then you try to push RootViewController
from first UINavigationController
. If you want your project work well - remove ViewController from storyboard, connect MainViewController instead it. This way, when you will push RoomViewController
they will be in the same navigation stack with your MainViewController
.
You need your stucture look like this:
Add your full project in zip file to investigate for sure.
UPDATE:
After reviewing suorce code of ViewController i found that showMainViewController
method is being called from background (after receiving data from API). Dispatching push on main queue solved problem.
For future: anything you do with UI do in main thread.
Please add
super.viewWillAppear(animated)
as first line below function of RoomViewController
override func viewWillAppear(_ animated: Bool)
What is happening is you are instantiating the controller but when you push the viewWillAppear doesn't invoke the defined methods required for view to appear because super.viewWillAppear is not called.
or
It might happen that you the controller where you have called the below function is not itself in the navigation stack. Make sure the VC is part of a navigation controller's view controllers, then only this will be effective.
self.navigationController?.pushViewController(roomController, animated: true)
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.