为什么单击时动画 UIButton 的位置会重置? [英] Why is animated UIButton's position reset when clicked?

查看:23
本文介绍了为什么单击时动画 UIButton 的位置会重置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短说明:当显示键盘时,我将一个按钮向上平移,但在单击该按钮时,它会弹回原来的位置.

详细说明:我有两个按钮,一个在另一个之上.一个在满足特定条件之前隐藏,然后变为可见,另一个隐藏.

@property (weak, nonatomic) IBOutlet UIButton *skipButton;@property (weak, nonatomic) IBOutlet UIButton *saveButton;@property (assign, nonatomic) BOOL saveButtonEnabled;@property (assign, readonly, nonatomic) CGRect fieldContainerDefaultFrame;@property (assign, readonly, nonatomic) CGRect skipButtonDefaultFrame;

当视图加载时我缓存默认位置

- (void)viewDidLoad{[超级viewDidLoad];..._fieldContainerDefaultFrame = self.fieldContainerView.frame;_skipButtonDefaultFrame = self.skipButton.frame;[self.saveButton setHidden:YES];self.saveButtonEnabled = NO;}

按钮正确连接到插座,这些是它们的内部修饰"动作

#pragma mark - 动作- (IBAction)didPressSaveButton:(id)sender{//这里的代码用于持久化数据//这里的代码将 segue 推送到下一个场景}- (IBAction)didPressSkipButton:(id)sender{//这里的代码将 segue 推送到下一个场景}

以下是响应键盘通知的方法.我确实注册了我只是不包括该代码的通知.(那里没有问题,所有这些东西都可以正确运行.)

注意:两个按钮都包含在同一个容器"框架中(连同其他字段),它向上平移.按钮翻译了额外的金额.翻译工作一般,唯一的问题是点击时按钮的重置行为.

#pragma mark - 通知处理程序- (void)handleKeyboardWillShowNotification:(NSNotification *)note{if([self.bioTextView isFirstResponder]){CGRect newFieldContainerFrame = self.fieldContainerDefaultFrame;CGRect newSkipButtonFrame = self.skipButtonDefaultFrame;newFieldContainerFrame.origin.y += AGSTSignupDetailsFieldContainerEditingOffset;newSkipButtonFrame.origin.y += AGSTSignupDetailsS​​kipButtonEditingOffset;NSTimeInterval 持续时间 = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];UIViewAnimationCurve animationCurve = [note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];[UIView animateWithDuration:duration 动画:^{[UIView setAnimationCurve:animationCurve];self.fieldContainerView.frame = newFieldContainerFrame;self.skipButton.frame = newSkipButtonFrame;self.saveButton.frame = newSkipButtonFrame;}];}}- (void)handleKeyboardWillHideNotification:(NSNotification *)note{NSTimeInterval 持续时间 = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];UIViewAnimationCurve animationCurve = [note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];[UIView animateWithDuration:duration 动画:^{[UIView setAnimationCurve:animationCurve];self.fieldContainerView.frame = self.fieldContainerDefaultFrame;self.skipButton.frame = self.skipButtonDefaultFrame;self.saveButton.frame = self.skipButtonDefaultFrame;}];}

如果您就如何修复错误或如何制定更好的解决方案提供任何见解或建议,我将不胜感激.谢谢.

解决方案

好的,我解决了这个问题.虽然我很欣赏 rob mayoff 的回应作为更好实践的指示(即,在使用自动布局时不要设置框架),但在我的案例中这并不是问题的实际原因,因此我不认为我的问答是我能找到的任何东西的副本.我将发布此答案,以防其他人遇到类似问题.

事实证明,正如我今天早上早些时候怀疑的那样,按钮的 push segue 做了两个相互不兼容的事情:(1)它导致键盘消失,导致字段向下平移;(2) 当新的 VC 到位时,它导致整个场景动画消失,这显然取消了所有待处理的动画(即翻译)并导致这些翻译突然跳转到它们的目标状态.

最快的解决方案是在 viewDidLoad 上将 BOOL didPressSaveButton 设置为 NO,并且仅在按下按钮时将其设置为 YES,然后在每个相关翻译动画之前检查该 BOOL:如果 BOOL 为 NO,则继续执行动画,否则什么都不做.这将防止在 push segue 之前突然出现最终动画.<​​/p>

