簡體   English   中英

如何在Swift中的集合視圖中禁用特定單元格

[英]How to disable specific cells in collection view in Swift

我創建了一個充當導航欄的集合視圖,並將其設為基本視圖控制器(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,它將無法正常工作,是否存在解決這個問題的方法? 喜歡在用戶位於相應的視圖控制器上時禁用單元格。

問題是您正在嘗試呈現當前提供的vc,因此您可以執行

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

我現在collectionView(_ collectionView: UICollectionView, didSelectItemAt...)嘗試使用此代碼,但是可以在collectionView(_ collectionView: UICollectionView, didSelectItemAt...)添加類似的內容:

let openViewController = self.viewControllerList[indexPath.row]

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

最簡單的方法是使用全局變量來跟蹤選擇了哪個索引,但這不是一種非常安全且不錯的方法:P

我復制並運行了您的代碼,然后在此部分崩潰

 let viewControllerList = [

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

 ]

我認為這是一個死循環,當你嘗試創建SecondScreenAppDelegate ,根TabBar這個類的會再次創建SecondScreen ,那么它會一次又一次重復此步驟...

您應該在開始時將viewControllerList設置為空,然后在TabBarviewDidLoad中重新分配列表。

    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)

希望它能對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM