我有几个UIViews用户应该能够拖动和放大下降。我使用 UIPanGestureRecognizer 来管理d& d操作(请参阅下面的代码)。 d& d动作工作正常,但是当我开始拖动另一个UIView时,我刚刚丢弃的那个正跳回原来的位置。
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:
for (UIView* checkView in dragAndDropImageViewsArray) {
if (checkView == recognizer.view) {
[checkView.superview bringSubviewToFront:checkView]; //this is done to make sure the currently dragged object is the top one
}
}
break;
case UIGestureRecognizerStateChanged:
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
break;
case UIGestureRecognizerStateEnded:
NSLog(@"UIGestureRecognizerStateEnded");
break;
default:
break;
}
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
我尝试了几个“解决”问题但却引发其他问题的事情:
我开始加深对自动布局的理解,但是在我看来,我正在寻找的内容应该非常简单;我看到很多方法都涉及执行“重新自动布局”,但我不清楚如何使用它们。
这里有简单的解决方案吗?比如调用一个覆盖IB Auto-Layout约束的方法并根据UIView的新位置重新定义它们?
任何帮助都会非常受欢迎。
答案 0 :(得分:11)
我认为如果您使用autolayout并且想要更改视图的位置,则需要更新视图上的约束,而不是手动设置视图的中心。从描述中可以看出你正在设置中心,但是当应用程序接下来放置视图时(例如你拖动另一个),它会将中心重新设置为自动布局应该是什么。
我不确定您应用的其余部分是什么样的,但您可以找到附近的视图并为其添加约束,或者您可能更愿意更新拖动视图的约束并设置前导空间和手动顶视空间到superview。如果你有一个方便的收藏,你也可以清除所有约束,然后重新添加它们,因为你想在视图之间保持填充。
要在代码中设置约束,您可以清除移动视图的约束并重新添加它们,或者如果您在IB中有视图,则可以将约束拖动到代码中以创建插座。查看removeConstraints和addConstraints方法,以便在代码中完成。
最后,如果它没有自动布局的方式,你可以尝试在移动的视图上设置translatesAutoresizingMaskIntoConstraints = YES,但要注意,这可能会导致其他地方发生冲突。
答案 1 :(得分:6)
使用Interface Builder可以实现这一切。以下是我用来执行此操作的代码:
@property (weak,nonatomic) IBOutlet NSLayoutConstraint *buttonXConstraint;
@property (weak,nonatomic) IBOutlet NSLayoutConstraint *buttonYConstraint;
然后将这些IBOutlet连接到Interface Builder中的水平约束(X位置)和垂直约束(Y位置)。确保将约束连接到基本视图,而不是它最近的视图。
连接平移手势,然后使用以下代码拖动对象:
- (IBAction)panPlayButton:(UIPanGestureRecognizer *)sender
{
if(sender.state == UIGestureRecognizerStateBegan){
} else if(sender.state == UIGestureRecognizerStateChanged){
CGPoint translation = [sender translationInView:self.view];
//Update the constraint's constant
self.buttonXConstraint.constant += translation.x;
self.buttonYConstraint.constant += translation.y;
// Assign the frame's position only for checking it's fully on the screen
CGRect recognizerFrame = sender.view.frame;
recognizerFrame.origin.x = self.buttonXConstraint.constant;
recognizerFrame.origin.y = self.buttonYConstraint.constant;
// Check if UIImageView is completely inside its superView
if(!CGRectContainsRect(self.view.bounds, recognizerFrame)) {
if (self.buttonYConstraint.constant < CGRectGetMinY(self.view.bounds)) {
self.buttonYConstraint.constant = 0;
} else if (self.buttonYConstraint.constant + CGRectGetHeight(recognizerFrame) > CGRectGetHeight(self.view.bounds)) {
self.buttonYConstraint.constant = CGRectGetHeight(self.view.bounds) - CGRectGetHeight(recognizerFrame);
}
if (self.buttonXConstraint.constant < CGRectGetMinX(self.view.bounds)) {
self.buttonXConstraint.constant = 0;
} else if (self.buttonXConstraint.constant + CGRectGetWidth(recognizerFrame) > CGRectGetWidth(self.view.bounds)) {
self.buttonXConstraint.constant = CGRectGetWidth(self.view.bounds) - CGRectGetWidth(recognizerFrame);
}
}
//Layout the View
[self.view layoutIfNeeded];
} else if(sender.state == UIGestureRecognizerStateEnded){
}
[sender setTranslation:CGPointMake(0, 0) inView:self.view];
}
我在那里添加了代码来检查框架,并确保它不会超出视图范围。如果您想让对象部分脱离屏幕,请随意将其取出。
我花了一点时间才意识到使用AutoLayout正在重置视图,但约束会在这里做你需要的!