【问题标题】:UIView Animation Removes layer.cornerRadius After CompletionUIView 动画完成后移除 layer.cornerRadius
【发布时间】:2021-03-28 17:55:41
【问题描述】:

我有一个UILabel,我正在为它的约束设置动画,以便它下降到视图中。我正在使用layer.cornerRadius 为视图提供圆角,但无论出于何种原因,动画完成后圆角半径都会被移除。

[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.4 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        
        if (shouldShow) {
            
            self.labelOverMapTopConstraint.constant = 16;
            
        } else {
            
            self.labelOverMapTopConstraint.constant = -40;
            
        }
        
        [self.view layoutIfNeeded];
        
} completion:nil];

cornerRadius 设置在viewDidLoad

有没有办法防止这种情况发生?

【问题讨论】:

  • “cornerRadius is set in viewDidLoad” 我们可以看看这段代码吗?请显示重现该行为所需的一切,minimal reproducible example

标签: ios objective-c xcode uiview


【解决方案1】:

我怀疑你在这里继承了 UILabel,因为看起来你在那里有填充,对吗?

您在那里进行的任何自定义绘图/计算都可能出现问题,因此发布该代码以供检查可能会有所帮助。

几个问题:

  • 您是否将 maskToBounds 设置为 YES?
  • 如果您不使用自定义 UILabel 子类,是否将标签包装在视图中?
  • 动画是如何触发的?是通过按钮吗?来自 NSURLRequest 的回调?如果它是由异步回调触发的,您是否会跳回主队列来执行动画?
  • 如果动画在生命周期内自动触发,是在哪个生命周期方法中触发的?

我无法在使用普通 UILabel 的测试项目中重现该问题。然后我尝试了一个包含额外填充的 UILabel 子类,但仍然无法在那里重现它。

我在下面包含了示例代码 sn-ps:

#import "ViewController.h"
#import "R4NInsetLabel.h"

@interface ViewController ()
@property BOOL showingToast;
@property (strong, nullable) IBOutlet R4NInsetLabel *toastLabel;
@property (strong, nullable) IBOutlet NSLayoutConstraint *toastLabelTopConstraint;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]};
    self.showingToast = NO;
    // start with the label pushed off the top of the screen
    self.toastLabelTopConstraint.constant = -40.0f;
    self.toastLabel.layer.cornerRadius = 6.0f;
    self.toastLabel.layer.masksToBounds = YES;
}

- (IBAction)toggleToast:(id)sender {
    [UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.4 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            if (self.showingToast == NO) {
                self.toastLabelTopConstraint.constant = 16;
                self.showingToast = YES;
            } else {
                self.toastLabelTopConstraint.constant = -40;
                self.showingToast = NO;
            }
            [self.view layoutIfNeeded];
    } completion:nil];
}

@end
#import "R4NInsetLabel.h"

IB_DESIGNABLE
@interface R4NInsetLabel()
@property IBInspectable CGFloat contentPadding;
@property (nonatomic) UIEdgeInsets contentInsets;
- (CGSize)_addInsetsToSize:(CGSize)size;
@end

@implementation R4NInsetLabel

- (UIEdgeInsets)contentInsets {
    return UIEdgeInsetsMake(self.contentPadding, self.contentPadding, self.contentPadding, self.contentPadding);
}

- (CGSize)_addInsetsToSize:(CGSize)size {
    CGFloat width = size.width + self.contentInsets.left + self.contentInsets.right;
    CGFloat height = size.height + self.contentInsets.top + self.contentInsets.bottom;
    return CGSizeMake(width, height);
}

- (void)drawTextInRect:(CGRect)rect {
    CGRect insetRect = UIEdgeInsetsInsetRect(rect, self.contentInsets);
    [super drawTextInRect:insetRect];
}

- (CGSize)intrinsicContentSize {
    CGSize baseSize = [super intrinsicContentSize];
    return [self _addInsetsToSize:baseSize];
}

- (CGSize)sizeThatFits:(CGSize)size {
    CGSize baseSize = [super sizeThatFits:size];
    return [self _addInsetsToSize:baseSize];
}

@end

这就是它的样子:

【讨论】:

  • 是的,我正在使用UILabel 的自定义子类。看起来我错过了masksToBounds = YES;,它解决了这个问题。非常感谢您的帮助!
  • @NicHubbard 太棒了。很高兴我能帮上忙。
【解决方案2】:

你还需要在viewDidLayoutSubviews上设置圆角半径

override func viewDidLayoutSubviews() {

    super.viewDidLayoutSubviews()
    label.layer.cornerRadius = yourValue
}

【讨论】:

  • 嗯,我试过了,但似乎没有帮助。 :(
猜你喜欢
  • 2016-03-09
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2014-05-02
相关资源
最近更新 更多