我在 a 中有一个UICollectionViewCell
可以接收第一响应者状态的文本字段。该单元格当前在屏幕上不可见,我想根据从UISegmentedControl
. 此控件有两个段……点击第二个段应滚动到UICollectionView
. 发生这种情况后,应该以编程方式选择单元格,然后该单元格内的文本字段应该获得第一响应者状态并调出键盘。
现在发生的事情(在我的操作方法中,来自分段控件的值更改)是调用-[UICollectionView selectItemAtIndexPath:animated:scrollPosition:]
根本没有滚动到它(我正在使用UICollectionViewScrollPositionTop
; 也可能是“ …None
”)。如果我手动按下列表,则确实选择了单元格(在该状态下它的背景颜色较深),但文本字段肯定没有第一响应者状态。
为了解决滚动问题,我已经能够确定单元格在列表中的位置,并滚动到单元格的内容偏移量(我也在scrollRectToVisible
这里使用过)。然后我手动选择它(以及告诉代理也触发其适当的方法,单元格的文本字段获得第一响应者状态)。
- (void)directionSegmentedControlChanged:(UISegmentedControl *)sender {
NSIndexPath *path = [NSIndexPath indexPathForItem:0 inSection:sender.selectedSegmentIndex];
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:path];
[self.collectionView setContentOffset:attributes.frame.origin animated:YES];
[self.collectionView selectItemAtIndexPath:path animated:NO scrollPosition:UICollectionViewScrollPositionNone];
[self.collectionView.delegate collectionView:self.collectionView didSelectItemAtIndexPath:path];
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
BDKCollectionViewCell *cell = (BDKCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
[cell.textField becomeFirstResponder];
}
这里的问题是它所看到的单元格-[collectionView:didSelectItemAtIndexPath:]
是 nil,因为当方法被触发时它不在集合视图的可见单元格集中。
解决这个问题的最佳方法是什么?我尝试将滚动代码扔到一个[UIView animateWithDuration:animations:completion:]
块内,并在完成后分配第一响应者,但是以这种方式手动为集合视图设置动画会忽略加载任何应该滚动过去的单元格。有任何想法吗?
更新:非常感谢@Esker,他建议我在使用 Grand Central Dispatch 延迟后执行“焦点选择”操作。我的解决方案最终看起来像这样。
- (void)directionSegmentedControlChanged:(UISegmentedControl *)sender {
NSIndexPath *path = [NSIndexPath indexPathForItem:0 inSection:sender.selectedSegmentIndex];
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:path];
[self.collectionView setContentOffset:attributes.frame.origin animated:YES];
dispatch_time_t startAfter = dispatch_time(DISPATCH_TIME_NOW, 0.28 * NSEC_PER_SEC);
dispatch_after(startAfter, dispatch_get_main_queue(), ^{
[self.collectionView selectItemAtIndexPath:path animated:NO scrollPosition:UICollectionViewScrollPositionNone];
[self collectionView:self.collectionView didSelectItemAtIndexPath:path];
});
}