我有3个称为的视图控制器firstvc, secondvc, thirdvc。我有一个集合视图,它将水平滚动。如果我选择我的first cell我firstvc的我的我的子画面WIL DISPLY mainviewcontroller。它同样为2, 3rd cell过。没关系 。
firstvc, secondvc, thirdvc
first cell
firstvc
mainviewcontroller
2, 3rd cell
现在,我需要一种功能,例如,如果subview我在选择任何单元格时滑动我的所有视图控制器,它将具有所有视图控制器。我需要向左或向右滑动。
subview
例如 :
如果我参加的firstvc话,我first cell会被 选中 。现在,如果我subview从右向右滑动,我secondvc必须要刻薄,而第二个集合视图单元也必须highlight
secondvc
highlight
我不知道如何申请。
我的代码:
@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
您应该只添加UISwipeGestureRecognizer到主视图控制器的视图。主视图控制器将负责管理手势的调用
UISwipeGestureRecognizer
在viewDidLoad:
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移到另一个索引,因此可能需要一个属性来跟踪当前选定的视图控制器:
var currentIndexPath: IndexPath?
您可以在每次选择新的VC时更改其值。所以:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { print("You selected cell #\(indexPath.item)!") self.currentIndexPath = indexPath // ... Other settings }
changePageOnSwipe(_ gesture: UISwipeGestureRecognizer)在您的主ViewController中添加方法。由于拥有的是“首席”视图控制器collectionView,因此它将处理滑动并告诉其子代出现:
changePageOnSwipe(_ gesture: UISwipeGestureRecognizer)
collectionView
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") } }
并且由于您是通过编程方式进行滑动,因此在尝试实际移动之前,必须确保滑动 有效 。您必须 添加安全检查 :
/** 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 self.currentIndexPath,viewDidLoad以便用户在登陆主VC时已经可以滑动而无需在collectionView中选择另一个VC。
self.currentIndexPath
注意:如果您在子ViewController中碰巧有手势识别器,则某些手势可能会发生冲突,您将必须学习如何使用诸如的委托方法来解决此类冲突gestureRecognizer(_:shouldRequireFailureOf:)。
gestureRecognizer(_:shouldRequireFailureOf:)