获取单元格索引 - Peek and Pop
Get Index of Cell - Peek and Pop
我有一个集合视图,我正在尝试获取我正在查看和弹出的单元格的索引。
问题
目前我正在使用 indexPathForItemAtPoint:
但是这个 总是 returns 0
无论我在屏幕上点击什么地方。
代码
集合视图控制器:
- (void)viewDidLoad {
[super viewDidLoad];
[self registerForPreviewingWithDelegate:self sourceView:self.collectionView];
}
- (UIViewController *) previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
CellEditViewController *CEVC = [self.storyboard instantiateViewControllerWithIdentifier:@"detail"]; //The view I want peek/pop to
NSLog(@"Location: %f,%f", location.x, location.y);
NSLog(@"Index of: %lu", [[self.collectionView indexPathForItemAtPoint:location] row]);
[CEVC setPreferredContentSize:CGSizeMake(0.0, 320.0)];
return CEVC;
}
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
[self showViewController:viewControllerToCommit sender:self];
}
我试过的
- 正在创建一个新位置来标识索引单元格。
- 移动
registerForPreviewingWithDelegate:sourceView:
到我创建每个单元格的位置。
- 将
previewingContext:viewControllerForLocation:
和 previewingContext:commitViewController:
移动到单元格视图方法,由于其他原因,这不起作用。
我认为这不是预览的问题,因为当我用 UITapGestureRecognizer
实现同样的事情时,我得到了类似的输出:
点击识别器:
- (void) processDoubleTap:(UITapGestureRecognizer *)sender {
NSLog(@"Got tapped twice");
if (sender.state == UIGestureRecognizerStateEnded) {
CGPoint point = [sender locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
NSLog(@"Index was: %lu", [indexPath row]);
if (indexPath) {
NSLog(@"Index was double tapped");
}
}
}
输出:
2017-12-25 10:48:13.990523-0800 quickthings[3052:356150] Got tapped twice
2017-12-25 10:48:13.990843-0800 quickthings[3052:356150] Index was: 0
来源
截图
事情是这样的,这正是我想要的。我唯一想做的另一件事是当单元格被点击时也能够获得被点击单元格的索引。
故事板中的集合视图
(蓝色)UIView
“链接”到集合视图控制器(下面第二个屏幕截图中的顶部视图控制器)。
原因:
问题的主要原因是 CollectionViewController 在 Storyboard 中的设置方式。总之,这些是它的主要问题:
- CollectionViewController 作为 UIViewController 添加,然后 class 更改为 CollectionViewController,但问题是它是 UICollectionViewController 的子class。所以故事板认为它是什么和实际是什么之间存在不匹配。您应该首先将其添加为 UICollectionViewController。
- CollectionViewControllers 顶视图已将其 class 从 UIView 更改为 UICollectionView,我认为这与 UICollectionViewController 的设置方式相匹配。所以这里又出现了一个未匹配项,这意味着您在 Interface Builder 中看不到任何正确的属性。
- 然后添加一个额外的 UICollectionView 作为主 CollectionViewController 主视图的子视图。这有它的数据源和委托 linked 到 CollectionViewController class 并且是实际显示的那个。这一切都使用原型电池正确设置。但是,它没有作为 IBOutlet linked 到 class 中,因此您无法引用它。
那么为什么这会导致您看到的问题。在 CollectionViewController 中,当您引用 self.collectionView 时,您指的是不是显示单元格的顶层。那不是显示单元格的那个,实际上没有显示单元格,所以当您在特定点请求单元格时,它总是 return nil ,因此您得到的行值为零。如果您能够访问实际显示单元格的 UICollectionView,您可以获得正确的值。
除此之外还有其他你没有遇到的问题。
解决方法:
这个问题基本上有两个主要的解决方案...
- 从情节提要中删除 CollectionViewController,然后将其重新添加为 UICollectionViewController。这当然是解决它的理想方法,因为它将全部正确设置,但是它需要再次在情节提要中重新创建整个控制器并且不是绝对必要的,因为您可以执行方法 2...
- 您可以修改情节提要和设置以正确反映您的设置并使其正常工作。
我已经尝试了方法 2,这是我必须做的才能使其正常工作:
将 CollectionViewController 从 subclassing UICollectionViewController 更改为 subclassing UIViewController,因为它将成为 UICollectionView 的容器。您还需要使其直接支持 UICollectionViewDataSource 和 UICollectionViewDelegate,因为 UICollectionViewController 已经这样做了,但 UIViewController 还没有。所以在 CollectionViewController.m 中更改此行:
@interface CollectionViewController : UICollectionViewController
对此:
@interface CollectionViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
接下来在故事板中将 CollectionViewController 的顶级视图改回 UIView(即删除 class 属性 中的 UICollectionView)。它现在只是真正的 UICollectionView 的持有者。
接下来 link 故事板中设置的剩余 UICollectionView 到 CollectionViewController.h 中的 IBOutlet 称为 'collectionView' 以便所有对 self.collectionView 的引用现在都指正确的事情。
我必须做的一件额外的事情,但我不确定为什么要更改 UITableViewController 和 UICollectionViewController 的单元格标识符,这样它们就不会同时存在 'Cell'。我刚刚使用了 'TableCell' 和 'CollectionCell'。如果您不这样做,他们都会出于某种原因感到困惑。
(我想这就是我所做的一切,但如果没有,我相信您将能够处理任何其他问题)
完成所有操作后,self.collectionView 将引用正确的内容,您将在 - (UIViewController *) previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
方法中获得正确的索引路径。
奖金回合:
现在一些额外的奖金评论。您似乎也对 TableViewController 有同样的问题,尽管它目前似乎没有引起任何问题。不过你可能想修复它。
当我第一次 运行 项目时,我无论如何都看不到向 table 添加任何内容,因为缺少文本字段和 'add' 按钮。结果是因为我使用的是 iPhone 8 模拟器而不是 iPhone X 模拟器,一旦我切换一切正常,我可以看到文本字段和 'add' 按钮。这意味着您的界面没有正确适应不同的设备尺寸(完全没有),您应该真正解决这个问题。
哎呀,比我想象的要长,但希望能解决问题。另外,因为我可以访问 git 存储库,所以我可以克隆它并进行更改。我显然没有提交它们,因为它是你的存储库,但如果你无法理解我为让它工作所做的工作,我可以将它们提交到你的主 b运行ch 或作为一个新的 b运行ch.
我有一个集合视图,我正在尝试获取我正在查看和弹出的单元格的索引。
问题
目前我正在使用 indexPathForItemAtPoint:
但是这个 总是 returns 0
无论我在屏幕上点击什么地方。
代码
集合视图控制器:
- (void)viewDidLoad {
[super viewDidLoad];
[self registerForPreviewingWithDelegate:self sourceView:self.collectionView];
}
- (UIViewController *) previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location {
CellEditViewController *CEVC = [self.storyboard instantiateViewControllerWithIdentifier:@"detail"]; //The view I want peek/pop to
NSLog(@"Location: %f,%f", location.x, location.y);
NSLog(@"Index of: %lu", [[self.collectionView indexPathForItemAtPoint:location] row]);
[CEVC setPreferredContentSize:CGSizeMake(0.0, 320.0)];
return CEVC;
}
- (void)previewingContext:(id <UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit {
[self showViewController:viewControllerToCommit sender:self];
}
我试过的
- 正在创建一个新位置来标识索引单元格。
- 移动
registerForPreviewingWithDelegate:sourceView:
到我创建每个单元格的位置。 - 将
previewingContext:viewControllerForLocation:
和previewingContext:commitViewController:
移动到单元格视图方法,由于其他原因,这不起作用。
我认为这不是预览的问题,因为当我用 UITapGestureRecognizer
实现同样的事情时,我得到了类似的输出:
点击识别器:
- (void) processDoubleTap:(UITapGestureRecognizer *)sender {
NSLog(@"Got tapped twice");
if (sender.state == UIGestureRecognizerStateEnded) {
CGPoint point = [sender locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
NSLog(@"Index was: %lu", [indexPath row]);
if (indexPath) {
NSLog(@"Index was double tapped");
}
}
}
输出:
2017-12-25 10:48:13.990523-0800 quickthings[3052:356150] Got tapped twice
2017-12-25 10:48:13.990843-0800 quickthings[3052:356150] Index was: 0
来源
截图
事情是这样的,这正是我想要的。我唯一想做的另一件事是当单元格被点击时也能够获得被点击单元格的索引。
故事板中的集合视图
(蓝色)UIView
“链接”到集合视图控制器(下面第二个屏幕截图中的顶部视图控制器)。
原因: 问题的主要原因是 CollectionViewController 在 Storyboard 中的设置方式。总之,这些是它的主要问题:
- CollectionViewController 作为 UIViewController 添加,然后 class 更改为 CollectionViewController,但问题是它是 UICollectionViewController 的子class。所以故事板认为它是什么和实际是什么之间存在不匹配。您应该首先将其添加为 UICollectionViewController。
- CollectionViewControllers 顶视图已将其 class 从 UIView 更改为 UICollectionView,我认为这与 UICollectionViewController 的设置方式相匹配。所以这里又出现了一个未匹配项,这意味着您在 Interface Builder 中看不到任何正确的属性。
- 然后添加一个额外的 UICollectionView 作为主 CollectionViewController 主视图的子视图。这有它的数据源和委托 linked 到 CollectionViewController class 并且是实际显示的那个。这一切都使用原型电池正确设置。但是,它没有作为 IBOutlet linked 到 class 中,因此您无法引用它。
那么为什么这会导致您看到的问题。在 CollectionViewController 中,当您引用 self.collectionView 时,您指的是不是显示单元格的顶层。那不是显示单元格的那个,实际上没有显示单元格,所以当您在特定点请求单元格时,它总是 return nil ,因此您得到的行值为零。如果您能够访问实际显示单元格的 UICollectionView,您可以获得正确的值。
除此之外还有其他你没有遇到的问题。
解决方法: 这个问题基本上有两个主要的解决方案...
- 从情节提要中删除 CollectionViewController,然后将其重新添加为 UICollectionViewController。这当然是解决它的理想方法,因为它将全部正确设置,但是它需要再次在情节提要中重新创建整个控制器并且不是绝对必要的,因为您可以执行方法 2...
- 您可以修改情节提要和设置以正确反映您的设置并使其正常工作。
我已经尝试了方法 2,这是我必须做的才能使其正常工作:
将 CollectionViewController 从 subclassing UICollectionViewController 更改为 subclassing UIViewController,因为它将成为 UICollectionView 的容器。您还需要使其直接支持 UICollectionViewDataSource 和 UICollectionViewDelegate,因为 UICollectionViewController 已经这样做了,但 UIViewController 还没有。所以在 CollectionViewController.m 中更改此行:
@interface CollectionViewController : UICollectionViewController
对此:
@interface CollectionViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
接下来在故事板中将 CollectionViewController 的顶级视图改回 UIView(即删除 class 属性 中的 UICollectionView)。它现在只是真正的 UICollectionView 的持有者。
接下来 link 故事板中设置的剩余 UICollectionView 到 CollectionViewController.h 中的 IBOutlet 称为 'collectionView' 以便所有对 self.collectionView 的引用现在都指正确的事情。
我必须做的一件额外的事情,但我不确定为什么要更改 UITableViewController 和 UICollectionViewController 的单元格标识符,这样它们就不会同时存在 'Cell'。我刚刚使用了 'TableCell' 和 'CollectionCell'。如果您不这样做,他们都会出于某种原因感到困惑。
(我想这就是我所做的一切,但如果没有,我相信您将能够处理任何其他问题)
完成所有操作后,self.collectionView 将引用正确的内容,您将在 - (UIViewController *) previewingContext:(id <UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
方法中获得正确的索引路径。
奖金回合: 现在一些额外的奖金评论。您似乎也对 TableViewController 有同样的问题,尽管它目前似乎没有引起任何问题。不过你可能想修复它。
当我第一次 运行 项目时,我无论如何都看不到向 table 添加任何内容,因为缺少文本字段和 'add' 按钮。结果是因为我使用的是 iPhone 8 模拟器而不是 iPhone X 模拟器,一旦我切换一切正常,我可以看到文本字段和 'add' 按钮。这意味着您的界面没有正确适应不同的设备尺寸(完全没有),您应该真正解决这个问题。
哎呀,比我想象的要长,但希望能解决问题。另外,因为我可以访问 git 存储库,所以我可以克隆它并进行更改。我显然没有提交它们,因为它是你的存储库,但如果你无法理解我为让它工作所做的工作,我可以将它们提交到你的主 b运行ch 或作为一个新的 b运行ch.