【发布时间】:2019-10-02 07:43:24
【问题描述】:
我需要将灰色视图内的红色视图缩放到滚动视图内的给定红色边界(在本例中,滚动视图边界取决于给定的宽度/高度比),同时保持视图可见大小不变。他们还应该始终触摸绿色边框。
我尝试在此视图上使用缩放变换来实现这一点,以便在向上缩放滚动视图时我使用公式1 / zoomScale 缩小此视图并更改它们的锚点以使其保持在绿色边框。
问题是在所有这些操作之后,我不知道如何计算红色视图的目标边界矩形,因此我可以使用适当的 zoomScale 滚动到它。
Please see full demo project here
编辑
灰色视图可能会缩小滚动视图边框(见上图),主要是适合红色视图包围的绿色矩形(您可能会将它们视为绿色区域的负插图)在滚动视图边界内,所以我们实际上应该考虑绿色矩形的初始和结束大小来计算,红色视图应该被“固定”到。
基本方法
- (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;
}
缩放前的初始场景:
缩放后的效果:
缩放后我需要什么:
【问题讨论】:
标签: objective-c algorithm uiscrollview cgaffinetransform