UIView 动画完成后删除 layer.cornerRadius
UIView Animation Removes layer.cornerRadius After Completion
我有一个 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
.
有没有办法防止这种情况发生?
您还需要在 viewDidLayoutSubviews
上设置圆角半径
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
label.layer.cornerRadius = yourValue
}
我怀疑您在此处对 UILabel 进行了子类化,因为看起来您在那里有填充,对吗?
您在其中执行的任何自定义操作 drawing/calculations 都可能出现问题,因此它也可能有助于 post 该代码进行检查。
几个问题:
- 您是否将 masksToBounds 设置为 YES?
- 如果您不使用自定义 UILabel 子类,是否将标签包装在视图中?
- 动画是如何触发的?是按一个按钮吗?来自 NSURLRequest 的回调?如果它是由异步回调触发的,你是否跳回主队列执行动画?
- 如果动画在生命周期内自动触发,是在哪个生命周期方法中触发的?
我无法在使用 vanilla UILabel 的测试项目中重现该问题。然后我用一个包含额外填充的 UILabel 子类尝试了它,但仍然无法在那里重现它。
我在下面包含了示例代码片段:
#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
,我正在为其设置动画约束,以便它下降到视图中。我正在使用 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
.
有没有办法防止这种情况发生?
您还需要在 viewDidLayoutSubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
label.layer.cornerRadius = yourValue
}
我怀疑您在此处对 UILabel 进行了子类化,因为看起来您在那里有填充,对吗?
您在其中执行的任何自定义操作 drawing/calculations 都可能出现问题,因此它也可能有助于 post 该代码进行检查。
几个问题:
- 您是否将 masksToBounds 设置为 YES?
- 如果您不使用自定义 UILabel 子类,是否将标签包装在视图中?
- 动画是如何触发的?是按一个按钮吗?来自 NSURLRequest 的回调?如果它是由异步回调触发的,你是否跳回主队列执行动画?
- 如果动画在生命周期内自动触发,是在哪个生命周期方法中触发的?
我无法在使用 vanilla UILabel 的测试项目中重现该问题。然后我用一个包含额外填充的 UILabel 子类尝试了它,但仍然无法在那里重现它。
我在下面包含了示例代码片段:
#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
这是它的样子: