我正在尝试在我的应用中实现PullDown To Search
功能。为了实现这一点,我刚刚修改了位EGOTableViewPullRefresh
,除了一个问题之外它工作正常。
问题
当用户打开应用程序后,将出现以下屏幕。最初UICollectionView's
contentoffset
应为(0,0)
如果用户下拉集合视图,此时将显示以下屏幕contentoffset
UICollectionView
为(0,-60)
用户可以在上面的屏幕中输入文字进行搜索。一旦用户点击UITextField
以输入contentoffset
更改UICollectionView
(0,-60)
(0,-110)
的文字{{1}}和屏幕下方的用户体验,我的问题就出现在此屏幕上。我不确定为什么会发生这种变化你能引导我解决这个问题吗?
答案 0 :(得分:1)
有同样的问题。覆盖viewWillAppear:
,viewDidLoad:
和文档中说明的其他方法无效,TPKeyboardAvoidingScrollView
也无济于事。在收集视图超过2天后,我遇到了一个非常糟糕的解决方法。想法是在键盘即将出现时锁定向上滚动,因此您的集合视图不会移动到任何地方,并在键盘结束动画后解锁滚动。为此,您应该将UICollectionView
子类化,以添加一个锁定滚动的标记,订阅键盘通知并正确设置此标记。
在实施此解决方法之前,我必须警告您,这是一个非常糟糕的主意,在执行此操作之前,您应该尝试其他所有操作。不过,这仍有效......
所以这就是你做的:
在viewController的viewWillAppear中订阅键盘 通知:
- (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中创建键盘处理方法以锁定和解锁滚动:
- (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:
的一点说明
如果在键盘确实显示后立即解锁滚动,则会忽略锁定并且向上滚动收集视图。将其包装到dispatch_after
以在0.3秒后运行此代码并且运行良好。这可能与运行循环有关,应该在真实设备上测试,而不是在模拟器中测试。
答案 1 :(得分:0)
也不是处理这个问题的漂亮解决方案
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
}
}
答案 2 :(得分:0)
最简单的替代方法是使用UIViewController并添加自己的UICollectionView。禁用键盘所有不良行为所需的疯狂黑客数量只是疯了。
答案 3 :(得分:0)
答案 4 :(得分:0)
我在UICollectionView中有一个UITableView并且得到了奇怪的滚动。受@AnkH的启发我覆盖了我的UICollectionView并将其添加到构造函数中:
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow),
name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide),
name: NSNotification.Name.UIKeyboardDidHide, object: nil)
覆盖contentOffset并在键盘可见时阻止contentOffset的所有修改。完成。 问题是UITableView已经在其自身上触发了正确的contentOffset设置,但是父UICollectionView添加了自己的contentOffset,导致了灾难性的行为。首先它滚动太远,然后太远了。现在它完美无缺!