UIAlert部分隐藏在iPad水平方向上。如何提升?

时间:2010-09-03 10:28:56

标签: cocoa-touch uitextfield uialertview ipad loginview

在我的iPad应用程序中,我有一个登录窗口的实现作为UIAlertView子类,使用在网上找到的成语添加两个UITextField

问题是在水平方向上,键盘会部分隐藏警报。即,按钮被隐藏。当然,可以隐藏键盘以显示按钮,但这很难看。

成语应该修复的方式是向视图添加翻译变换:

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

然而,这确实不起作用:

  • 在初始垂直方向,有效(但在任何设备旋转后停止工作)
  • 在初始水平方向,人们可以看到它有效,但警报立即动画回到屏幕中心,再次部分隐藏。
  • 在旋转iPad之后的任何方向,它根本不起作用:没有任何反应,就好像转换不存在一样。

(另外,这个转换的想法可能会停止iOS 4.x的{working | need}}。但这是另一个问题。)

欢迎任何想法。

为了完整起见,这里是完整的代码:

- (id)initWithLogin:(NSString *)defaultLogin delegate:(id)delegate
{
    if (self = [super initWithTitle:@"Username and password"
                            message:@"\n\n\n"
                           delegate:delegate
                  cancelButtonTitle:@"Cancel"
                  otherButtonTitles:@"Enter", nil])
    {
        UITextField *theTextField = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 45.0, 260.0, 25.0)]; 
        [theTextField setBackgroundColor:[UIColor whiteColor]];
        theTextField.text = defaultLogin;
        theTextField.placeholder = @"username";
        [self addSubview:theTextField];
        self.loginField = theTextField;
        [theTextField release];

        theTextField = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 80.0, 260.0, 25.0)]; 
        [theTextField setBackgroundColor:[UIColor whiteColor]]; 
        theTextField.placeholder = @"password";
        theTextField.secureTextEntry = YES;
        [self addSubview:theTextField];
        self.passwordField = theTextField;
        [theTextField release];

    // the two next lines may not be useful for iOS > 4.0
        CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 100.0); 
        [self setTransform:translate];
    }
    return self;
}

感谢Bittu提供的解决方案。这是我对他的想法的实现。我把代码放在我的子类的新方法中移动警报:

- (void)slideUp
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    [UIView beginAnimations:nil context:context];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.25f];           

    CGPoint center = self.center;
    center.y -= 100;
    self.center = center;

    [UIView commitAnimations];
}

关键是何时调用该代码。有两种情况:最简单的情况是用户旋转设备。不幸的是,Alert类没有被告知该事件,只有客户端UIViewController,所以我们需要调用它。通过打破封装这很难看,但就是这样:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{
    if(loginWindow && UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
    {
        [loginWindow slideUp];
    }   
}

第二种情况是打开警报时方向已经是水平的。警报代表在其didPresentAlertView:委托方法中被告知。

- (void)didPresentAlertView:(UIAlertView *)alertView
{
    if ( UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) ) {
        [self slideUp];
    }
}

不幸的是,该实现不起作用,因为此时调用slideUp将与已经将警报设置为屏幕中心的系统冲突。解决方案是稍微延迟调用,例如使用NSTimer

- (void)didPresentAlertView:(UIAlertView *)alertView
{
    if ( UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]) ) {
        [NSTimer scheduledTimerWithTimeInterval:0.25f
                                      target:self
                                    selector:@selector(slideUp)
                                    userInfo:nil
                                     repeats:NO];
    }
}

顺便说一下,slideUp没有NSTimer选择器的文档签名,但它似乎仍然有效!如果这困扰你,只需在方法之间添加一个正确的签名:

- (void)slideUpByTimer:(NSTimer*)theTimer
{
    [self slideUp]; 
}

1 个答案:

答案 0 :(得分:1)

我在使用UITextField作为子视图的alertView时遇到了完全相同的问题。我采取了一种不同的方法,而不是采取转换路径。我就是这样做的。

首先使用文本字段创建警报视图:

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 40.0, 260.0, 25.0)];
[textField setBackgroundColor:[UIColor whiteColor]];
textField.placeholder = @"Search";

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Enter Search Text" message:@"        " delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Enter",nil];

[alertView addSubview:textField];
[alertView show];

然后在将要显示警报视图的UIViewController中,实现此方法:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{

    if(self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)
    {
         CGContextRef context = UIGraphicsGetCurrentContext();
         [UIView beginAnimations:nil context:context];
         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
         [UIView setAnimationDuration:0.25f];           

         CGPoint center = self.alertView.center;
         center.y -= 100;
         self.alertView.center = center;

         [UIView commitAnimations];
    }

}

此方法在发布“轮换完成”通知后发生。因此,你会看到部分在键盘下面的警报视图,然后动画将其向上滑动开始发生。希望这可以帮助您使用登录提醒视图。