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

发布于 2024-10-02 03:22:55 字数 1464 浏览 0 评论 0原文

我在我的应用程序中使用子类 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?或者它太丑陋了,有更好的方法吗?

I'm using subclassed UIAlertView window as a login prompt in my application (I know it's against Apple guidelines but it will not be submitted to the appstore so it's not a problem).

The code to add text fields and position the window on screen looks like this:

- (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;
}

The problem is with setTransform call:

on iOS 3.x:
- without setTransform: The window is displayed centered horizontally and vertically on the screen, with onscreen keyboard displayed partially on top of it - so the whole window is not visible
- with setTransform: The window is displayed 90 pixels higher, so it is whole visible with onscreen keyboard displayed.

on iOS 4.x however:
- without setTransform: The window is displayed perfectly fine (visible above the onscreen keyboard)
- with setTransform: The window is displayed partially above the top border of the screen (90 pixels too high).

What would be the best solution for this issue? Detecting iOS version and calling setTransform conditionally? Or it's too ugly hack and there is some better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世俗缘 2024-10-09 03:22:56

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

Because iOS 4 has been released for the newer devices (and iOS 4.2 for iPad is right around the corner), I would recommend setting the Base SDK to the latest version of iOS 4 and compiling your application with this version. However, if you want your application to be available to original iPhone and iPod Touch users, conditionally using the setTransform method is the best way.

静水深流 2024-10-09 03:22:56

无论您在 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);

}

Whatever (text) you add in the UIAlertView, is shown as label. So if you wanna add textfield, just add the textfield on top of all the labels, and shift down the labels. this is what i have done,

- (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);

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文