ios 如何从 UICollectionViewCell 访问 UICollectionView 中 Cell 的 indexPath
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13875428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to access from UICollectionViewCell the indexPath of the Cell in UICollectionView
提问by brush51
i want to animate the UICollectionViewCell
when action is called.
i have done UICollectionViewCell
in Interface Builder
, the UICollectionView
also.
Now i want to get the correct indexPath
at my actionBtnAddToCard
method.
我想UICollectionViewCell
为调用动作的时间设置动画。
我已经完成UICollectionViewCell
了Interface Builder
,UICollectionView
也。现在我想indexPath
在我的actionBtnAddToCard
方法中得到正确的结果。
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.
how to acces the correct indexPath?
SortimentViewController 是继承 UICollectionView 的 viewController。
如何访问正确的indexPath?
UPDATE 1: edited post for better understanding.
更新 1:编辑帖子以便更好地理解。
采纳答案by Shubhank
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];
回答by carmen_munich
- (IBAction)actionAddToCart:(id)sender {
NSIndexPath *indexPath;
indexPath = [self.collectionView indexPathForItemAtPoint:[self.collectionView convertPoint:sender.center fromView:sender.superview]];
...
}
回答by Ego Slayer
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);
回答by Echelon
Using code like [[button superview] superview]
is fragile and not future-proof; indeed, it's not even guaranteed to work on all iOS versions unless you explicitly test it. I always use an iterative helper method for this purpose:-
使用像这样的代码[[button superview] superview]
是脆弱的,而且不是面向未来的;事实上,除非您明确测试它,否则它甚至不能保证适用于所有 iOS 版本。为此,我总是使用迭代辅助方法:-
- (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
. Made it a class method since it never references self
.
更新:Swift 版本的superviewWithClassName
. 使它成为类方法,因为它从不引用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}
回答by Ishan Handa
Swiftsolution: 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)
回答by Markus
You can do it like this, indexPathsForVisibleItems will return array of NSIndexPaths for items currently visible on view and first object returns the first one (if you have one cell per view).
你可以这样做,indexPathsForVisibleItems 将返回当前在视图上可见的项目的 NSIndexPaths 数组,第一个对象返回第一个(如果每个视图有一个单元格)。
NSIndexPath *indexPath = [[svc.collectionViewProdukte indexPathsForVisibleItems] firstObject]
回答by Tim
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);
}];
回答by bpolat
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)")
}
回答by Asta ni enohpi
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);
}
回答by RFAustin
//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;