出现键盘时,UICollectionView contentOffset会更改
我正试图在我的应用程序中实现PullDown To Search
function。 为了实现这个,我只是修改了一下EGOTableViewPullRefresh ,除了一个问题外,它工作的很好。
问题
当用户打开应用程序时,将出现以下屏幕。 最初UICollectionView's
contentoffset
应该是(0,0)
如果用户拉下集合视图,此时出现下面的屏幕, contentoffset
的UICollectionView
应该是(0,-60)
用户可以在上面的屏幕中input文字进行search。 当用户点击UITextField
inputcontentoffset
的文本contentoffset
(0,-60)
到(0,-110)
和UI loosks(如下图屏幕(0,-110)
,我的问题就发生在这个屏幕上。 我不知道为什么会发生这种变化,请你指导我解决这个问题?
有同样的问题。 重写viewWillAppear:
, viewDidLoad:
和文档中告诉的其他方法没有效果, TPKeyboardAvoidingScrollView
也没有帮助。 经过两天的收集视图苦苦挣扎,我已经到了一个非常糟糕的解决方法。 这个想法是当键盘即将出现时locking滚动,所以你的collections视图将不会移动到任何地方,并且在键盘结束animation之后解锁滚动。 为此,您应该子类UICollectionView
添加一个标志locking滚动,订阅键盘通知并正确设置此标志。
在实施此解决方法之前,我必须警告您,这是一个非常糟糕的主意,您应该在做这件事之前尝试其他一切。 不过,这工作…
所以,这就是你所做的:
-
在viewWill你的viewController的订阅键盘通知:
- (void)viewWillAppear:(BOOL)animated { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; // you custom code here }
稍后您将处理通知
-
不要忘记取消订阅通知:
- (void)viewWillDisappear:(BOOL)animated { [[NSNotificationCenter defaultCenter] removeObserver:self]; // your custom code }
-
子类UICollectionView并添加标志:
@property (nonatomic, getter=isLocked) BOOL locked;
-
覆盖您的集合视图中的setContentOffset:
- (void)setContentOffset:(CGPoint)contentOffset { if (contentOffset.y < self.contentOffset.y && self.isLocked) // user scrolls up contentOffset.y = self.contentOffset.y; // ignore new Y coordinate, so collection view will not scroll up [super setContentOffset:contentOffset]; }
-
在您的viewController创build键盘处理方法来locking和解锁滚动:
- (void)keyboardWillShow:(NSNotification *)aNotification { [(LockableCollectionView *)self.collectionView setLocked:YES]; } - (void)keyboardDidShow:(NSNotification *)aNotification { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [(LockableCollectionView *)self.collectionView setLocked:NO]; }); }
警告! 下面是关于dispatch_after
在keyboardDidShow:
的一些说明keyboardDidShow:
如果在键盘显示后解锁滚动,locking将被忽略,集合视图将向上滚动。 将其包装到dispatch_after
,在0.3秒后运行此代码,并且工作正常。 这可能与运行循环有关, 应该在真实设备上进行testing,而不是在模拟器上进行testing。
也不是一个美丽的解决办法来处理这个
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIKeyboardWillShowNotification, object: nil)
func keyboardWillShow() { let offset = self.collectionView!.contentOffset; self.collectionView!.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right:0 ) self.collectionView!.contentOffset = offset let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))) dispatch_after(delayTime, dispatch_get_main_queue()) { let offset = self.collectionView!.contentOffset; self.collectionView!.contentInset = UIEdgeInsets(top: 60, left: 0, bottom: 0, right:0 ) self.collectionView!.contentOffset = offset } }
最简单的select是使用UIViewController并添加自己的UICollectionView。 为了禁用所有不需要的键盘操作,疯狂的黑客数量是疯狂的。
问题解决! 通过UIViewController更改我的UICollectionViewController并使我的UICollectionView成为ViewController.view的子视图。