2015-11-07 55 views
1

我试图在拖动时更改UIView框架。我将其分类为UIView并编写了touchesBegantouchesMoved方法。他们是:拖动时调整UIView框架

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    let touch = touches.first 
    startPosition = touch?.locationInView(self) 
} 

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    let touch = touches.first 
    let endPosition = touch?.locationInView(self) 
    let difference = endPosition!.y - startPosition.y 
    let newFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.width, self.frame.height + difference) 
    self.frame = newFrame 
} 

但是,结果我得到了意想不到的行为。描述它有点困难。 Here's video how it works.。小的拖拽(大约20px)使框架在大约100px上更大。

我对自定义视图也有一些限制。图片在自定义视图的底部应保持一直存在:

enter image description here

所以问题是:

  1. 如何使视图上拖曳距离用户更大。
  2. 为什么约束不适用后改变框架,以及如何再次应用它们?

回答

2

您的视图快速增长的原因是您始终使用自第一次触摸以来移动的距离更新当前视图高度。您应该始终添加移动到视图原始高度的距离,而不是修改当前高度。

将另一个属性添加到您的自定义视图以跟踪视图的原始高度。将其设置为touchesBegan,然后在touchesMoved计算帧时使用originalHeight

class CustomView: UIView { 

    var startPosition: CGPoint? 
    var originalHeight: CGFloat = 0 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let touch = touches.first 
     startPosition = touch?.locationInView(self) 
     originalHeight = self.frame.height 
    } 

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let touch = touches.first 
     let endPosition = touch?.locationInView(self) 
     let difference = endPosition!.y - startPosition!.y 
     let newFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.width, originalHeight + difference) 
     self.frame = newFrame 
    } 

} 

为什么约束不改变帧申请后,如何重新申请 呢?

使用自动布局时,您确实不应该更新帧。正确的做法是将@IBOutlet添加到视图的高度约束中,然后在您希望更改视图的高度时更新约束的constant属性。

当您这样做时,自动布局将使用更新的高度正确定位自定义视图的子视图。

要将@IBOutlet从高度约束在文档大纲添加到高度约束你的代码,控制 -drag您的viewController。给它起个名字,如customViewHeight

Control drag to create @IBOutlet for height constraint

由于您更新视图的高度代码视图代码本身,有指定的viewController的高度约束到自定义视图viewDidLoad。然后,自定义视图可以更新高度约束的constant属性以调整视图的大小。

class ViewController: UIViewController { 

    @IBOutlet weak var customViewHeight: NSLayoutConstraint! 

    @IBOutlet weak var customView: CustomView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Assign the layout constraint to the custom view so that it can update it itself 
     customView.customViewHeight = customViewHeight 
    } 
} 

class CustomView: UIView { 

    var startPosition: CGPoint? 
    var originalHeight: CGFloat = 0 
    var customViewHeight: NSLayoutConstraint! 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let touch = touches.first 
     startPosition = touch?.locationInView(self) 
     originalHeight = customViewHeight.constant 
    } 

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let touch = touches.first 
     let endPosition = touch?.locationInView(self) 
     let difference = endPosition!.y - startPosition!.y 
     customViewHeight.constant = originalHeight + difference 
    } 

} 
0

在你的情况,我认为你应该改变底部约束的常量而不是改变视图的框架。顺便说一句,你最好使用手势而不是重写触摸方法,因为手势是更高级别的API并且更易于维护。基本上,使用Autolayout的项目应避免使用帧更改视图。