如何在Swift

时间:2019-07-03 15:48:30

标签: ios swift uicollectionview

我创建了一个充当导航栏的集合视图,并将其设为基本视图控制器(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 个答案:

答案 0 :(得分:1)

问题是您正在尝试提供当前提供的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

答案 1 :(得分:0)

我现在无法自己尝试使用此代码,但是应该在collectionView(_ collectionView: UICollectionView, didSelectItemAt...)中添加类似的内容:

let openViewController = self.viewControllerList[indexPath.row]

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

最简单的方法是使用全局变量来跟踪选择了哪个索引,但这不是一种非常安全且不错的方法:P

答案 2 :(得分:0)

我复制并运行了您的代码,然后在这部分崩溃了

 let viewControllerList = [

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

 ]

我认为当您尝试在SecondScreen中创建AppDelegate时会出现死循环,此类的根TabBar将再次创建SecondScreen,然后它将一次又一次地重复此步骤...

您应在开始时将viewControllerList设置为空,然后在viewDidLoad的{​​{1}}中重新分配列表。

TabBar

这还将解决您遇到的崩溃(我想这是您遇到的崩溃)。因为在创建这些类时没有初始化collectionView的任何布局。就像在 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] = []

中一样进行操作
AppDelegate

希望它可以为您提供帮助。