向左或向右滑动以使用集合视图单元格高亮显示加载视图控制器 [英] Swipe left or right to load the view controller with the collection view cell highlight

查看:125
本文介绍了向左或向右滑动以使用集合视图单元格高亮显示加载视图控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个名为 firstvc,secondvc,thirdvc 的视图控制器。我有一个水平滚动的集合视图。如果我在我的 mainviewcontroller上的子视图中显示我的第一个单元格我的 firstvc wil / code>。对于 2,第3个单元格也是如此。很好。

I have 3 view controllers called firstvc, secondvc, thirdvc. And I have one collection view which will scroll horizontally. If i select my first cell my firstvc wil disply in my sub view on my mainviewcontroller. Its same for 2, 3rd cell too. Its fine .

现在我需要一个功能,如果我刷我的子视图这将包含我的所有视图控制器当我选择任何细胞时。我需要向左或向右添加滑动。

Now i need one functionality like, if i swipe my subview which will have all my view controllers when i am selecting any cell. I need to add swipe left or right.

例如:

如果我在 firstvc 然后我的第一个单元格将被选中。现在,如果我向我的子视图滑动到右边我的 secondvc 必须是我的第二个单元格集合视图也必须突出显示

if i am in firstvc then my first cell will be selected . Now if i swipe my subview to right my secondvc have to come mean while my second cell of collection view also have to highlight

我不知道如何applay。

I dont know how to applay.

我的代码:

  @IBOutlet weak var collectionview: UICollectionView!

    @IBOutlet weak var contentSubView: UIView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.items.count
    }

    // make a cell for each cell index path
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        // get a reference to our storyboard cell
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell

        // Use the outlet in our custom class to get a reference to the UILabel in the cell
        cell.myLabel.text = self.items[indexPath.item]
       // cell.backgroundColor = UIColor.cyan // make cell more visible in our example project

        var borderColor: UIColor! = UIColor.clear
        //var borderWidth: CGFloat = 0

        if indexPath == selectedIndexPath{
            borderColor = UIColor.red
            //borderWidth = 1 //or whatever you please
        }else{
            borderColor = UIColor.white
           // borderWidth = 0
        }

        cell.myview.backgroundColor = borderColor
       // cell.myview.layer.borderWidth = borderColor

        return cell
    }


    // MARK: - UICollectionViewDelegate protocol

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("You selected cell #\(indexPath.item)!")

        //based on your comment remove the subviews before add on your myview
        //let cell = collectionView.cellForItemAtIndexPath(indexPath) as! MyCollectionViewCell

        selectedIndexPath = indexPath

        for subview in contentSubView.subviews {
            subview.removeFromSuperview()
        }

        let alertStoryBoard =  UIStoryboard(name: "Main", bundle: nil)
        var controller: UIViewController!

        if indexPath.item == 0 {

            if  let allCollectionViewController = alertStoryBoard.instantiateViewController(withIdentifier:"firstvc") as? firstvc  {

                controller = allCollectionViewController
            }

        } else if indexPath.item == 1 {

            if  let allCollec = alertStoryBoard.instantiateViewController(withIdentifier:"secondvc") as? secondvc  {
                controller = allCollec
            }


        }else if indexPath.item == 2 {


            if  let wController = alertStoryBoard.instantiateViewController(withIdentifier:"Thirdvc") as? Thirdvc  {
                controller = wController
            }

        }

        addChildViewController(controller)

        // Add the child's View as a subview
        contentSubView.addSubview(controller.view)
        controller.view.frame = contentSubView.bounds
        controller.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        // tell the childviewcontroller it's contained in it's parent
        controller.didMove(toParentViewController: self)

}

我的完整项目zip: https://www.dropbox.com/s/fwj745kdgqvgjxa/Collection%20view%20example.zip?dl=0

My full project zip : https://www.dropbox.com/s/fwj745kdgqvgjxa/Collection%20view%20example.zip?dl=0

推荐答案

您应该只将 UISwipeGestureRecognizer 添加到主视图控制器的视图中。
主视图控制器将负责管理手势的调用

You should just add UISwipeGestureRecognizer to the main view controller's view. The main view controller would be responsible for managing the gesture's calls

viewDidLoad

