tableView ошибка

swift4
ios

#1
import UIKit

class ViewControllerM: UIViewController, UITableViewDelegate, UITableViewDataSource {
  
    
    @IBOutlet weak var ZayTableView: UITableView!
    
    var data = [
    ["dfghdfg","sfgsfgsg"], ["sdgsd", "sdfgvsd"]
    ]
   

    
    
    var p: Int!
    @IBOutlet weak var menuBarButtonItem:  UIBarButtonItem!
  
  // Переход на меню
  var menuVC: MenuViewController!
    
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
        
            
            
            menuVC = self.storyboard?.instantiateViewController(withIdentifier: "MenuVC") as! MenuViewController
        let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:)))
        swipeRight.direction = .right
       
        
        let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(_:)))
        swipeLeft.direction = .left
      
        self.view.addGestureRecognizer(swipeRight)
        self.view.addGestureRecognizer(swipeLeft)
            
            
        let nib = UINib(nibName: "CustomCell", bundle: nil)
        ZayTableView.register(nib, forCellReuseIdentifier: "customCell")
        ZayTableView.backgroundColor = UIColor.darkGray
        p = 2
    }
   
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       return data[p].count
        //return data.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") as! CustomCell
        let str = data[p][indexPath.row].components(separatedBy: " ")
        cell.customInit(text: str[1], accessoryText: str[0])
        return cell
    }
    
    @objc func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
        switch gesture.direction {
        case UISwipeGestureRecognizerDirection.right:
           // print("Right")
            showMenu()
        case UISwipeGestureRecognizerDirection.left:
           // print("Left")
            hideMenu()
        default: break
        }
    }
    
    @IBAction func menuBarButtonItem(_ sender: UIBarButtonItem) {
        if AppDelegate.isMenuVC {
            showMenu()
        } else {
            hideMenu()
        }
}
    // Функция открытия меню
    func showMenu() {
        UIView.animate(withDuration: 0.3) {
            self.menuVC.view.frame = CGRect(x: 0, y: 60, width: UIScreen.main.bounds.size.width,height: UIScreen.main.bounds.size.height)
            self.addChildViewController(self.menuVC)
            self.view.addSubview(self.menuVC.view)
            AppDelegate.isMenuVC = false
        }
}
// Функция закрытия меню
func hideMenu() {
    UIView.animate(withDuration: 0.3, animations: {
        self.menuVC.view.frame = CGRect(x: -UIScreen.main.bounds.size.width, y: 60, width:UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
        
    })  { (finished) in
        self.menuVC.view.removeFromSuperview()
        AppDelegate.isMenuVC = true
    }

}
// Пэйдж меню заявки и мониторы

@IBAction func switchCustomTableViewAction(_ sender: UISegmentedControl) {
    p = sender.selectedSegmentIndex
    ZayTableView.reloadData()
}

}
из этого vc есть два перехода , на меню, и на две вкладки, пока был только переход на меню, все работало, добавил код с вкладками, появилась фатальная ошибка, с tableview. вот второй vc где прописано меню

import UIKit
import WebKit
class MenuViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    
    @IBOutlet weak var menuTableView: UITableView!
    
    let Mytitle = ["     Обновить", "     Проверить соединение", "     О программе", "     Поддержка", "     Выйти из учетной записи"]
    // кнопка обновить
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 0 {
    let UnameViewController: unameViewController = self.storyboard?.instantiateViewController(withIdentifier: "unameViewController") as!
            unameViewController
            self.navigationController?.pushViewController(UnameViewController, animated: true)
        }
       
    // Кнопка Проверить соединение
        
         if indexPath.row == 1 {
        if functionViewController.isConnectedToNetwork(){
            //print("Internet Connection Available!")
            let alert = UIAlertController(title: "Соединение с интернетом", message: "Отлично", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        } else {
            let alert = UIAlertController(title: "Соединение с интернетом", message: "Нет соединения", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)            }
        }
        
    //кнопка выйти
        if indexPath.row == 4 {
           // UIControl().sendAction(#selector(NSXPCConnection.suspend),
                                 //  to: UIApplication.shared, for: nil)
          
                let vs = self.storyboard?.instantiateViewController(withIdentifier: "ViewController")
                self.present(vs!, animated: true)
            
         /*   let ViewControllerP: ViewController = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as!
           ViewController
            self.navigationController?.pushViewController(ViewControllerP, animated: true)*/
      }
    }
  
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        menuTableView.delegate = self
        menuTableView.dataSource = self
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Mytitle.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = menuTableView.dequeueReusableCell(withIdentifier: "MenuCell") as! MenuTableViewCell
        cell.labelText.text = Mytitle[indexPath.row]
        return cell	
    }
    
}

#2

лучше лог ошибки из консоли покажите - быстрее помогут )


#3

Еще будет лучше, если подсветку нормально сделаете, читать сложно код.


#4

Многие видимо не знают, но, выделив вставленный код и нажав на кнопочку 19, то код сформатируется в читабельный вид (точнее вставится без форматирования ))))):slight_smile:


#5
@IBOutlet weak var lbl: UILabel!
    @IBOutlet weak var seg: UISegmentedControl!
    @IBAction func ValueChanged(_ sender: UISegmentedControl) {
        if seg.selectedSegmentIndex == 0
        {
            lbl.text = " Заявки"
            lbl.isHidden = false
        }
        else if seg.selectedSegmentIndex == 1
        {
            lbl.isHidden = false
            lbl.text = "Продажа мониторов"
    }
    }

это код для вкладок, как можно сделать чтобы туда записывались данные вот в таком виде из базы данных