更好的解决方案,我将很快实施,将使用自动布局约束代替我对框架的使用.

Short description: When the keyboard is shown I translate a button up, but upon clicking the button it pops back down to its original position.

Long description: I have two buttons, one on top of the other. One is hidden until certain criteria are met, then it becomes visible and the other is hidden.

@property (weak, nonatomic) IBOutlet UIButton *skipButton;
@property (weak, nonatomic) IBOutlet UIButton *saveButton;
@property (assign, nonatomic) BOOL saveButtonEnabled;

@property (assign, readonly, nonatomic) CGRect fieldContainerDefaultFrame;
@property (assign, readonly, nonatomic) CGRect skipButtonDefaultFrame;

When view loads I cache the default positions

- (void)viewDidLoad
{
    [super viewDidLoad];

    ...

    _fieldContainerDefaultFrame = self.fieldContainerView.frame;
    _skipButtonDefaultFrame = self.skipButton.frame;

    [self.saveButton setHidden:YES];
    self.saveButtonEnabled = NO;
}

The buttons are wired to outlets correctly and these are their "touch up inside" actions

#pragma mark - Actions

- (IBAction)didPressSaveButton:(id)sender
{
    // Code here to persist data

    // Code here to push segue to next scene
}

- (IBAction)didPressSkipButton:(id)sender
{
    // Code here to push segue to next scene
}

Here are the methods that respond to the keyboard notifications. I do register for the notifications I'm just not including that code. (There is no issue there, all this stuff gets run correctly.)

NOTE: Both buttons are contained in the same "container" frame (along with other fields), which translates up. The buttons translate up an additional amount. The translation works in general, the only issue is the reseting behavior of the button upon click.

#pragma mark - Notification handlers

- (void)handleKeyboardWillShowNotification:(NSNotification *)note
{
    if([self.bioTextView isFirstResponder])
    {
        CGRect newFieldContainerFrame = self.fieldContainerDefaultFrame;
        CGRect newSkipButtonFrame = self.skipButtonDefaultFrame;
        newFieldContainerFrame.origin.y += AGSTSignupDetailsFieldContainerEditingOffset;
        newSkipButtonFrame.origin.y += AGSTSignupDetailsSkipButtonEditingOffset;

        NSTimeInterval duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
        UIViewAnimationCurve animationCurve = [note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];

        [UIView animateWithDuration:duration animations:^{

            [UIView setAnimationCurve:animationCurve];
            self.fieldContainerView.frame = newFieldContainerFrame;
            self.skipButton.frame = newSkipButtonFrame;
            self.saveButton.frame = newSkipButtonFrame;
        }];
    }
}

- (void)handleKeyboardWillHideNotification:(NSNotification *)note
{
    NSTimeInterval duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve animationCurve = [note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];

    [UIView animateWithDuration:duration animations:^{

        [UIView setAnimationCurve:animationCurve];
        self.fieldContainerView.frame = self.fieldContainerDefaultFrame;
        self.skipButton.frame = self.skipButtonDefaultFrame;
        self.saveButton.frame = self.skipButtonDefaultFrame;
    }];
}

I'd appreciate any insights or suggestions as to how to fix the bug or how to craft a better solution. Thanks.

解决方案

Okay, I fixed the problem. While I appreciate rob mayoff's response as an indication of better practices (i.e., don't set frames when using autolayout), that was not the actual cause of the problem in my case, thus I don't consider my Q&A to be a duplicate of anything I could find. I'm going to post this answer in case someone else runs across a similar problem.

It turns out, as I suspected earlier this morning, that the button's push segue did two mutually incompatible things: (1) it caused the keyboard to disappear, which caused the fields to be translated downward; and (2) it caused the whole scene to animate away as the new VC comes into place, which apparently cancelled all pending animations (i.e., the translation) and caused those translations to abruptly jump to their destination states.

The quickest solution was to set a BOOL didPressSaveButton to NO on viewDidLoad and only set it to YES once the button is pushed, and then check that BOOL before every relevant translation animation: if the BOOL is NO, go ahead and do the animation, otherwise do nothing. This will prevent the abrupt final animation before the push segue.

The better solution, and one I will implement soon, will be to replace my use of frames with autolayout constraints.

这篇关于为什么单击时动画 UIButton 的位置会重置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