[英]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()),
]
我認為這是一個死循環,當你嘗試創建SecondScreen
在AppDelegate
,根TabBar
這個類的會再次創建SecondScreen
,那么它會一次又一次重復此步驟...
您應該在開始時將viewControllerList
設置為空,然后在TabBar
的viewDidLoad
中重新分配列表。
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.