Как отключить определенные ячейки в представлении коллекции в Swift - PullRequest
0 голосов
/ 03 июля 2019

Я создал коллекционное представление, которое действует как панель навигации, и я сделал это базовым контроллером представления (TabBar.swift), и оно будет отображаться на всех других моих контроллерах представления.на данный момент у него есть 3 ячейки, и нажатие на каждую ячейку направит пользователя к соответствующему контроллеру представления.Контроллерами 3 представлений являются FirstScreen.swift, SecondScreen.swift и ThirdScreen.swift.Вот код контроллера базового представления:

TabBar.swift

struct OpenViewController {
    var viewController: UIViewController
}

class TabBar: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Call all the elements
        setupCollectionView()

        view.backgroundColor = .white


    }

    let viewControllerList = [

        OpenViewController(viewController: FirstScreen()),
        OpenViewController(viewController: SecondScreen()),
        OpenViewController(viewController: ThirdScreen()),

    ]

    // Setup the collection veiw
    func setupCollectionView() {

        collectionView?.backgroundColor = .clear
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellID")
        collectionView.showsHorizontalScrollIndicator = false

        view.addSubview(collectionView)
        addCollectionViewConstraints()

    }

    // Add constraints to the collection view
    func addCollectionViewConstraints() {

        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
        collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        collectionView.heightAnchor.constraint(equalTo: collectionView.widthAnchor, multiplier: 0.3).isActive = true

    }

    // The number of elements inside the collection view
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 3
    }

    // Adding the cells
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath)

        // Customize the cells
        cell.backgroundColor = .clear
        cell.layer.cornerRadius = collectionView.contentSize.height / 2
        cell.layer.borderWidth = 1
        cell.layer.borderColor = UIColor.black.cgColor

        return cell
    }

    // The witdth and the height of the cell
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.height, height: collectionView.frame.height)
    }

    // Padding to the cells
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
    }

    // Selecting a cell and navigating to another view controller
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        let openViewController = self.viewControllerList[indexPath.row]
        self.present(openViewController.viewController, animated: true)
    }

}

FirstScreen.swift

class FirstScreen: TabBar {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .yellow

    }
}

SecondScreen.swift

class SecondScreen: TabBar {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .green

    }
}

ThirdScreen.swift

class ThirdScreen: TabBar {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .red

    }
}

AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    window = UIWindow()
    window?.makeKeyAndVisible()

    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    let firstScreen = SecondScreen(collectionViewLayout: layout)

    window?.rootViewController = firstScreen

    return true
}

Теперь, когда я запускаю это, это происходит сбой, и причина, например, в том, что пользователь находится на FirstScreen.swift, и пользователь нажимает на первую ячейку, которая приведет пользователя к FirstScreen.swift, он будетне работает, есть ли способ решить эту проблему?Как отключить ячейку, когда пользователь находится на соответствующем контроллере представления.

Ответы [ 3 ]

1 голос
/ 03 июля 2019

Проблема в том, что вы пытаетесь представить виртуальный канал, который в данный момент представлен, поэтому вы можете сделать

var current:Int?   

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard current != indexPath.row else { return }
    let openViewController = self.viewControllerList[indexPath.row]
    self.present(openViewController.viewController, animated: true)
    current = indexPath.row
}

Кстати, я думаю, что это лучше всего для UISegmentedControl

0 голосов
/ 07 июля 2019

Я скопировал и запустил ваш код, затем я получил сбой в этой части

 let viewControllerList = [

        OpenViewController(viewController: FirstScreen()),
        OpenViewController(viewController: SecondScreen()),
        OpenViewController(viewController: ThirdScreen()),

 ]

Я думаю, что существует тупик, когда вы пытаетесь создать SecondScreen в AppDelegate, корень TabBar этого класса создаст снова SecondScreen, затем он будет повторять этот шаг снова и снова ...

Вы должны установить viewControllerList пустым в начале, затем переназначить список в viewDidLoad из TabBar.

    override func viewDidLoad() {
        super.viewDidLoad()

        // Call all the elements
        setupCollectionView()

        view.backgroundColor = .white

        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        viewControllerList = [
            OpenViewController(viewController: FirstScreen(collectionViewLayout: layout)),
            OpenViewController(viewController: SecondScreen(collectionViewLayout: layout)),
            OpenViewController(viewController: ThirdScreen(collectionViewLayout: layout)),
        ]
    }

    var viewControllerList: [OpenViewController] = []

Это также разрешит аварию, с которой вы столкнулись (я полагаю, это авария, с которой вы столкнулись).Потому что вы не инициализировали никакой макет collectionView при создании этих классов.Просто сделайте это, как вы делали в AppDelegate

SecondScreen(collectionViewLayout: layout)

Надеюсь, это поможет вам.

0 голосов
/ 03 июля 2019

Я не могу попробовать этот код сам сейчас, но добавление чего-то вроде этого в collectionView(_ collectionView: UICollectionView, didSelectItemAt...) должно работать:

let openViewController = self.viewControllerList[indexPath.row]

if type(of: self) != type(of: secondViewController) {
    self.present(openViewController.viewController, animated: true)
}

Самый простой способ - это глобальная переменная, отслеживающая, какой индекс выбран, но это не очень безопасный и приятный способ сделать это: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...