Мне нужно увеличить красные представления внутри серого представления до заданных красных границ (в этом случае границы представления прокрутки в зависимости от заданного соотношения ширины / высоты) внутри представления прокрутки, сохраняя видимые размеры видимых видов неизменными.Они также должны всегда касаться зеленой границы.
Я пытаюсь добиться этого, используя масштабные преобразования для этих видов, чтобы при масштабировании вида с прокруткой я уменьшал масштаб этих видов, используя формулу 1 / zoomScale
, и меняя их опорные точки, чтобы они оставались на зеленой границе.
Проблема в том, что я не понимаю, как рассчитать целевой прямоугольник для красных видов после всех этих манипуляций, чтобы я мог перейти к нему, используя соответствующие zoomScale
.
Пожалуйста, смотритеполный демонстрационный проект здесь
РЕДАКТИРОВАТЬ
Серый вид может выходить за границы просмотра с прокруткой (см. последнее изображение), главное, чтобы он соответствовал зеленый прямоугольник, окруженный красными видами (вы можете думать о них как о негативных вставках для зеленой области) внутри границ вида прокрутки, поэтому мы должны вычислить, принимая во внимание начальный и конечный размер зеленого прямоугольника, для которого красные видыдолжно быть «закреплено».
Основные методы
- (void)adjustScrollPositionAndZoomToFrame:(CGRect)frame
{
CGFloat viewWidth = frame.size.width;
CGFloat viewHeight = frame.size.height;
CGFloat scrollViewWidth = self.scrollView.frame.size.width;
CGFloat scrollViewHeight = self.scrollView.frame.size.height;
CGSize newSize = [self scaleSize:frame.size toHeight:scrollViewHeight];
if (newSize.width > scrollViewWidth) {
newSize = [self scaleSize:frame.size toWidth:scrollViewWidth];
}
CGFloat scaleFactor = newSize.height == scrollViewHeight
? scrollViewHeight / viewHeight
: scrollViewWidth / viewWidth;
[self scrollRect:frame toCenterInScrollView:self.scrollView animated:NO];
self.scrollView.zoomScale = scaleFactor;
}
Масштабирование
- (void)handleZoom:(CGFloat)zoom
{
NSArray *anchorPoints = @[[NSValue valueWithCGPoint:CGPointMake(1.0, 1.0)],
[NSValue valueWithCGPoint:CGPointMake(0.5, 1.0)],
[NSValue valueWithCGPoint:CGPointMake(0.0, 1.0)],
[NSValue valueWithCGPoint:CGPointMake(1.0, 0.5)],
[NSValue valueWithCGPoint:CGPointMake(0.5, 0.5)],
[NSValue valueWithCGPoint:CGPointMake(0.0, 0.5)],
[NSValue valueWithCGPoint:CGPointMake(1.0, 0.0)],
[NSValue valueWithCGPoint:CGPointMake(0.5, 0.0)],
[NSValue valueWithCGPoint:CGPointMake(0.0, 0.0)]
];
for (UILabel *label in _labels) {
[self setViewAnchorPoint:label value:[anchorPoints[[_labels indexOfObject:label]] CGPointValue]];
label.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1 / zoom, 1 / zoom);
}
}
/**
* @see https://stackoverflow.com/a/9649399/3004003
* @param value See view.layer.anchorPoint
*/
- (void)setViewAnchorPoint:(UIView *)view value:(CGPoint)value
{
CGPoint newPoint = CGPointMake(view.bounds.size.width * value.x,
view.bounds.size.height * value.y);
CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x,
view.bounds.size.height * view.layer.anchorPoint.y);
newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);
CGPoint position = view.layer.position;
position.x -= oldPoint.x;
position.x += newPoint.x;
position.y -= oldPoint.y;
position.y += newPoint.y;
view.layer.position = position;
view.layer.anchorPoint = value;
}
Начальная сцена перед увеличением:
Что у меня после увеличения:
Что мне нужно после увеличения: