Cocoa touch UIAlert部分隐藏在iPad水平方向上。如何将其向上移动?

Cocoa touch UIAlert部分隐藏在iPad水平方向上。如何将其向上移动?,cocoa-touch,uitextfield,uialertview,ipad,loginview,Cocoa Touch,Uitextfield,Uialertview,Ipad,Loginview,在我的iPad应用程序中,我实现了一个登录窗口,作为一个UIAlertView子类,它添加了两个UITextField,使用了一个在网上找到的习惯用法 问题在于,在水平方向上,警报部分被键盘隐藏。也就是说,按钮是隐藏的。当然,可以隐藏键盘以显示按钮,但这很难看 习语应该解决的问题是向视图中添加翻译转换: CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 100.0); [self setTransform:t

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

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

习语应该解决的问题是向视图中添加翻译转换:

CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 100.0); 
[self setTransform:translate];
但是,这并没有真正起作用:

  • 在初始垂直方向上,该操作有效(但在任何设备旋转后停止工作)
  • 在初始水平方向上,可以看到它工作,但警报会立即动画显示回屏幕中心,在那里它再次部分隐藏
  • 在旋转iPad后的任何方向上,它都不起作用:什么也没发生,就好像变换根本就不存在一样
(此外,这种转换想法可能会停止ios4.x的{工作|是必要的},但这是另一个问题)

任何想法都欢迎

为了完整起见,以下是完整的代码:

- (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];
}
关键是何时调用该代码。有两种情况:最简单的情况是当用户旋转设备时。不幸的是,警报类没有被通知该事件,只有客户端UIViewController,因此我们需要调用它。通过破坏封装,这很难看,但就这样吧:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{
    if(loginWindow && UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
    {
        [loginWindow slideUp];
    }   
}
第二种情况是,打开警报时方向已经是水平的。警报代理在其
didPresentAlertView:
delegate方法中被告知

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

我在将UITextField作为子视图的alertView中遇到了完全相同的问题。我没有采用转换路径,而是采用了一种稍微不同的方法。我是这样做的

首先创建包含文本字段的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];
    }

}

此方法发生在“旋转完成”通知发布之后。因此,在开始向上滑动alertview的动画之前,您将看到它部分位于键盘下方。希望这有助于您登录alertview。

另外一项:实现以下uialertview委托方法-(void)didPresentAlertView:(uialertview*)alertview;在这种方法中,也要进行与DIDROTEFROMINTERFACEORIENT相同的检查。这将允许修复警报问题,如果您在uiviewcontroller的当前界面操作已被设置为横向时显示警报。是的,我马上就看到了。不幸的是,它不起作用,因为在这种情况下,我已经看到系统将警报动画化到屏幕中央,而且不知何故,您的代码从未运行过,就好像它被系统动画抢先一样。修复方法是延迟您的代码:我在一个NSTimer中运行它,计划在0.25秒后运行。另外,我讨厌这一点:您需要通过向客户端控制器添加实现代码来打破封装。我讨厌这样,但我看不到解决的办法。