可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How can i find indexPath
for cell
in the middle of UICollectionView
?
I have horizontal scrolling and only one big cell
is visible (partially two other cell
s on the sides are visible as well).
I need to delete cell
located in the center (means - current cell
) without touching it.
Only pressing "Trash" button and confirm Delete. But now it delete only first cell
s.
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == actionSheet.destructiveButtonIndex) {
initialPinchPoint = ????????
self.tappedCellPath = [self.collectionView indexPathForItemAtPoint:initialPinchPoint];
Technique *technique = [arrayOfTechnique objectAtIndex:self.tappedCellPath.row];
[self deleteData:[NSString stringWithFormat:@"DELETE FROM TECHNIQUES WHERE TECHNIQUENAME IS '%s'",[technique.techniquename UTF8String]]];
[arrayOfTechnique removeObjectAtIndex:self.tappedCellPath.row];
//[arrayOfTechnique removeObjectAtIndex:[custom_layout ]];
[self removeImage:technique.techniquename];
[self.collectionView performBatchUpdates:^{
[self.collectionView deleteItemsAtIndexPaths:[NSArrayarrayWithObject:self.tappedCellPath]];
} completion:nil];
[self checkArrayCount];
}
}
回答1:
Like you did yourself, indexPathForItemAtPoint
is a good way of finding the index path of the element you're interested in. If your question is: how do i know the coordinates of this point? Then you should try with (using the same name you gave it in your code snippet):
initialPinchPoint = CGPointMake(self.collectionView.center.x + self.collectionView.contentOffset.x,
self.collectionView.center.y + self.collectionView.contentOffset.y);
回答2:
This would be better code because it's cleaner and easier to read, all the content offset calculation is superfluous:
NSIndexPath *centerCellIndexPath =
[self.collectionView indexPathForItemAtPoint:
[self.view convertPoint:[self.view center] toView:self.collectionView]];
This would also be the correct representation of what you're actually trying to do:
1. Taking the center point of your viewcontroller's view - aka visual center point
2. convert it to the coordinate space of the view you're interested in - which is the collection view
3. Get the indexpath that exist at the location given.
回答3:
Here's what I did in Swift 3
private func findCenterIndex() {
let center = self.view.convert(self.collectionView.center, to: self.collectionView)
let index = collectionView!.indexPathForItem(at: center)
print(index ?? "index not found")
}
回答4:
Swift:
extension UICollectionView {
var centerPoint : CGPoint {
get {
return CGPoint(x: self.center.x + self.contentOffset.x, y: self.center.y + self.contentOffset.y);
}
}
var centerCellIndexPath: IndexPath? {
if let centerIndexPath: IndexPath = self.indexPathForItemAtPoint(self.centerPoint) {
return centerIndexPath
}
return nil
}
}
Usage :
if let centerCellIndexPath: IndexPath = collectionView.centerCellIndexPath {
print(centerCellIndexPath)
}
Swift 3:
extension UICollectionView {
var centerPoint : CGPoint {
get {
return CGPoint(x: self.center.x + self.contentOffset.x, y: self.center.y + self.contentOffset.y);
}
}
var centerCellIndexPath: IndexPath? {
if let centerIndexPath = self.indexPathForItem(at: self.centerPoint) {
return centerIndexPath
}
return nil
}
}
回答5:
Thank you micantox!
I had multiple visible cells of UICollectionView and needed to position the cell at the centre of the collection view. Something similar to Adobe Content Viewer. If someone is struggling with similar scenario:
#pragma mark - UIScrollViewDelegate methods
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
CGPoint centerPoint = CGPointMake(self.pageContentCollectionView.center.x + self.pageContentCollectionView.contentOffset.x,
self.pageContentCollectionView.center.y + self.pageContentCollectionView.contentOffset.y);
NSIndexPath *centerCellIndexPath = [self.pageContentCollectionView indexPathForItemAtPoint:centerPoint];
[self.pageContentCollectionView scrollToItemAtIndexPath:centerCellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
回答6:
I made like for horizontal UICollectionView I use Swift 2.x.
private func findCenterIndex() {
let collectionOrigin = collectionView!.bounds.origin
let collectionWidth = collectionView!.bounds.width
var centerPoint: CGPoint!
var newX: CGFloat!
if collectionOrigin.x > 0 {
newX = collectionOrigin.x + collectionWidth / 2
centerPoint = CGPoint(x: newX, y: collectionOrigin.y)
} else {
newX = collectionWidth / 2
centerPoint = CGPoint(x: newX, y: collectionOrigin.y)
}
let index = collectionView!.indexPathForItemAtPoint(centerPoint)
print(index)
}
override func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
findCenterIndex()
}
回答7:
UICollectionView
has a method - (NSIndexPath *)indexPathForItemAtPoint:(CGPoint)point
.
This method return the index path of the item at the specified point. You could calculate the point that represents the center of the UICollectionView
and then use that CGPoint
and this method to retrieve the index path of the item you want to delete.
回答8:
Swift 4
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let indexPath = collectionView.indexPathForItem(at: collectionView.bounds.center)
}
回答9:
For some of you that might be experiencing some troubles on getting the center, please look at this potential solution:
func centerCell()->UICollectionViewCell? {
// Asuming your scrolling is horizontal
let viewHorizontalCenter = self.view.bounds.width / 2
let center = CGPoint(x: viewHorizontalCenter, y: self.collectionView.center.y)
let convertedPoint = self.view.convert(center, to: self.unitsCollectionView)
let center = CGPoint(x: self.view.bounds.width / 2, y: self.unitsCollectionView.center.y)
let convertedPoint = self.view.convert(center, to: self.unitsCollectionView)
for cell in unitsCollectionView.visibleCells {
if cell.frame.contains(convertedPoint) {
print("Hello")
return cell
}
}
return nil
}
回答10:
Try this protocol...
protocol CollectionVisibleMidCell {}
extension CollectionVisibleMidCell where Self: UICollectionView {
func getMidVisibleIndexPath() -> IndexPath? {
var visibleRect = CGRect()
visibleRect.origin = self.contentOffset
visibleRect.size = self.bounds.size
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
guard let indexPath = self.indexPathForItem(at: visiblePoint) else { return nil }
return indexPath
}
}
extension UICollectionView: CollectionVisibleMidCell {}
回答11:
Based on @micantox answer. Updated code for Swift 5
let initialPinchPoint = CGPoint(x: collectionView.center.x + collectionView.contentOffset.x,
y: collectionView.center.y + collectionView.contentOffset.y)