У меня есть табличное представление с представлением коллекции в каждой ячейке, все они связаны с массивом. Каждое представление коллекции имеет теги, поэтому, когда у меня есть материал в массиве с самого начала, все ячейки представления таблицы и ячейки представления коллекции правильно отображаются в приложении. Но когда я добавляю элемент в массив в самом приложении (у меня есть второй контроллер представления со всем необходимым для этого), он работает, но новая ячейка табличного представления появляется только после поворота экрана (действительно странно). Я попытался добавить объект контроллера представления с табличным представлением во втором контроллере представления, где я добавляю элемент в массив. Затем во втором контроллере представления в ViewWillDisappear я перезагружаю данные() через этот объект следующим образом:
var vc : ViewController? = ViewController()
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
vc?.listOfActs.reloadData()
}
Но это приводит к EXC_BAD_INSTRUCTION
Затем я попытался добавить self.listOfActs.reloadData() в prepareForSegue в контроллере представления с табличным представлением, чтобы я мог видеть, что он, по крайней мере, обновляет данные в какой-то момент времени, но даже это не работает, когда я нажимаю при добавлении сцены второй раз.
ОБНОВЛЕНИЕ: новый MainViewController
Это новый контроллер первого представления с табличным представлением. Я переименовал его и реализовал метод добавления в массив и перезагрузки. Это работает, если я использую if let для reloadData, но затем я возвращаюсь к исходной точке, где он обновляется только при повороте экрана. Когда я избавляюсь от if let, чтобы он действительно мог попытаться обновить представление таблицы, он выдает мне ошибку Fata: неожиданно найден ноль при распаковке.
class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//The Table View
@IBOutlet var AddActButton: UIButton!
@IBOutlet weak var listOfActs: UITableView!
var sectionTapped : Int?
var indexitemTapped : Int?
override func viewDidLoad() {
super.viewDidLoad()
listOfActs.delegate = self
listOfActs.dataSource = self
}
//Table View Functions
func numberOfSections(in tableView: UITableView) -> Int {
return actsCollection.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "actCell", for: indexPath) as! ActCell
cell.setCollectionViewDataSourceDelegate(self, forSection: indexPath.section)
return cell
}
//Add To Table View
func addObjects(appendage: Act) {
actsCollection.append(appendage)
if let shit = listOfActs {
shit.reloadData()
}
}
//Header Cell
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cellHeader = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! HeaderCell
cellHeader.headerName.text = actsCollection[section].actName
return cellHeader
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
}
//Scene Collection in Act Cell
extension MainViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return actsCollection[collectionView.tag].actScenes.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "sceneCell", for: indexPath) as! SceneCell
cell.sceneTitle.text = actsCollection[collectionView.tag].actScenes[indexPath.item].sceneTitle
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
sectionTapped = collectionView.tag
indexitemTapped = indexPath.item
performSegue(withIdentifier: "showDetail", sender: self)
}
//Segue Prepare
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
let detailsVC = segue.destination as! SceneDetailController
detailsVC.textToAppearInSceneName = actsCollection[sectionTapped!].actScenes[indexitemTapped!].sceneTitle
}
}
}
ОБНОВЛЕНИЕ: Новый второй контроллер представления, который добавляется к массиву.
class AddActController: UIViewController, UITextFieldDelegate {
@IBOutlet var sceneLiveName: UILabel!
@IBOutlet var sceneNameTextField: UITextField!
@IBOutlet var sceneDescriptionTextField: UITextField!
@IBOutlet var AddSceneButton: UIButton!
@IBOutlet var cardBounds: UIView!
var newName: String? = ""
@IBOutlet var cardShadow: UIView!
var shit = MainViewController()
override func viewDidLoad() {
super.viewDidLoad()
sceneNameTextField.delegate = self
AddSceneButton.alpha = 0.0
cardBounds.layer.cornerRadius = 20.0
cardShadow.layer.shadowRadius = 25.0
cardShadow.layer.shadowOpacity = 0.4
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 0.2){
self.AddSceneButton.alpha = 1.0
}
}
@IBAction func exitButton(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
@IBAction func addSceneButton(_ sender: UIButton) {
if newName == "" {
sceneLiveName.text = "Enter Something"
sceneNameTextField.text = ""
}
else {
let appendAct: Act = Act(actName: newName!, actTheme: "Action", actScenes: [Scene(sceneTitle: "Add Act", sceneDescription: "")])
shit.addObjects(appendage: appendAct)
dismiss(animated: true, completion: nil)
}
}
//MARK: textField
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text: NSString = (sceneNameTextField.text ?? "") as NSString
let resultString = text.replacingCharacters(in: range, with: string)
sceneLiveName.text = resultString
newName = String(describing: (sceneLiveName.text)!.trimmingCharacters(in: .whitespacesAndNewlines))
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
sceneNameTextField.resignFirstResponder()
return true
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Вот класс для uitableviewcell, который содержит собственное представление коллекции.
class ActCell: UITableViewCell {
@IBOutlet fileprivate weak var sceneCollection: UICollectionView!
}
extension ActCell {
func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>(_ dataSourceDelegate: D, forSection section: Int) {
sceneCollection.delegate = dataSourceDelegate
sceneCollection.dataSource = dataSourceDelegate
sceneCollection.tag = section
sceneCollection.reloadData()
}
}
А вот и модель с пользовательскими данными, включая акты и сцены.
struct Scene {
var sceneTitle: String
var sceneDescription: String
//var characters: [Character]
//var location: Location
}
struct Act {
var actName: String
var actTheme: String
var actScenes : [Scene] = []
}
var actsCollection : [Act] = [
Act(actName: "dfdsfdsfdsf", actTheme: "Action", actScenes: [Scene(sceneTitle: "Example Act", sceneDescription: "")])
]
Любая помощь приветствуется. Спасибо тебе за все.