我有一个容器视图 - 我们称之为套接字视图 - 它有一个子视图,它是内容视图 - 让我们称之为插件视图。该插件视图可以是nil,即套接字视图当前是空的。如果它确实包含一个插件视图,它将占用整个套接字的空间,即它的框架是套接字的边界。从外观来看,你甚至不应该知道实际上有两个视图,因为插件视图总是与套接字完全一致。
我正在努力让动画正常工作:如果插件视图存在并且在动画之前布局,一切都按预期工作。但是,如果仅在动画已经运行时设置套接字的插件视图,则会产生不良影响:
插件视图布局到动画结束时的位置,并且不会在其插槽旁边进行动画处理。我希望它看起来像是一直存在但只是刚才可见,即插件视图(及其子视图)应该在套接字旁边动画,即使我在动画进行过程中添加它。
我该如何实现这种行为?
我的想法:显然,插件视图必须布置两次:一次用于最终位置,再一次用于套接字视图开始动画或添加位置的位置。我可以计算这个帧,在没有动画的情况下应用它,并在新的动画块中动画到最终帧。为了使动画定时保持一致,我需要具有相同的曲线和持续时间,但过去开始动画或以某种方式转发动画。这可能吗?是否有其他方法让插件视图始终为全宽 ?
。作为Rob回答的后续内容,以下是我正在寻找的更多细节:
套接字视图是动画的,因为它的所有者的绑定大小已更改。您可以将其视为表格视图中的全宽度单元格。
插件视图可能包含其自身的子视图,如图像视图,标签等。这些也应该加入到套接字视图的动画中,就像动画开始以来它们一直存在一样。
虽然理论上可以在已经运行的情况下启动新动画,但我并不介意此边缘情况下的行为。
在动画运行时,用户无需与插件视图进行交互。无论如何,最有可能在接口方向更改期间发生这种情况。
插件视图可能决定在动画时由于异步模型更新而更改其内容,但这又是一个边缘情况,我不介意动画在这种情况下看起来不完美。但是,它的大小不会改变 - 它总是与插件视图的大小相同。
答案 0 :(得分:1)
我用这种方式修改了Rob mayoff代码。这对你有帮助吗?
重要的变化是实际使用CADisplayLink来更新plugView的框架,我添加了一个带有插件约束的子视图。还改变了添加plugView并更新其框架的方式。
检查一下这是否适用于你。您应该能够在项目中替换此代码而不会出现任何问题。
#import "ViewController.h"
@interface UIView (recursiveDescription)
- (NSString *)recursiveDescription;
@end
@interface ViewController ()
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *socketWidthConstraint;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *socketHeightConstraint;
@property (strong, nonatomic) IBOutlet UIView *socketView;
@property (strong, nonatomic) IBOutlet UIImageView *plugView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIView *extraView = [[UIView alloc] init];
extraView.translatesAutoresizingMaskIntoConstraints = NO;
extraView.backgroundColor = [UIColor blackColor];
[self.plugView addSubview:extraView];
NSLayoutConstraint *c1 = [NSLayoutConstraint constraintWithItem:extraView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.plugView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
NSLayoutConstraint *c2 = [NSLayoutConstraint constraintWithItem:extraView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.plugView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
NSLayoutConstraint *c3 = [NSLayoutConstraint constraintWithItem:extraView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.plugView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
NSLayoutConstraint *c4 = [NSLayoutConstraint constraintWithItem:extraView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.plugView attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0];
[self.plugView addConstraints:@[c1, c2, c3, c4]];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)displayLinkDidFire:(CADisplayLink *)link {
CGSize size = [self.socketView.layer.presentationLayer frame].size;
self.plugView.frame = CGRectMake(0, 0, size.width, size.height);
[self.plugView layoutIfNeeded];
}
- (IBAction)plugWasTapped:(id)sender {
if (self.plugView.superview) {
[self.plugView removeFromSuperview];
return;
}
CGSize size = [self.socketView.layer.presentationLayer frame].size;
self.plugView.frame = CGRectMake(0, 0, size.width, size.height);
[self.socketView addSubview:self.plugView];
}
- (IBAction)bigButtonWasTapped:(id)sender {
[UIView animateWithDuration:10 animations:^{
self.socketWidthConstraint.constant = 320;
self.socketHeightConstraint.constant = 320;
[self.view layoutIfNeeded];
}];
}
- (IBAction)smallButtonWasTapped:(id)sender {
[UIView animateWithDuration:5 animations:^{
self.socketWidthConstraint.constant = 160;
self.socketHeightConstraint.constant = 160;
[self.view layoutIfNeeded];
}];
}
@end
答案 1 :(得分:0)
为什么不让插件视图始终作为套接字视图的子视图存在,而是设置hidden = YES
?或者您可以使用alpha = 0
。然后,当您想要显示它时,只需将其设置为隐藏= hidden = NO
或alpha = 1
。
通过这种方式,您的插件视图将始终伴随着#34;当您为套接字视图设置动画时。
顺便说一下,你的术语让我们这些使用TCP套接字的人迷惑了。 ("插座?什么?")