【发布时间】:2014-09-18 19:29:12
【问题描述】:
我的应用中有一个包含三个视图的 segmentedControl,其中一个是 scrollView,它的工作原理类似于一种没有缩放的画廊,pageControl 和一个 imageView 在中心。
层次结构是这样的
--> 分段控制(3 个视图):descriptionView、imageTabView、shareView
----> imagesTabView (UIView)
------> 滚动视图
------> 图像视图
----> 页面控制
当设备为纵向或横向时,imageView 图像正确显示、居中且滚动效果非常好。
唯一的问题是,当您再次转动设备时,如果图像位于“中间”(例如,是 3 个中的第 2 个或 6 个中的第 3 个),它会显示为偏心、最左边或最右边,并且轻轻滑动它会回到中心,而如果图像是第一个或最后一个,它可以正常工作。
我在 S.O. 上看过这里。在各种线程上,尝试将contentView 设置为scrollView 的子视图并将imageView 添加为contentView 的子视图,但没有奏效,尝试将imageView 附加到底部或右侧scrollView 但也不起作用。
我觉得我离实现我想做的事情还有一步之遥,唯一的问题是我不明白为什么它没有居中。
在viewWillLayoutSubviews 中我指定了contentSize,以便在它旋转时正确设置它的大小,比如
-(void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.scrollView.contentSize = CGSizeMake (self.scrollView.frame.size.width * photosArray.count, 1);
}
下面是我如何初始化 pageControl、scrollView 和 imageView:
-(void)configureImageTab{
pageControl = [UIPageControl new];
[pageControl addTarget:self action:@selector(changePage) forControlEvents:UIControlEventValueChanged];
pageControl.translatesAutoresizingMaskIntoConstraints = NO;
//Don't show pageControl when there are no photos
if (photosURL.count == 0)
pageControl.hidden = YES;
//Configuring scrollView
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.imageSegmentView.frame.size.width, self.imageSegmentView.frame.size.height-pageControl.frame.size.height)];
self.scrollView.pagingEnabled = YES;
self.scrollView.delegate = self;
self.scrollView.userInteractionEnabled = YES;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.translatesAutoresizingMaskIntoConstraints = NO;
//... Code cut - adding remote images to fetch to array
//Actual setup -> scrollView adding imageView as subview with all the images
for (int i =0; i< photosArray.count; i++){
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
//imageView setup
imageView = [[UIImageView alloc]initWithFrame:frame];
imageView.backgroundColor = [UIColor clearColor];
imageView.clipsToBounds = YES;
imageView.userInteractionEnabled = YES;
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
imageView.translatesAutoresizingMaskIntoConstraints = YES;
imageView.contentMode = UIViewContentModeScaleAspectFit;
//Setting images urls
[imageView setImageWithURL:[NSURL URLWithString:[photosArray objectAtIndex:i]] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
//Error handling
}
}usingActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
//Adding gesture recognizer to scrollView and imageView as subview
[self.scrollView addGestureRecognizer:singleTap];
[self.scrollView addSubview:imageView];
}
//Setting the contentSize
pageControl.numberOfPages = [photosURL count];
[self.imageSegmentView addSubview:self.scrollView];
[self.imageSegmentView addSubview:pageControl];
//Constraints
NSDictionary *views = @{@"pageControl" : pageControl, @"scrollView" : self.scrollView};
[self.imageSegmentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[pageControl]-0-|" options:0 metrics:nil views:views]];
[self.imageSegmentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]-1-[pageControl]-1-|" options:0 metrics:nil views:views]];
[self.imageSegmentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:nil views:views]];
[pageControl addConstraint:[NSLayoutConstraint constraintWithItem:pageControl attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.imageSegmentView attribute:NSLayoutAttributeHeight multiplier:0 constant:30]];
}
#pragma mark - scrollView delegate -
-(void)scrollViewDidScroll:(UIScrollView *)sView{
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor ((self.scrollView.contentOffset.x - pageWidth /2) /pageWidth) +1;
self.pageControl.currentPage = page;
}
-(IBAction)changePage {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
}
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
pageControlBeingUsed = NO;
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
pageControlBeingUsed = NO;
}
需要注意的是:imageView 正在使用 autoresizingMask:否则,它将无法正确显示图像。
我的猜测是,scrollView 委托中可能有一些需要修复的地方,但我不太确定。
任何建议表示赞赏!
编辑
我注意到 Twitter 应用在浏览用户图片然后转动设备时会出现同样的错误。
编辑 2 用于 TL;DR
基本上,假设我在带有分页的水平滚动视图中有 3 张图像。
我在第一张照片上将设备从纵向切换到横向,它显示在自己的位置,正确居中。
我移到下一张照片,显示为居中,然后我再次将设备转到纵向。照片未正确对齐,未居中
实际上,当设备旋转多次时,第一张和最后一张图像会居中显示。其他不居中
编辑 3
我提取了一些行并制作了sample project 来演示我遇到的问题。我想 contentSize 肯定有问题。
【问题讨论】:
标签: ios uiscrollview autolayout