在我的iPad应用程序中,我有一个登录窗口的实现作为UIAlertView
子类,使用在网上找到的成语添加两个UITextField
。
问题是在水平方向上,键盘会部分隐藏警报。即,按钮被隐藏。当然,可以隐藏键盘以显示按钮,但这很难看。
成语应该修复的方式是向视图添加翻译变换:
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, 100.0);
[self setTransform:translate];
然而,这确实不起作用:
(另外,这个转换的想法可能会停止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];
}
答案 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];
}
}
此方法在发布“轮换完成”通知后发生。因此,你会看到部分在键盘下面的警报视图,然后动画将其向上滑动开始发生。希望这可以帮助您使用登录提醒视图。