let swipeToLeft = UISwipeGestureRecognizer(target: self, action: #selector(changePageOnSwipe(_:)))
let swipeToRight = UISwipeGestureRecognizer(target: self, action: #selector(changePageOnSwipe(_:)))
swipeToLeft.direction = .right 
swipeToRight.direction = .left
self.contentSubView.addGestureRecognizer(swipeToLeft) // Gesture are added to the top view that should handle them
self.contentSubView.addGestureRecognizer(swipeToRight)

由于您必须从索引中的VC移动到另一个索引,因此您可能需要一个属性来跟踪当前选定的视图controller:

Since you will have to move from a VC at an index to another index you might need a property for keeping track of the currently selected view controller:

var currentIndexPath: IndexPath?

每次选择新VC时,您都可以更改它的值。所以:

And you can change the value of it each time a new VC is selected. So:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print("You selected cell #\(indexPath.item)!")
    self.currentIndexPath = indexPath
    // ... Other settings
}

在主ViewController中添加 changePageOnSwipe(_ gesture:UISwipeGestureRecognizer)方法。由于它是拥有 collectionView 的主要视图控制器,它将处理滑动并告诉其子项出现:

add the changePageOnSwipe(_ gesture: UISwipeGestureRecognizer) method in your main ViewController. Since it is the "chief" view controller who possesses the collectionView, it will handle the swipes and tell its children to appear:

func changePageOnSwipe(_ gesture: UISwipeGestureRecognizer) {
    guard let indexPath = self.currentIndexPath else {
        // When the page loads and there is no current selected VC, the swipe will not work
        // unless you set an initial value for self.currentIndexPath
        return
    }

    var newIndex = indexPath    // if self.collectionview.indexPathsForSelectedItems is not empty, you can also use it instead of having a self.currentIndexPath property 

    // move in the opposite direction for the movement to be intuitive
    // So swiping " <-- " should show index on the right (row + 1)
    if gesture.direction == .left {
        newIndex = IndexPath(row: newIndex.row+1, section: newIndex.section)
    } else {
        newIndex = IndexPath(row: newIndex.row-1, section: self.currentIndexPath!.section)
    }

    if canPresentPageAt(indexPath: newIndex) {
        // Programmatically select the item and make the collectionView scroll to the correct number
        self.collectionview.selectItem(at: newIndex, animated: true, scrollPosition: UICollectionViewScrollPosition.centeredHorizontally)
        // The delegate method is not automatically called when you select programmatically
        self.collectionView(self.collectionview, didSelectItemAt: newIndex!)
    } else {
        // Do something when the landing page is invalid (like if the swipe would got to page at index -1 ...)
        // You could choose to direct the user to the opposite side of the collection view (like the VC at index self.items.count-1
        print("You are tying to navigate to an invalid page")
    }
}

因为你是做滑动程序从某种程度上说,在尝试实际移动之前,您必须确保滑动有效。您必须添加安全检查

and since you are doing the swipe programmatically, you have to make sure that the swipe is valid before trying to actually move. You have to add safety checks:

/** You can use an helper method for those checks
 */
func canPresentPageAt(indexPath: IndexPath) -> Bool {
    // Do necessary checks to ensure that the user can indeed go to the desired page
    // Like: check if you have a non-nil ViewController at the given index. (If you haven't implemented index 3,4,5,... it should return false)
    //
    // This method can be called either from a swipe
    // or another way when you need it
    if indexPath.row < 0 || indexPath.row >= self.items.count {
        print("You are trying to go to a non existing page")
        return false
    } else {
        print("If you haven't implemented a VC for page 4 it will crash here")
        return true;
    }
}

最后,您可以为<$设置默认的indexPath c $ c> self.currentIndexPath viewDidLoad 中,以便用户在登陆主VC时可以滑动,而无需选择其他VC collectionView。

Finally, you can set a default indexPath for self.currentIndexPath in viewDidLoad so that the user can already swipe when he lands on your main VC without having selected another VC in the collectionView.

注意:如果你碰巧在子ViewControllers中有手势识别器,一些手势可能会发生冲突而你必须学习如何使用委托方法解决此类冲突,例如 gestureRecognizer(_:shouldRequireFailureOf :)

Note: If you happen to have gesture recognisers in the sub-ViewControllers, some gestures may conflict and you would have to learn how to resolve such conflicts with delegate methods such as gestureRecognizer(_:shouldRequireFailureOf:).

这篇关于向左或向右滑动以使用集合视图单元格高亮显示加载视图控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