[英]how to access from UICollectionViewCell the indexPath of the Cell in UICollectionView
i want to animate the UICollectionViewCell
when action is called. 我想在
UICollectionViewCell
操作时为UICollectionViewCell
设置动画。
i have done UICollectionViewCell
in Interface Builder
, the UICollectionView
also. 我已经做了
UICollectionViewCell
在Interface Builder
的UICollectionView
也。 Now i want to get the correct indexPath
at my actionBtnAddToCard
method. 现在我想在
actionBtnAddToCard
方法中获取正确的indexPath
。
thats the way i try it now (method in ProduktViewCell.m): 这就是我现在尝试的方式(ProduktViewCell.m中的方法):
- (IBAction)actionAddToCart:(id)sender {
XLog(@"");
// see this line
NSIndexPath *indexPath = ??** how can i access the correct indexPath**??;
SortimentViewController *svc = [[SortimentViewController alloc] initWithNibName:@"SortimentViewController_iPad" bundle:[NSBundle mainBundle]];
[svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];
[svc collectionView:svc.collectionViewProdukte didSelectItemAtIndexPath:indexPath];
}
SortimentViewController is the viewController which inherits the UICollectionView. SortimentViewController是viewController,它继承了UICollectionView。
how to acces the correct indexPath? 如何访问正确的indexPath?
UPDATE 1: edited post for better understanding. 更新1:编辑帖子以便更好地理解。
- (IBAction)actionAddToCart:(id)sender {
NSIndexPath *indexPath;
indexPath = [self.collectionView indexPathForItemAtPoint:[self.collectionView convertPoint:sender.center fromView:sender.superview]];
...
}
if you know the view hierarchy it is easy. 如果你知道视图层次结构很容易。
UIButton *button = (UiButton *) sender;
if the button is like this - > UITableViewCell - > button 如果按钮是这样的- > UITableViewCell - >按钮
then you can get cell like this 然后你可以像这样得到细胞
UITableViewCell *cell = (UITableViewCell *)[button superview];
if the button is like this - > UITableViewCell - > content view -> button 如果按钮是这样的- > UITableViewCell - >内容视图 - >按钮
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
and finally index path can be extracted like this 最后可以像这样提取索引路径
NSIndexPath *indexPath = [self.table_View indexPathForCell:cell];
Do Not Depend on view. 不依赖于视图。 Try this.
尝试这个。
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:buttonPosition];
NSLog(@"%ld", (long)indexPath.row);
Using code like [[button superview] superview]
is fragile and not future-proof; 使用像
[[button superview] superview]
这样的代码是脆弱的,不能面向未来; indeed, it's not even guaranteed to work on all iOS versions unless you explicitly test it. 实际上,除非您明确测试它,否则它甚至不能保证在所有iOS版本上运行。 I always use an iterative helper method for this purpose:-
为此,我总是使用迭代辅助方法: -
- (UIView *)superviewWithClassName:(NSString *)className fromView:(UIView *)view
{
while (view)
{
if ([NSStringFromClass([view class]) isEqualToString:className])
{
return view;
}
view = view.superview;
}
return nil;
}
Then I call it from the button handler like so:- 然后我从按钮处理程序中调用它,如下所示: -
- (IBAction)buttonClicked:(id)sender
{
UIButton *button = (UIButton *)sender;
UICollectionViewCell *cell = (UICollectionViewCell *)
[self superviewWithClassName:@"UICollectionViewCell"
fromView:button];
if (cell)
{
NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
// do whatever action you need with the indexPath...
}
}
UPDATE: Swift version of superviewWithClassName
. 更新:
superviewWithClassName
Swift版本。 Made it a class method since it never references self
. 使它成为一种类方法,因为它从不引用
self
。
static func superviewWithClassName(className:String, fromView view:UIView?) -> UIView? {
guard let classType = NSClassFromString(className) else {
return nil
}
var v:UIView? = view
while (v != nil) {
if v!.isKindOfClass(classType) {
return v
}
v = v!.superview
}
return nil
}
and some code to call it, either from prepareForSegue
or a button handler:- 以及从
prepareForSegue
或按钮处理程序调用它的一些代码: -
guard let cell = UIView.superviewWithClassName("UICollectionViewCell", fromView: sender as? UIView) as? UITableViewCell else {return}
Swift solution: A UICollectionView extension like this one can be useful for this. Swift解决方案:像这样的UICollectionView扩展可能对此有用。
extension UICollectionView {
func indexPathForView(view: AnyObject) -> NSIndexPath? {
let originInCollectioView = self.convertPoint(CGPointZero, fromView: (view as! UIView))
return self.indexPathForItemAtPoint(originInCollectioView)
}
}
Usage becomes easy everywhere. 到处使用变得容易。
let indexPath = collectionView.indexPathForView(button)
你可以这样做,indexPathsForVisibleItems将返回当前在视图中可见的项目的NSIndexPaths数组,第一个对象返回第一个(如果每个视图有一个单元格)。
NSIndexPath *indexPath = [[svc.collectionViewProdukte indexPathsForVisibleItems] firstObject]
If you want to animate a specific cell, you need to get a reference to that cell. 如果要为特定单元格设置动画,则需要获取对该单元格的引用。 Simply calling
只是打电话
[svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];
does nothing. 什么也没做。 You need to keep the cell that the method returns, like this:
您需要保留方法返回的单元格,如下所示:
UICollectionViewCell *cell = [svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];
After that, go ahead and animate: 之后,继续进行动画制作:
[UIView animateWithDuration:0.2f animations:^{
cell.transform = CGAffineTransformMakeScale(0.5f, 0.5f);
}];
Swift 3 Solution : Based on Ishan Handa's Answer Swift 3解决方案:基于Ishan Handa的答案
extension UICollectionView {
func indexPathForView(view: AnyObject) -> IndexPath? {
let originInCollectioView = self.convert(CGPoint.zero, from: (view as! UIView))
return self.indexPathForItem(at: originInCollectioView) as IndexPath?
}
}
Usage: 用法:
func deleteCell(sender:UIButton){
var indexPath:IndexPath? = nil
indexPath = self.collectionView.indexPathForView(view: sender)
print("index path : \(indexPath)")
}
//Note: this is for a storyboard implementation
// here is code for finding the row and section of a textfield being edited in a uicollectionview
UIView *contentView = (UIView *)[textField superview];
UICollectionViewCell *cell = (UICollectionViewCell *)[contentView superview];
cell = (UICollectionViewCell *)[contentView superview];
// determine indexpath for a specific cell in a uicollectionview
NSIndexPath *editPath = [myCollectionView indexPathForCell:cell];
int rowIndex = editPath.row;
int secIndex = editPath.section;
Even though many answer i found here .this will be shortest and useful irrespective of the view hierarchy 尽管我在这里找到了许多答案。无论视图层次如何,这都是最短且有用的
- (void) actionAddToCart:(id)sender
{
id view = [sender superview];
while (view && [view isKindOfClass:[UICollectionViewCell class]] == NO)
{
view = [view superview];
}
NSIndexPath *thisIndexPath = [self.collectionView indexPathForCell:view];
NSLog(@"%d actionAddToCart pressed",thisIndexPath.row);
}
You almost certainly have a UICollectionViewCell subclass. 你几乎肯定有一个UICollectionViewCell子类。 Just add a property and set the indexPath in cellForItemAtIndexPath.
只需添加一个属性并在cellForItemAtIndexPath中设置indexPath。
Xcode10. Xcode10。 Swift 4.2 version.
Swift 4.2版本。
extension UICollectionView {
func indexPathForView(view: AnyObject) -> IndexPath? {
guard let view = view as? UIView else { return nil }
let senderIndexPath = self.convert(CGPoint.zero, from: view)
return self.indexPathForItem(at: senderIndexPath)
}
}
Usage: 用法:
// yourView can be button for example
let indexPath = collectionView.indexPathForView(view: yourView)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.