在 iOS 上使用屏幕键盘定位子类 UIAlertView 窗口

Posted

技术标签:

【中文标题】在 iOS 上使用屏幕键盘定位子类 UIAlertView 窗口【英文标题】:positioning subclassed UIAlertView window with onscreen keyboard on iOS 【发布时间】:2010-11-15 13:29:23 【问题描述】:

我在我的应用程序中使用子类 UIAlertView 窗口作为登录提示(我知道这违反了 Apple 准则,但它不会提交到应用商店,所以这不是问题)。

添加文本字段和在屏幕上定位窗口的代码如下所示:

- (id)initWithTitle:(NSString *)title delegate:(id)delegate

    if (self = [super initWithTitle:title message:@"\n\n\n" delegate:delegate cancelButtonTitle:@"Cancel" otherButtonTitles:@"Login", nil]) 
        UITextField *loginTF = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 55.0, 260.0, 25.0)];
        // text field settings removed for code clarity 
        [self addSubview:loginTF];
        self.loginTextField = loginTF;
        [loginTF release];

        UITextField *passwordTF = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 85.0, 260.0, 25.0)];
        // text field settings removed for code clarity
        [self addSubview:passwordTF];
        self.passwordTextField = passwordTF;
        [passwordTF release];

        CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 90.0); 
        [self setTransform:translate];
    

    return self;

问题在于setTransform 调用:

ios 3.x 上: - 没有setTransform:窗口在屏幕上水平和垂直居中显示,屏幕键盘部分显示在其顶部 - 所以整个窗口不可见 - setTransform:窗口显示高 90 像素,因此在显示屏幕键盘时整个可见。

然而,在 iOS 4.x 上: - 没有setTransform:窗口显示得非常好(在屏幕键盘上方可见) - 带有setTransform:窗口部分显示在屏幕上边框上方(90 像素太高)。

这个问题的最佳解决方案是什么?检测iOS版本并有条件地调用setTransform?或者它太丑陋了,有更好的方法吗?

【问题讨论】:

【参考方案1】:

因为 iOS 4 已针对较新的设备发布(iPad 的 iOS 4.2 即将发布),我建议将 Base SDK 设置为最新版本的 iOS 4 并使用此版本编译您的应用程序。但是,如果您希望原始 iPhone 和 iPod Touch 用户可以使用您的应用程序,有条件地使用 setTransform 方法是最好的方法。

【讨论】:

我真的希望这个应用程序可以在尽可能广泛的 iOS 设备上使用。这就是我为 iOS3.x 编译它的原因——那里仍然有很多 iOS3 设备。我想我会去有条件的setTransform 打电话。谢谢。【参考方案2】:

您在 UIAlertView 中添加的任何(文本)都显示为标签。因此,如果您想添加文本字段,只需将文本字段添加到所有标签的顶部,然后向下移动标签。这就是我所做的,

- (void) drawRect:(CGRect)rect 
    [super drawRect:rect];

    CGRect labelFrame = CGRectMake(0, 0, 0, 0); // init if no label is there
    NSArray *views = [self subviews];
    for (UIView *view in views)
        if ([view isKindOfClass:[UILabel class]]) 
            labelFrame = view.frame;
         else     
            view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y + kTextFieldHeight , view.frame.size.width, view.frame.size.height);
        

    

    CGRect myFrame = self.frame;
    self.textField.frame = CGRectMake(95, labelFrame.origin.y+labelFrame.size.height + 5.0, kTextFieldWidth, kTextFieldHeight);
    self.frame = CGRectMake(myFrame.origin.x, myFrame.origin.y, myFrame.size.width, myFrame.size.height + kTextFieldHeight);


【讨论】:

以上是关于在 iOS 上使用屏幕键盘定位子类 UIAlertView 窗口的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 CSS 或 JS 防止 iOS 键盘将视图推离屏幕

在 Darwin 通知中心回调上调用 UIAlert

虚拟键盘激活时的屏幕样式

KeyboardWillShowNotification 和 UIAlert

在 Xcode 6 中,如何使用硬件键盘但在 iOS 模拟器中显示软件键盘

使用 UITextView 的子类和自定义屏幕键盘,调用 textField.textShouldChange