我面临一个非常奇怪的问题 - 至少对我而言 - 似乎我疯了:) 我有一个UIView,我添加了一个UIPanGestureRecognizer,以便能够在屏幕上垂直移动它;这是我做的代码:
- (id)init {
// ...
UIPanGestureRecognizer *gestureRecognizerPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesturePan:)];
[self.viewMenuProper addGestureRecognizer:gestureRecognizerPan];
imageArrowOriginalFrame = self.imageArrow.frame;
// ...
}
说UIView,self.viewMenuProper
,应该可以向屏幕底部拖动(并朝向默认位置向后移动)。在屏幕正上方放置一个UIImageView,其顶边的位置和宽度是为了保持它们的值,但它的高度应该根据self.viewMenuProper
的位置而改变,这样它似乎连接了那个UIView即使UIView被移动,屏幕顶部还有一些点。
所以这是处理手势的方法:
- (void)handleGesturePan:(UIPanGestureRecognizer *)gestureRecognizerPan {
if (gestureRecognizerPan.state == UIGestureRecognizerStateBegan) {
gesturePanPreviousY = [gestureRecognizerPan locationInView:self].y;
}
else if (gestureRecognizerPan.state == UIGestureRecognizerStateChanged) {
float gesturePanCurrentY = [gestureRecognizerPan locationInView:self].y;
float gesturePanDeltaY = gesturePanCurrentY - gesturePanPreviousY;
float imageArrowFrameNewHeight = self.imageArrow.frame.size.height + gesturePanDeltaY;
if (imageArrowFrameNewHeight <= 200 && imageArrowFrameNewHeight >= imageArrowOriginalFrame.size.height) {
[self.imageArrow setFrame:CGRectMake(imageArrowOriginalFrame.origin.x, imageArrowOriginalFrame.origin.y, imageArrowOriginalFrame.size.width, imageArrowFrameNewHeight)]; // line A
}
// Check if the transformed View won't be too far up any way of the screen
float gesturePanNewY = self.viewMenuProper.transform.ty + gesturePanDeltaY;
if (gesturePanNewY <= 200 && gesturePanNewY > 0) {
[self.viewMenuProper setTransform:CGAffineTransformTranslate(self.viewMenuProper.transform, 0, gesturePanDeltaY)]; // line B
}
gesturePanPreviousY = gesturePanCurrentY;
}
// The below animates the Views back to their default positions
else if (gestureRecognizerPan.state == UIGestureRecognizerStateEnded || gestureRecognizerPan.state == UIGestureRecognizerStateFailed || gestureRecognizerPan.state == UIGestureRecognizerStateCancelled) {
[UIView animateWithDuration:1.0 animations:^{
[self.viewMenuProper setTransform:CGAffineTransformIdentity];
// NOTE: the below line prevents the animation from jumping wrong way 1st before animating the way it should
// http://stackoverflow.com/questions/12535647/uiview-animation-jumps-at-beginning
[self layoutIfNeeded];
}];
self.imageArrow.frame = imageArrowOriginalFrame;
}
}
现在这不起作用:viewMenuProper
移动得很好但imageArrow
仅在前一个位于其最远位置而不再移动时伸展。如果我注释掉A行(看看上面的代码),那么B行工作正常;同样,如果我注释掉B行,那么A行就可以了。但是当它们都被取消注释时,就像我写的那样:imageArrow
并没有像预期的那样延伸。
有什么想法吗? 如果您需要更多说明,请告诉我。
修改:UIView
和UIImageView
都是同一父母UIView
的子女 - 他们之间没有“相互关联”我创建布局的.xib文件。
答案 0 :(得分:1)
在你的情况下,正如我们所确定的,AutoLayout是罪魁祸首。
要禁用它,请取消选中此框:
AutoLayout破坏您的框架更改的原因很大程度上是由于它使用了constraints。当您创建一个开箱即用的控件时,iOS会自动将其当前帧转换为足够的约束,以满足元素的不明确定位。
想象一下,你有一个视图,你已经定位在上/下。如果您添加了一个约束,表示它始终是50pt到50pt,并且触摸左上角和右下角,则最终会出现断裂约束。
相反,想象一下你根本没有赋予元素任何约束:iOS必须猜测你想要它的位置。在你的情况下,你正在翻译控件的框架,但是当“假设”约束到位时,他们告诉控件它在错误的位置,因此试图将其移回。
调用和更新autolayout的方法是:
[myView setNeedsLayout]; // Tells your view that it needs to be laid out again
[self.view layoutIfNeeded]; // Tells the view to update its constraints if they've changed
幸运的是,在您的情况下,您可以禁用AutoLayout并开始一天的活动!不幸的是,如果你决定实际使用 AutoLayout(创建约束和自动调整大小元素),如果你想操纵帧等,你就会遇到更复杂的任务。通常,您可能会发现为约束创建IBOutlet会很有帮助 - 这样您就可以通过编程方式更新约束。