我为标准UIViews 构建了以下解决方案,其中UIScrollView 和CGAffineTransform 缩放不合适,因为我不希望视图的子视图倾斜。我还将它与 CorePlot 折线图一起使用。
缩放以用户开始捏合的点为中心。
这是一个简单的实现:
@interface BMViewController ()
@property (nonatomic, assign) CGFloat pinchXCoord; // The point at which the pinch occurs
@property (nonatomic, assign) CGFloat minZoomProportion; // The minimum zoom proportion allowed. Used to control minimum view width
@property (nonatomic, assign) CGFloat viewCurrentXPosition; // The view-to-zoom’s frame’s current origin.x value.
@property (nonatomic, assign) CGFloat originalViewWidth, viewCurrentWidth; // original and current frame width of the view.
@end
@implementation BMViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Setup the pinch gesture recognizer
UIPinchGestureRecognizer *pinchZoomRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchZoomGestureDetected:)];
[self.view addGestureRecognizer:pinchZoomRecognizer];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.originalViewWidth = self.view.frame.size.width;
self.viewCurrentWidth = self.originalViewWidth;
}
- (void)pinchZoomGestureDetected:(UIPinchGestureRecognizer *)recognizer
{
CGPoint pinchLocation = [recognizer locationInView:self.view];
if (recognizer.state == UIGestureRecognizerStateBegan) {
self.viewCurrentWidth = self.view.frame.size.width;
self.viewCurrentXPosition = self.view.frame.origin.x;
// Set the pinch X coordinate to a point relative to the bounds of the view
self.pinchXCoord = pinchLocation.x - self.viewCurrentXPosition;
self.minZoomProportion = self.originalViewWidth / self.viewCurrentWidth;
}
CGFloat proportion = recognizer.scale;
CGFloat width = self.viewCurrentWidth * MAX(proportion, self.minZoomProportion); // Set a minimum zoom width (the original size)
width = MIN(self.originalViewWidth * 4, width); // Set a maximum zoom width (original * 4)
CGFloat rawX = self.viewCurrentXPosition + ((self.viewCurrentWidth - width) * (self.pinchXCoord / self.viewCurrentWidth)); // Calculate the new X value
CGRect frame = self.view.frame;
CGFloat newXValue = MIN(rawX, 0); // Don't let the view move too far right
newXValue = MAX(newXValue, self.originalViewWidth - width); // Don't let the view move too far left
self.view.frame = CGRectMake(newXValue, frame.origin.y, width, frame.size.height);
NSLog(@"newXValue: %f, width: %f", newXValue, width);
}
@end
这就是调整UIView的水平轴大小所需要做的一切。
对于 Core-Plot,假设 CPTGraphHostingView 是 UIViewController 正在调整大小的视图的子视图。 CPTGraphHostingView 在其框架/边界发生更改时重绘,因此,在包含视图的 layoutSubviews 方法中,更改 CPTGraphHostingView 和绘图区域的框架相对于其父级的边界(这是您应该调整大小的视图)。像这样的:
self.graphHostingView.frame = self.bounds;
self.graphHostingView.hostedGraph.plotAreaFrame.frame = self.bounds;
我没有尝试在图表缩放时更改数据,但我无法想象这会太难。在包含视图的layoutSubviews 中,在CPTGraph 上调用reloadData。