先上效果图吧,框框被限制在了image内了。
就好像Ray Wenderlich的iOS Apprentice一书说的一样,要实现任何feature都要列个任务清单。所以我们先列个任务清单:
1. 实现把一个可拖动的View限制在一个特定的View里。
2. 实现把框到的image放大。
首先讲第一点:
既然要实现拖动的feature,Google之后就知道Cocoa Touch框架里的UIKit module里有一个UIPanGestureRecognizer类,有了这个类之后就可以实现拖拽feature了。
那么Google之后又知道了有两种方式:
一种是纯代码(在要放大的View所在的controller里或者view里, 在willAppear时刻或者didLoad时刻或者layoutSubView时刻写上, xxxView是拖拽的View):
let panGesture = UIPanGestureRecognizer.init(target: self, action: #selector(handlePan(sender: )))
xxxView.addGestureRecognizer(panGesture)
之后再在放大的View所在的类中写selector, 就是观察者panGestureRecognizer观察到被观察者(在这里是要拖拽的View)的变化之后执行的function。
@objc func handlePan(sender: UIPanGestureRecognizer) {
...
}
另一种是直接在storyboard里面拖panGesture到要拖拽的view上即可,再用IBAction连接到代码里,这个Action里写的东西和前面的handlePan一样。
那么如何限制在所在view里呢?
Easy playing! 只要在action里添加(assistView是铺在上面的UIView,):
let transition = sender.translation(in: self.assistView)
let changeX = (sender.view?.center.x)! + transition.x
let changeY = (sender.view?.center.y)! + transition.y
var limitCenter = CGPoint.init(x: changeX, y: changeY)
limitCenter.y = max((sender.view?.frame.size.height)! / 2, limitCenter.y)
limitCenter.y = min(self.assistView.frame.size.height - (sender.view?.frame.size.height)! / 2, limitCenter.y)
limitCenter.x = max((sender.view?.frame.size.width)! / 2, limitCenter.x)
limitCenter.x = min(self.assistView.frame.size.width - (sender.view?.frame.size.width)! / 2, limitCenter.x)
sender.view?.center = limitCenter
sender.setTranslation(CGPoint.zero, in: self.assistView)
到了这一步之后就可以把这个view限制在imageView里了。
至此第一步实现。
那么第二步就简单了(因为可以直接Google到),
在所在类里写上这两个functions:
private func snapshotTargetView(view: UIView!, inRect rect: CGRect!) -> UIImage! {
let scale = UIScreen.main.scale
//Snapshot of view
UIGraphicsBeginImageContextWithOptions(rect.size, false, scale)
UIGraphicsGetCurrentContext()?.translateBy(x: -rect.origin.x, y: -rect.origin.y)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
//Need this to stop screen flashing, but it's slower
let snapshotImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return snapshotImage
}
private func resizeImage(image: UIImage, toNewSize newSize:CGSize) -> UIImage {
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(newSize, false, scale)
image.draw(in: CGRect(x:0, y:0, width:newSize.width, height:newSize.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
再在Action里加上这两句(resultImageView是放大后要put的地方):
let transition = sender.translation(in: self.assistView)
let changeX = (sender.view?.center.x)! + transition.x
let changeY = (sender.view?.center.y)! + transition.y
var limitCenter = CGPoint.init(x: changeX, y: changeY)
limitCenter.y = max((sender.view?.frame.size.height)! / 2, limitCenter.y)
limitCenter.y = min(self.assistView.frame.size.height - (sender.view?.frame.size.height)! / 2, limitCenter.y)
limitCenter.x = max((sender.view?.frame.size.width)! / 2, limitCenter.x)
limitCenter.x = min(self.assistView.frame.size.width - (sender.view?.frame.size.width)! / 2, limitCenter.x)
sender.view?.center = limitCenter
sender.setTranslation(CGPoint.zero, in: self.assistView)
// add this two lines
let imges = snapshotTargetView(view: self.productImageView, inRect: sender.view?.frame)
resultImageView.image = resizeImage(image: images!, toNewSize: resultImageView.frame.size)
OK了?。
效果: