Я работаю над созданием приложения для коллажей изображений. И у меня будет несколько 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 все еще доступна для касания? маски изменяют только то, что вы можете видеть, а не область, к которой вы можете прикоснуться. Итак, я создал подкласс 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:withEvent:
возвращает ноль.