无法将视图原点设置为负数

时间:2014-09-24 11:46:00

标签: objective-c uikit ios8

我有一个简单的KeyboardAdjuster类,它是我的表单视图的属性。如果其中一个表单字段被键盘隐藏,则输入该字段将有一个动画来向上移动整个帧的origin.y,以便该字段出现在键盘上方。一种非常常见的方法。它还有一些复杂性,比如计算在字段之间导航时要滚动多少,但现在这并不重要。 。 。自从iOS5以来我一直在使用这个实用程序类。

示例表格

enter image description here


问题:

在iOS8上,它已停止工作。

  • 当动画帧开始时,通过相反方向捕捉它应该滚动的量。然后滚动回原点。
  • 我尝试将动画部分评论出来,并简单地设置框架。没有效果。

例如,如果框架应该是:{0, -127, 320, 480}那么它只会停留在{0, 0, 320, 480}

为什么这不适用于iOS8?有什么变化我错过了吗?

关于观点:

  • 我的观点是手工编码的,它们是简单形式基础视图的子类。 (包含键盘调整器和滚动视图)。其他元素添加了CGRectZero的初始帧,然后在layoutSubviews
  • 中手动布局


视图/控制器的创建方式:

有一个RootViewController充当容器控制器(UIView包含)。它:

  • 有一个主导航控制器
  • 有一个容器可以显示/解除导航控制器顶视图的汉堡菜单(这些可以更改)。
  • 有一个容器可以显示带有自定义反弹动画的叠加层。

因此视图创建如下:

- (instancetype)initWithView:(INFAcceptGiftView *)view offerDao:(id <INFOfferDao>)offerDao
    locationTracker:(INFLocationTracker *)locationTracker
{
    self = [super init];
    if (self)
    {
        self.view = view;
        _offerDao = offerDao;
        _locationTracker = locationTracker;
    }
    return self;
}


触发键盘动画的原因是什么?:

UIView是表格基础视图的子类,它是一个UITextFieldDelegate:

interface INFFormBaseView : UIView <UITextFieldDelegate, INFInputAccessoryDelegate>
{
    UIResponder *_currentResponder;
    INFInputValidator *_validator;
}


输入字段时

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [_validator dismissMessages];
    [_keyboardAdjuster scrollToAccommodateField:textField];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [_keyboardAdjuster scrollToAccommodateField:nil];
}

2 个答案:

答案 0 :(得分:1)

我有一个不同的解决方案适用于iOS 7和iOS 8和自动布局。

在我的例子中,我有两个UITextFields,我可以移动和隐藏它们,具体取决于它们的位置和键盘的位置。在这种特殊情况下,我在它们之间切换UITextField并隐藏不活动的文件。

viewDidLoad注册以下通知:

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardShowed:)
                                                 name:UIKeyboardWillShowNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardHidden:)
                                             name:UIKeyboardWillHideNotification object:nil];

之后,您抓住视图的默认框架,在这种情况下是两个UITextFields

    - (void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];

        /*** FOR AUTOLAYOUT MODIFICATIONS & ADDITIONS @ RUNTIME ***/

        self.mailTextFieldDefaultFrame = self.mailTextField.frame;
        self.passwordTextFieldDefaultFrame = self.passwordTextField.frame;
}

当您收到UIKeyboardWillShowNotification时,您将开始移动您的观点:

- (void) keyboardShowed:(NSNotification*)notification {

    //GET KEYBOARD FRAME
    CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    //CONVERT KEYBOARD FRAME TO MATCH OUR COORDINATE SYSTEM (FOR UPSIDEDOWN ROTATION)
    CGRect convertedFrame = [self.view convertRect:keyboardFrame fromView:self.view.window];

        if ([self.mailTextField isFirstResponder]) {
            [UIView transitionWithView:self.mailTextField
                              duration:.3f
                               options:UIViewAnimationOptionCurveLinear
                            animations:^{
                                self.mailTextField.alpha = 1.0f;
                                self.mailTextField.frame = CGRectMake(self.mailTextField.frame.origin.x,
                                                                      convertedFrame.origin.y -
                                                                      self.mailTextField.frame.size.height - 25,
                                                                      self.mailTextField.frame.size.width,
                                                                      self.mailTextField.frame.size.height);
                                self.passwordTextField.alpha = 0.0f;
                            }
                            completion:nil];
        } else if ([self.passwordTextField isFirstResponder]) {
[UIView transitionWithView:self.passwordTextField
                              duration:.3f
                               options:UIViewAnimationOptionCurveLinear
                            animations:^{
                                self.passwordTextField.alpha = 1.0f;
                                self.mailTextField.frame = self.passwordTextField.frame;
                                self.passwordTextField.frame = CGRectMake(self.passwordTextField.frame.origin.x,
                                                                          convertedFrame.origin.y -
                                                                          self.passwordTextField.frame.size.height - 25,
                                                                          self.passwordTextField.frame.size.width,
                                                                          self.passwordTextField.frame.size.height);
                                self.mailTextField.alpha = 0.0f;
                            }
                            completion:(void (^)(BOOL finished)) ^{
                        }];
    }

当你隐藏键盘时:

- (void) keyboardHidden:(NSNotification*)notification {

        //RESTORE ORIGINAL STATE OF TEXTFIELDS
        [UIView transitionWithView:self.view
                          duration:.3f
                           options:UIViewAnimationOptionCurveLinear
                        animations:^{
                            self.mailTextField.frame = self.mailTextFieldDefaultFrame;
                            self.passwordTextField.frame = self.passwordTextFieldDefaultFrame;
                            self.mailTextField.alpha = 1.0f;
                            self.passwordTextField.alpha = 1.0f;
                        }
                        completion:nil];
    }

答案 1 :(得分:0)

这是解决方案,发布以防万一。

我上面提到我使用UIView包含,所以我有一个根视图控制器:

  • 包含UINavigationController(根视图是可替换的)。
  • 包含一个菜单控制器(不使用时dealloc&#39; d)
  • 呈现带有自定义动画的叠加层

我的根视图的布局子视图如下:

- (void)layoutSubviews
{
    [super layoutSubviews];
    [_mainContentViewContainer setFrame:self.bounds];
}

这表现的方式我想要它在iOS8之前,但之后没有。从技术上讲,似乎iOS8正在做正确的事情 - 我应该只在启动或方向更改时布置_mainConentViewContainer