我在可编辑的webView中显示了一些文本。只要我向下滚动并触摸某处来编辑呈现的文本,它就会自动滚动到顶部并出现键盘,因此我必须再次将其向下滚动以进行编辑。有没有办法阻止webView做到这一点?可编辑的webView自动滚动到顶部
回答
得到了同样的问题,仍然在寻找的这种怪异的行为,正常的解决方案。 我们仍然不能阻止一个UIWebView从这样做,如果你看一下iPad上的Evernote的应用程序,你会看到同样的问题在那里,不幸的是:( 我们可以在此做的唯一一件事就是保存的UIWebView的contentOffset当键盘所示,如果键盘打开后恢复
这看起来像:
//register your controller for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) UIKeyboardDidShowNotification object:nil];
然后,你将需要处理像键盘通知:
- (void)keyboardWillShow:(NSNotification *)aNotification {
// scroll view will scroll to beginning, but we save current offset
[_yourViewWithWebView saveOffset];
...
}
你的Wi之后会需要处理事件表现出键盘的时候:
- (void)keyboardWasShown:(NSNotification*)aNotification{
...
// scroll view scrolled to beginning, but we restore previous offset
[_yourViewWithWebView restoreOffset];
}
因此在您的视图包含一个UIWebView您需要实现:
static CGPoint editableWebViewOffsetPoint;
- (void) saveOffset{
editableWebViewOffsetPoint = yourWebView.scrollView.contentOffset;
}
- (void) restoreOffset{
//just use animation block to have scroll animated after jumping to top and back to old position
[UIView animateWithDuration:.2
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
yourWebView.scrollView.contentOffset = editableWebViewOffsetPoint;
}
completion:nil];
}
希望一般来说这将帮助你解决你的问题至少部分。
如果有人可以帮助我们防止UIWebView的滚动每个显示键盘时到顶部,我深深的体会到这一点。
UIWebView.scrollView.scrollsToTop = NO;
没有帮助。
显示键盘,并使其显示后的键盘也没有工作之前禁用滚动。
此外,在未来,你会当光标不在UIWebView的可视区域面临编辑文本的问题 - 它不会自动滚动本身,使光标可见。我们已经解决了这个问题,但是我正在编写关于我们如何完成这个任务的详细和可读教程。如果你已经解决了这个问题,我会很感激看看你的解决方案:)
PS:http://www.cocoanetics.com/2011/01/uiwebview-must-die/
谢谢 谢尔盖N.
的“编辑文本功能,当光标不在可见区域“问题。
- (void)keyboardWasShown:(NSNotification *)aNotification {
//if(self.navigationController.viewControllers objectAtIndex:([self.navigationController.viewControllers count]-1)==self.)
NSLog(@"keyboardshown");
if (keyboardshown)
return;
keyboardshown=YES;
NSDictionary* userInfo = [aNotification userInfo];
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
CGRect newFrame = self.textView.frame;
CGRect keyboardFrame = [self.textView convertRect:keyboardEndFrame toView:nil];
newFrame.size.height -= keyboardFrame.size.height;
[UIView beginAnimations:@"ResizeForKeyboard" context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3];
[self.textView setFrame:newFrame];
[UIView commitAnimations];
}
- (void)keyboardWasHidden:(NSNotification *)aNotification {
if (!keyboardshown)
return;
keyboardshown=NO;
NSDictionary* userInfo = [aNotification userInfo];
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
CGRect newFrame = self.textView.frame;
CGRect keyboardFrame = [self.textView convertRect:keyboardEndFrame toView:nil];
newFrame.size.height += keyboardFrame.size.height;
[UIView beginAnimations:@"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:0.3];
self.textView.frame = newFrame;
[UIView commitAnimations];
}
实际上keyboardWasShown不会总是特别是当用户已经BT键盘连接和虚拟一个可以隐藏/通过弹出键所示调用。我们已经实现了自己的类,如:
@implementation KeyboardUtils
+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view {
UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window];
return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil];
}
/**
* This is working but deprecated solution
* Based on UIKeyboardCenterBeginUserInfoKey and UIKeyboardCenterEndUserInfoKey which are deprecated since iOS 3.2
*/
+ (BOOL)checkKeyboardOnDisplayCenterBegin:(CGRect)centerBegin centerEnd:(CGRect)centerEnd{
CGRect mainScreen = [UIApplication currentBounds];
BOOL isKeyboardOnDisplay = CGRectContainsPoint(mainScreen, centerEnd.origin);
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:isKeyboardOnDisplay] forKey:@"isKeyboardOnDisplay"];
[[NSUserDefaults standardUserDefaults] synchronize];
return isKeyboardOnDisplay;
}
/**
* This method allows to verify if software keyboard is currently present on screen for the application
* Allows to handle undocked, split states of keyboard, as well as connected Bluetooth keyboard.
* Needed to adjust UI - scrolling and insets for editable parts of the app, as well as avoid application be beneath open keyboard
*/
+ (BOOL)checkKeyboardOnDisplayBeginFrame:(CGRect)frameBegin endFrame:(CGRect)frameEnd{
CGRect mainScreen = [UIApplication currentBounds];
UIView *firstView = [[(AppDelegate *)[[UIApplication sharedApplication] delegate] window].subviews objectAtIndex:0];
CGRect convertedEndFrame = [KeyboardUtils convertRect:frameEnd toView:firstView];
BOOL isKeyboardOnDisplay = CGRectContainsRect(mainScreen, convertedEndFrame);
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:isKeyboardOnDisplay] forKey:@"isKeyboardOnDisplay"];
[[NSUserDefaults standardUserDefaults] synchronize];
return isKeyboardOnDisplay;
}
+ (BOOL)checkKeyboardOnDisplayFromNotification:(NSNotification *)aNotification{
BOOL isKeyboardOnDisplay = [KeyboardUtils checkKeyboardOnDisplayBeginFrame:[[aNotification.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]
endFrame:[[aNotification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]];
return isKeyboardOnDisplay;
}
然后你可以使用它像:
- (void)keyboardWillChangeFrame:(NSNotification*)aNotification{
[KeyboardUtils checkKeyboardOnDisplayFromNotification:aNotification];
}
哪里keyboardWillChangeFrame是选择-观察员:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
以这样的方式你保存你的键盘状态(如果它显示为停靠状态并且确实存在于显示器上,并且不使用BT键盘)进入NSUserDefaultSettings。在听取键盘通知或方向更改的处理程序中,您应该从默认值中检查此键值。
另外一个方法是[UIApplication currentBounds]; 它存在于应用程序通过像类扩展它:(h文件)
#import <UIKit/UIKit.h>
@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGRect) currentBounds;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end
.m文件:
#import "UIApplication+AppDimensions.h"
@implementation UIApplication (AppDimensions)
+(CGSize) currentSize
{
return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}
+(CGRect) currentBounds{
CGRect bounds = [UIScreen mainScreen].bounds;
bounds.size = [UIApplication currentSize];
return bounds;
}
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
CGSize size = [UIScreen mainScreen].bounds.size;
UIApplication *application = [UIApplication sharedApplication];
if (UIInterfaceOrientationIsLandscape(orientation))
{
size = CGSizeMake(size.height, size.width);
}
if (application.statusBarHidden == NO)
{
size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
}
return size;
}
@end
希望这将帮助任何人谁是关心处理键盘的存在屏幕上。
工作得很好的方法是在键盘显示时临时禁用UIScrollView
上的setContentOffset:
。尽管这有点不妥,但在某些情况下,它可能会导致其他问题。
正如@Sergey N.的响应,注册键盘的通知,但不是保存/恢复contentOffset,使用这些:在类其他
- (void)keyboardWillShow:(NSNotification *)aNotification {
[self disableMethod:@selector(setContentOffset:) onClass:[UIScrollView class]];
}
- (void)keyboardWasShown:(NSNotification *)aNotification {
[self enableMethod:@selector(setContentOffset:) onClass:[UIScrollView class]];
}
某处(或其他类,只要你替换上面的调用self
),将这些:
-(void)swizzleMethod:(SEL)origSel from:(Class)origClass toMethod:(SEL)toSel from:(Class)toClass{
Method origMethod = class_getInstanceMethod(origClass, origSel);
Method newMethod = class_getInstanceMethod(toClass, toSel);
method_exchangeImplementations(origMethod, newMethod);
}
-(void)disableMethod:(SEL)sel onClass:(Class)cl{
[self swizzleMethod:sel from:cl toMethod:@selector(doNothing) from:[self class]];
}
-(void)enableMethod:(SEL)method onClass:(Class)cl{
[self swizzleMethod:@selector(doNothing) from:[self class] toMethod:method from:cl];
}
-(void)doNothing{
}
这样可以防止web视图从摆在首位滚动到顶部,这样就不会显示不错的动画,但是,在一些situatio ns可能会导致一些问题(例如,在拥有webview的视图中有更多的输入控件)。在iOS 5.0+中成功测试了这一点。 在iOS 6.0中,滚动到顶部似乎是固定的,因此没有必要解决方法。
谢谢你!奇迹般有效! ^^它可以在4.3模拟器上运行。像这个解决方案更好,因为它消除了屏幕碰撞。对于想要完全控制其页面的phonegap开发人员非常有用 – Arthur 2013-03-07 12:37:12
- 1. 如何滚动以自动滚动到可编辑分区的底部
- 2. 自动滚动到顶部在UITableView
- 3. Listview自动滚动到顶部
- 4. RecyclerView自动滚动到顶部
- 5. 启动IText内嵌编辑滚动到页面顶部 - Fabric.js
- 6. 的jQuery#滚动到顶部
- 7. listview滚动到顶部后编辑条目
- 8. 当TD被点击时,可滚动的DIV滚动到顶部
- 9. KendoListView,滚动到顶部,这可能吗?
- 10. 禁用滚动到顶部
- 11. 滚动到灯箱顶部
- 12. Android ListView滚动到顶部
- 13. LinearLayout滚动到顶部
- 14. 网格:滚动到顶部?
- 15. 滚动到顶部DIV
- 16. UIScrollView不滚动到顶部
- 17. 滚动到顶部代码
- 18. BlockUI滚动到顶部
- 19. CollectionView滚动到顶部
- 20. jquery滚动到顶部的动画
- 21. 如何强制Android上的webview滚动到页面顶部?
- 22. FullPage.js - 滑块自动滚动到顶部部分每次
- 23. 当点击状态栏时,我可以禁用/编辑自动跳转到顶部滚动吗?
- 24. 滚动到顶部不可思议或作物顶部溢出
- 25. 自动滚动WebView Android
- 26. jQuery滚动到顶部并滚动到下一部分
- 27. UIScrollView在触摸动作时自动滚动到顶部
- 28. 自动滚动到ipad上的safari页面的顶部
- 29. 动画滚动到顶部2
- 30. 动画滚动到顶部链接
非常感谢这么全面的回答。我很感激。该解决方案确实在一定程度上解决了问题。关于“光标不在可见区域时编辑文本”问题,我使用以下两个函数在textView中解决了这个问题。尽管我也必须在webView中尝试它们。 – gamersoul 2012-07-19 05:02:49
谢尔盖,你是对的。肯定会死的。 – velkopopovizky 2012-07-19 10:12:45
谢尔盖,你写过那个教程了吗? :)我一直在努力与这些'UIWebView's很长一段时间。 – 2012-09-25 23:03:06