#6

Пожалуйста воспользуйтесь редактором для того, чтобы оформить Ваш вопрос.


#7

Прочитайте сообщение выше и вам помогут.


#8

Код не изучал, многа букаф.
Если вы используете одну и ту же таблицу для разных вкладок, то при переключении вкладок делайте необходимый запрос. Для каждой вкладки заведите переменную, которая будет хранить данные именно для этой вкладки и соответственно в каждом запросе используйте нужную переменную для хранения полученных данных. В конце любого запроса делайте обновление общей таблицы.
В numberOfRowsInSectionпроверяйте какая вкладка активна на данный момент и в зависимости от этого, возвращайте нужную переменную со свойстов .count.
Аналогично будет и в cellForRowAt: проверяете текущую вкладку, на основе этого получайте нужный класс ячейки и заполняйте его нужными данными.
Аналогично и для didSelectItemAt.


#9

Добрый день!
У меня есть структура по которой в таблице располагаю данные(это получается как выдвижное меню, нажал на строку, выехал ниже список)

  Section(courseName: "Контроллер, Коробка, Ограничитель, Розетка",
                    lessons: [
            "Контроллер Z-5R",
            "Контроллер замка ELC-T4E-5000",
            "Коробка расппред. 70x70",
            "Коробка распред. 100x100",
            "Ограничитель цепной ЦОМД",
            "Розетка 1-мест"
            ],
                    expanded: false)

далее идет код расстановки этих данных,

 override func numberOfSections(in tableView: UITableView) -> Int {
       
        return sections.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   
    return sections[section].lessons.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

 cell.textLabel?.text = sections[indexPath.section].lessons[indexPath.row]

    return cell
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 44
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if sections[indexPath.section].expanded {
        return 44
    }
return 0
}
override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return 2
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let header = ExpandableHeaderView()
    header.setup(withTitle: sections[section].courseName, section: section, delegate: self)
    return header
}
func toogleSection(header: ExpandableHeaderView, section: Int) {
    sections[section].expanded = !sections[section].expanded
    
    tableView.beginUpdates()
    for row in 0..<sections[section].lessons.count {
        tableView.reloadRows(at: [IndexPath(row: row, section: section)], with: .automatic)
    }
    tableView.endUpdates()
}

и потом я хочу по нажатию передать то что написано в строке в списке , и делаю это вот так но не работает

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let oborudovanie = segue.destination as? SpisaniePeresort {
            let index = tableView.indexPathForSelectedRow?.row
            if index != nil {
           
            
                oborudovanie.categoryTitle = sections[indexPath.section].courseName
            } else {
                oborudovanie.categoryTitle = "Undefined category"
                
            }
        }
    }

а принимаю вот так в другом классе

@IBOutlet weak var spisatText: UITextView!
var _categoryTitle: String! 

    var categoryTitle: String {
        get {
            return _categoryTitle
        }
        set {
            
            _categoryTitle = newValue
        }
    }



    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        spisatText.text = categoryTitle
        print(categoryTitle)
        print(_categoryTitle)
    }

суть такова: три класса,
что хочу: перехожу из 1 во 2(там текстовое поле, под ним есть кнопка выбор ) нажимая ее я перехожу в 3 класс где как раз мои данные что хочу выбрать по нажатию, и выйдя обратно во 2 класс увидеть это в текстовом поле, но
!!!
что на самом деле:
перехожу из 1 во 2 и у меня ошибка
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value в переменной
var _categoryTitle: String!
и я понимаю там при первом туда попадании действительно пусто, как исправить это?
Помогите пожалуйста)))


#10

сделайте ее опциональной или присвойте пустую строку

var _categoryTitle: String?
var _categoryTitle: String = ""

#11

Я делал оба варианта, все работает, но данные не отображаются в окне, может я не правильно их выбираю из таблицы?


#12

вы уверены в этом моменте? пройдитесь дебагером. должно быть

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let segue.identifier ==  "название_сигвея" {
if let oborudovanie = segue.destination as? SpisaniePeresort {

#13

я перехожу назад, уже в этот класс есть сигвей, я просто возвращаюсь по выбору данных в таблице, и они должны отобразиться в текстВью


#14

segue.identifier не обязательно проверять, достаточно будет проверить destination на приведение к классу VC


#15

Посмотрите код, может не то передаю вообще?
По сути должно по нажатию переходить назад, а он не переходит


#16

где у вас переход назад сделан? не вижу в коде


#17

не назад, сделан сегвей к таблице уже вот,

 @IBAction func VyborSpisania(_ sender: UIButton) {
        func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if segue.identifier == "prus" {
                let spisokVCv = segue.destination as! TableViewController
                
            }
        }
    }
перешел в контроллер где надо выбрать из таблицы данные, и перейти назад от куда пришел и там бы они отобразились, вы мне сами как то говорили RexHunt  , что еще один сегвей строить нельзя просто програмно перейти, вот я пытаюсь, перейти обратно с данными на которые нажал

#18


кнопка выбор чего то там, перебрасывает меня на таблицу где происходит выбор


#19

переход назад делается либо navigationController?.popViewController(), либо dismiss() (если VC показано как modal)

prepare используется только для перехода вперед.
если вам лень читать основы, вы хотя бы видео посмотрите от swiftbook’a, там все эти действия имеются.


#20

блииииин, понял,
и еще одно посмотрите вообще правильно ли я по нажатию беру данные из таблицы
там структура данных вот такая

struct Section {

    var courseName: String

    var lessons: [String]

    var expanded: Bool

    }