使用动画创建自定义视图
Posted
技术标签:
【中文标题】使用动画创建自定义视图【英文标题】:Creating a custom view with an animation 【发布时间】:2013-10-14 12:04:36 【问题描述】:我正在尝试制作一个自定义视图,其中一个元素(UILabel)具有动画,当点击自定义视图的按钮时,标签应该展开然后收缩。动画的第一部分正确发生,但第二部分不正确。我正在使用这种方法。
[UIView animateWithDuration:1.3 animations:^
CGRect frame = CGRectMake(50, 15, 140, 20);
[labelFav setFrame:frame];
completion:^(BOOL finished)
//[labelFav setHidden:YES];
[UIView animateWithDuration:1.3 animations:^
CGRect frame = CGRectMake(50, 15, 0, 20);
[labelFav setFrame:frame];
];
];
我认为 Refresh 和 LayoutSubviews 方法的实现方式存在问题。 我是按照本教程完成的,ray wenderlinch
问题是在第一个动画被调用之后,LayoutSubviews被调用,所以所有的项目都被设置到初始位置,当第一个动画完成时,第二个动画开始但项目被设置为原始状态,所以我相信动画不会发生,因为动画之间发生了变化。
我想知道如何正确实现这个,你能帮帮我吗?
谢谢。
PS:这是第二个关于同一个问题但角度不同的问题。my previous question
[更新]
这是我的 LayoutSubviews 代码:
- (void)layoutSubviews
[super layoutSubviews];
if(_idEvent == 0) return;
_buttonFav = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
[_buttonFav setImage:[UIImage imageNamed:@"fav.png"] forState:UIControlStateNormal];
[_buttonFav addTarget:self action:@selector(pressedFavButton:) forControlEvents:UIControlEventTouchDown];
_labelButton = [[UILabel alloc]initWithFrame:CGRectMake(0, 45, 0, 20)];
_labelButton.text = @"LABEL";
[self addSubview:_labelButton];
[self addSubview:_buttonFav];
在第二个动画之前调用。我的刷新方法是:
- (void)refresh
if(selected)
[_buttonFav setImage:[UIImage imageNamed:@"fav_sel.png"] forState:UIControlStateNormal];
else
[_buttonFav setImage:[UIImage imageNamed:@"fav.png"] forState:UIControlStateNormal];
我只是根据让我知道按钮是否被点击的属性设置按钮的图像。
【问题讨论】:
只是为了确认:这个项目中没有使用自动布局? 我愿意,那么如何用自动布局制作动画呢?使用新的 XCode,您无法选择禁用它。 【参考方案1】:我愿意,那么如何使用自动布局制作动画呢?随着新 XCode 你没有禁用它的选项。
为标签添加宽度约束。然后在你的实现文件中为这个约束创建IBOutlet
(如果你不知道怎么做,请参阅the section 3. here),让我们这样说:
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonWidthConstraint;
然后你可以这样动画它:
[UIView animateWithDuration:1.3 animations:^
self.buttonWidthConstraint.constant = 140;
[self.view layoutIfNeeded];
completion:^(BOOL finished)
[UIView animateWithDuration:1.3 animations:^
self.buttonWidthConstraint.constant = 0;
[self.view layoutIfNeeded];
];
];
【讨论】:
我不相信这是一个自动布局问题,因为我试图将动画更改为“淡入”“淡出”动画和事件,尽管它确实淡出它不是动画,我认为这是因为在调用第二个布局之前调用了 LayoutSubview。我将向您展示 LayoutSubviews 的代码 这是一个自动布局问题。使用自动布局时不应手动设置框架。只是谷歌:自动布局更改框架。 Here's a video of how my code works(按钮标题隐藏,但这是另一个问题:))。 我会尝试,但我不是通过 Interface Builder 而是通过代码设置我的 UIView,如何通过代码设置 NSLayoutConstraint?感谢您的帮助[NSLayoutConstraint constraintWithItem:self.label attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:40];
我应该把这个放在哪里?我把它放在 LayoutSubviews labelConstraint = [NSLayoutConstraint constraintWithItem:_labelButton attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:40]; [自我添加约束:标签约束];添加后再次调用LayoutSubview,因此发生无限循环。【参考方案2】:
使用 SetTransform 和 CGAffineTransform
试试这个
[UIView animateWithDuration:1.3 animations:^
[labelFav setTransform:CGAffineTransformMakeScale(0.5,0.5)];
completion:^(BOOL finished)
[UIView animateWithDuration:1.3 animations:^
[labelFav setTransform:CGAffineTransformMakeScale(1.0,1.0)];
];
];
【讨论】:
【参考方案3】:尝试将 UILabel 封装到 UIView 中并为该视图设置动画。
UIView *auxView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
[auxView addSubview:labelFav];
[UIView animateWithDuration:1.3 animations:^
CGRect frame = CGRectMake(50, 15, 140, 20);
[auxView setFrame:frame];
completion:^(BOOL finished)
//[labelFav setHidden:YES];
[UIView animateWithDuration:1.3 animations:^
CGRect frame = CGRectMake(50, 15, 10, 20);
[auxView setFrame:frame];
];
];
【讨论】:
以上是关于使用动画创建自定义视图的主要内容,如果未能解决你的问题,请参考以下文章
UICollectionViewCell 与自定义 UICollectionViewLayout 仅在一个子视图上创建视差动画