让我说:
UIImageView
的{{1}} fox
的父ImageView fence
中的主UIView
现在换句话说,我希望ViewControllers
仅在其fox
内移动
在我的fence
中:
viewDidLoad()
现在这部分工作正常,我想通过对override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(fence)
fence.addSubview(fox)
}
进行子类化并进行一些修改来移动fox
:
UIImageView
现在,我可以将class DraggableImageView: UIImageView {
var dragStartPositionRelativeToCenter : CGPoint?
override init(image: UIImage!) {
super.init(image: image)
self.isUserInteractionEnabled = true
addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(nizer:))))
layer.shadowColor = UIColor.black.cgColor
layer.shadowOffset = CGSize(width: 0, height: 3)
layer.shadowOpacity = 0.5
layer.shadowRadius = 2
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func handlePan(nizer: UIPanGestureRecognizer!) {
if nizer.state == UIGestureRecognizer.State.began {
let locationInView = nizer.location(in: superview)
dragStartPositionRelativeToCenter = CGPoint(x: locationInView.x - center.x, y: locationInView.y - center.y)
layer.shadowOffset = CGSize(width: 0, height: 20)
layer.shadowOpacity = 0.3
layer.shadowRadius = 6
return
}
if nizer.state == UIGestureRecognizer.State.ended {
dragStartPositionRelativeToCenter = nil
layer.shadowOffset = CGSize(width: 0, height: 3)
layer.shadowOpacity = 0.5
layer.shadowRadius = 2
return
}
let locationInView = nizer.location(in: superview)
UIView.animate(withDuration: 0.1) {
self.center = CGPoint(x: locationInView.x - self.dragStartPositionRelativeToCenter!.x,
y: locationInView.y - self.dragStartPositionRelativeToCenter!.y)
}
}}
对象拖到我喜欢的任何位置,但是;如果我只想在fox
对象内移动fox
,该怎么办?由于它是子视图,所以我认为是可能的。
答案 0 :(得分:2)
为了将图像视图保留在其父视图中,我在更新视图中心之前添加了一项检查,以确保视图框架位于父框架中。仅当更新将视图保持在其父框架之内时,中心才会更新。
我还更新了平移处理程序以使用翻译(类似于平移手势documentation中的示例),而不是locationInView。 这样可以使拖动效果更好。
我已经对此进行了测试,并且我相信它会按照您期望的方式运行。希望这会有所帮助:
@objc func handlePan(nizer: UIPanGestureRecognizer!) {
if nizer.state == UIGestureRecognizer.State.began {
dragStartPositionRelativeToCenter = self.center
layer.shadowOffset = CGSize(width: 0, height: 20)
layer.shadowOpacity = 0.3
layer.shadowRadius = 6
return
}
if nizer.state == UIGestureRecognizer.State.ended {
dragStartPositionRelativeToCenter = nil
layer.shadowOffset = CGSize(width: 0, height: 3)
layer.shadowOpacity = 0.5
layer.shadowRadius = 2
return
}
if let initialCenter = dragStartPositionRelativeToCenter {
let translation = nizer.translation(in: self.superview)
let newCenter = CGPoint(x: initialCenter.x + translation.x, y: initialCenter.y + translation.y)
if frameContainsFrameFromCenter(containingFrame: superview!.frame, containedFrame: self.frame, center: newCenter) {
UIView.animate(withDuration: 0.1) {
self.center = newCenter
}
}
}
}
func frameContainsFrameFromCenter(containingFrame: CGRect, containedFrame: CGRect, center: CGPoint) -> Bool {
let leftMargin = containedFrame.width / 2
let topMargin = containedFrame.height / 2
let testFrame = CGRect(
x: leftMargin,
y: topMargin,
width: containingFrame.width - (2*leftMargin),
height: containingFrame.height - (2*topMargin)
)
return testFrame.contains(center)
}