我正在使用UIScrollView,并在里面添加一张图像,每页一页。我在旋转iPhone时遇到了问题。
当我旋转iPhone时,scrollViewDidScroll(滚动视图代理方法)会被调用。因此,我的分页出现问题,页码会改变。
解决方案是什么?
我正在使用UIScrollView,并在里面添加一张图像,每页一页。我在旋转iPhone时遇到了问题。
当我旋转iPhone时,scrollViewDidScroll(滚动视图代理方法)会被调用。因此,我的分页出现问题,页码会改变。
解决方案是什么?
Raphaël的回答是问题的一个很好的描述,并提供了一个巧妙的解决方法。我遇到了完全相同的问题,最终使用了一个scrollingLocked
标志,我在旋转开始前将其设置为YES(锁定),在旋转结束时设置为NO(解锁)。这样做可能比临时更改contentSize略微不太hacky。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
duration:(NSTimeInterval)duration
{
self.photoViewer.scrollingLocked = YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation
{
self.photoViewer.scrollingLocked = NO;
}
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
if (self.scrollingLocked)
{
return;
}
/* do normal scrollViewDidScroll: stuff */
}
UIScrollView
的内置属性scrollEnabled
。顺便说一下,在最后一张图片时,这仍然会触发scrollViewDidScroll
,原因不明。 - Steven我发现了一个奇怪的未记录行为,当旋转分页UIScrollView
时。
当滚动视图位于最后一页并且用户更改方向时,操作系统会将UIScrollView
滚动回几个像素以弥补高度和宽度之间的差异。
基本上,对于任何页面,我都收到以下调用。
willRotateToInterfaceOrientation:duration
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:
最后一页的情况:
willRotateToInterfaceOrientation:duration
scrollViewDidScroll:
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:
这也搞糊涂了我的页面。问题在于,在 willRotate
中,边界尚未被操作系统更新,在 willAnimate
中,您已经拥有了新的边界并且可以计算新的大小,但为时已晚...
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
CGSize tempSize = [self.pagingScrollView contentSize];
NSUInteger padding = abs(pagingScrollView.frame.size.width - pagingScrollView.frame.size.height);
tempSize.width += padding;
[self.pagingScrollView setContentSize:tempSize];
[...]
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration{
CGSize newSize = ... // Compute new content size based on new orientation
[self.pagingScrollView setContentSize:newSize];
}
这只是一种解决方法,但我在这个问题上花费了无数小时,并找不到一个优雅的解决方案。
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
// Execute before rotation
}) { _ in
//Execute after rotation
}
}
Swift 4解决方案:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
lui.l("apply previousTraitCollection: \(previousTraitCollection)")
canScroll = true
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation
{
if( UIInterfaceOrientationIsPortrait( [[UIApplication sharedApplication] statusBarOrientation] ) ){
scrollView.contentSize = portaitScrollSize;
}
else{//statusbar is Landscape
scrollView.contentSize = landscapeScrollSize;
}
}
scrollView绑定到Interface Builder中的iVar视图。portaitScrollSize
和landscapeScrollSize
是私有变量。它们被初始化并且不会改变。
在my.h
文件中:
IBOutlet UIScrollView *scrollView;
CGSize portaitScrollSize, landscapeScrollSize;
...
portaitScrollSize = CGSizeMake(320,440);
landscapeScrollSize = CGSizeMake(480,480);
我希望这能帮助有需要的人为肖像设计添加旋转+滚动功能。
别忘了在顶部组件上允许肖像+横向:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return TRUE;
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[self.scrollView setContentSize:CGSizeMake(self.scrollView.contentSize.width + 400, self.scrollView.contentSize.height)];
}
在屏幕方向改变后,请确保重新设置内容大小和偏移量:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[self.scrollView setContentSize:CGSizeMake(self.scrollView.bounds.size.width *3, self.scrollView.bounds.size.height)];
[self.scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width * self.pageControl.currentPage, 0) animated:NO];
}