objective-c - Objecitve C/Swift Pinch 放大区域
问题描述
我发现很多关于 SO 的问题可以放大,并且我已经能够按照它们来真正让它工作,但我遇到的问题是它是如何工作的。
当我捏放大时,我认为它会放大到我捏时手指所在的区域。然而,无论我的手指在哪里,当我捏它时,它会放大到恰好是我视图左上角的同一区域。有没有办法控制缩放发生的位置?
作为参考,我正在实现我的捏以缩放滚动视图,如下所示(在 Objective C 中,但答案可以在 Swift 中):
_scrollView = [[UIScrollView alloc] init];// scrollview
_nestedView = [[UIView alloc] init];// top level view within scrollview that contains everything
_scrolledView = scrolledView;// the view I want to zoom into when pinching - a UIView in this case
// viewDidLoad
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
self.nestedView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:self.nestedView];
[self.view addSubview:self.scrollView];
self.scrollView.delegate = self;
self.scrollView.panGestureRecognizer.enabled = YES;// tried with this on an off but doesn't seem to do anything
self.scrollView.bouncesZoom = NO;
self.scrollView.minimumZoomScale = 1.0;
self.scrollView.maximumZoomScale = 3.0;
self.scrollView.zoomScale = 1.0;
// Delegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.scrolledView;
}
// Constraints
[NSLayoutConstraint constraintWithItem:self.nestedView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.nestedView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.nestedView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.nestedView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.scrollView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0],
// scrolledView constraints
[NSLayoutConstraint constraintWithItem:self.scrolledView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.scrolledView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.scrolledView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0],
[NSLayoutConstraint constraintWithItem:self.scrolledView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0],
再次,缩放缩放发生了,但它只是不断放大到我的视图的左上角(scrolledView),不幸的是这使得缩放对我的用例完全没有意义。
解决方案
这是基于本教程的一种方法:https ://www.raywenderlich.com/5758454-uiscrollview-tutorial-getting-started
@interface ViewController ()
{
UIScrollView *scrollView;
UIImageView *imageView;
NSLayoutConstraint *imageViewTopConstraint;
NSLayoutConstraint *imageViewLeadingConstraint;
NSLayoutConstraint *imageViewTrailingConstraint;
NSLayoutConstraint *imageViewBottomConstraint;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// set name of image asset here
NSString *imageName = @"myImage";
UIImage *img = [UIImage imageNamed:imageName];
NSAssert(img, @"Failed to load image!");
scrollView = [UIScrollView new];
imageView = [UIImageView new];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
imageView.translatesAutoresizingMaskIntoConstraints = NO;
imageView.contentMode = UIViewContentModeScaleToFill;
[scrollView addSubview:imageView];
[self.view addSubview:scrollView];
// respect safe area
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
UILayoutGuide *cg = scrollView.contentLayoutGuide;
imageViewTopConstraint = [imageView.topAnchor constraintEqualToAnchor:cg.topAnchor];
imageViewLeadingConstraint = [imageView.leadingAnchor constraintEqualToAnchor:cg.leadingAnchor];
imageViewTrailingConstraint = [imageView.trailingAnchor constraintEqualToAnchor:cg.trailingAnchor];
imageViewBottomConstraint = [imageView.bottomAnchor constraintEqualToAnchor:cg.bottomAnchor];
[NSLayoutConstraint activateConstraints:@[
[scrollView.topAnchor constraintEqualToAnchor:g.topAnchor constant:0.0],
[scrollView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:0.0],
[scrollView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
[scrollView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:0.0],
imageViewTopConstraint,
imageViewLeadingConstraint,
imageViewTrailingConstraint,
imageViewBottomConstraint,
]];
scrollView.delegate = self;
// this will be updated
scrollView.minimumZoomScale = 0.1;
// desired max zoom scale
scrollView.maximumZoomScale = 5.0;
imageView.image = img;
imageView.frame = CGRectMake(0.0, 0.0, img.size.width, img.size.height);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self updateMinZoomScaleForSize:scrollView.bounds.size];
[self updateConstraintsForSize:scrollView.bounds.size];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return imageView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
[self updateConstraintsForSize:scrollView.frame.size];
}
- (void)centerImage {
CGFloat yOffset = (scrollView.frame.size.height - imageView.frame.size.height) * 0.5;
CGFloat xOffset = (scrollView.frame.size.width - imageView.frame.size.width) * 0.5;
scrollView.contentOffset = CGPointMake(xOffset, yOffset);
}
- (void)updateMinZoomScaleForSize:(CGSize)size {
UIImage *img = imageView.image;
if (!img) {
return;
}
CGFloat widthScale = size.width / img.size.width;
CGFloat heightScale = size.height / img.size.height;
CGFloat minScale = MIN(widthScale, heightScale);
scrollView.minimumZoomScale = minScale;
scrollView.zoomScale = minScale;
}
- (void)updateConstraintsForSize:(CGSize)size {
CGFloat yOffset = MAX(0.0, (size.height - imageView.frame.size.height) * 0.5);
imageViewTopConstraint.constant = yOffset;
imageViewBottomConstraint.constant = yOffset;
CGFloat xOffset = MAX(0.0, (size.width - imageView.frame.size.width) * 0.5);
imageViewLeadingConstraint.constant = xOffset;
imageViewTrailingConstraint.constant = xOffset;
[self.view layoutIfNeeded];
}
@end
推荐阅读
- python - 在 Azure Web Apps 中设置 Python 服务器
- javascript - 如何使用node js检查文件中有多少行代码
- php - 如何在codeigniter中显示应用于电子商务网站中产品的过滤器数量?
- c++ - VS Code C++ program does not display any output while debugging
- c# - 将一个以上的班级列表添加到一个班级列表中
- ethereum - 我的智能合约导致错误:气体不足错误
- elasticsearch - 如何计算elasticsearch/kibana中的保留率?
- selenium-webdriver - cucumber.runtime.CucumberException:无法加载插件类:com.cucumber.listener.ExtentCucumberFormatter
- html - 在 div 周围创建一个边框,顶部边框穿过标题,底部边框穿过按钮
- react-native - 使用 npm 安装 react-native-gesture-handler 时出错