我正在创建一个图像拼贴应用程序。我会有多个
UIScrollView
的。滚动视图将具有自定义形状的边界,用户将能够动态更改形状相交处的角。滚动视图具有
UIImageView
的子视图。
滚动视图是其他UIView的子视图。我申请了
CAShapeLayer
给每个人戴上面具
UIView
的。这样我就可以毫无问题地屏蔽滚动视图。
但问题是,我只能滚动添加的最后一个滚动视图的内容。此外,我可以平移和缩放遮罩的边界。当我触摸作为遮罩的多边形的边界时,我应该只能平移或缩放。
我试过了;
scrollView.clipsToBounds = true
scrollView.layer.masksToBounds = true
但结果是一样的。
不幸的是,我无法发布屏幕截图,但下面是我用来为UIViews创建掩码的代码:
func createMask(v: UIView, viewsToMask: [UIView], anchorPoint: CGPoint)
{
let frame = v.bounds
var shapeLayer = [CAShapeLayer]()
var path = [CGMutablePathRef]()
for i in 0...3 {
path.append(CGPathCreateMutable())
shapeLayer.append(CAShapeLayer())
}
//define frame constants
let center = CGPointMake(frame.origin.x + frame.size.width / 2, frame.origin.y + frame.size.height / 2)
let bottomLeft = CGPointMake(frame.origin.x, frame.origin.y + frame.size.height)
let bottomRight = CGPointMake(frame.origin.x + frame.size.width, frame.origin.y + frame.size.height)
switch frameType {
case 1:
// First view for Frame Type 1
CGPathMoveToPoint(path[0], nil, 0, 0)
CGPathAddLineToPoint(path[0], nil, bottomLeft.x, bottomLeft.y)
CGPathAddLineToPoint(path[0], nil, anchorPoint.x, bottomLeft.y)
CGPathAddLineToPoint(path[0], nil, anchorPoint.x, anchorPoint.y)
CGPathCloseSubpath(path[0])
// Second view for Frame Type 1
CGPathMoveToPoint(path[1], nil, anchorPoint.x, anchorPoint.y)
CGPathAddLineToPoint(path[1], nil, anchorPoint.x, bottomLeft.y)
CGPathAddLineToPoint(path[1], nil, bottomRight.x, bottomRight.y)
CGPathAddLineToPoint(path[1], nil, bottomRight.x, anchorPoint.y)
CGPathCloseSubpath(path[1])
// Third view for Frame Type 1
CGPathMoveToPoint(path[2], nil, 0, 0)
CGPathAddLineToPoint(path[2], nil, anchorPoint.x, anchorPoint.y)
CGPathAddLineToPoint(path[2], nil, bottomRight.x, anchorPoint.y)
CGPathAddLineToPoint(path[2], nil, bottomRight.x, 0)
CGPathCloseSubpath(path[2])
default:
break
}
for (key, view) in enumerate(viewsToMask) {
shapeLayer[key].path = path[key]
view.layer.mask = shapeLayer[key]
}
}
那么,我如何才能使滚动视图的行为方式使其仅在触摸发生在相应的遮罩边界内时滚动或缩放内容?
编辑:
根据这个问题的答案:
UIView's masked-off area still touchable?
面具只会修改你能看到的东西,而不会修改你能触摸的区域。所以我对UIScrollView进行了子类化,并试图重写
hitTest:withEvent:
这样的方法,
protocol CoolScrollViewDelegate: class {
var scrollViewPaths: [CGMutablePathRef] { get set }
}
class CoolScrollView: UIScrollView
{
weak var coolDelegate: CoolScrollViewDelegate?
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView?
{
if CGPathContainsPoint(coolDelegate?.scrollViewPaths[tag], nil, point, true) {
return self
} else {
return nil
}
}
}
但是使用这个实现,我只能检查最后一个滚动视图,并且当我放大时路径边界会发生变化。例如,如果我放大图像
hitTest:带有事件:
方法返回nil。