带有内容插入的UIScrollView自动更改边界
我使用UIScrollView作为分页滚动视图pagesScrollView
。 里面,我把个别UIScrollViews专门用于缩放。 在每个内部,我有一个视图,这是应该是可缩放的页面项目。 所有这一切都在一个带有半透明导航栏的UINavigationController中。
我pagesScrollView
有contentInset.top = 64
和bounds.origin.y = -64
(这似乎很奇怪,但这就是系统自动设置为我),这工作得很好。 我的屏幕看起来不错!
然而,在scrollViewWillEndDragging
调用scrollViewWillEndDragging
之后, scrollViewWillEndDragging
会从bounds.origin.y = -64
开始animation变化为bounds.origin.y = 0
,这会导致我的页面项目被遮挡由导航栏。
左边是加载时的样子,右边是拖动几个像素后的样子,然后放开,在导航栏下滑动(因为bounds.origin.y会变成0) 。
问题是,我没有任何代码正在改变的界限,我没有任何代码在各种滚动委托方法做任何事情。 我已经添加了一堆滚动委托方法,只是添加了NSLog(),所以我可以找出更改发生的时间/地点,但是这不会发生在我的代码中的任何地方。
所以,我不知道我可以告诉你什么样的代码来帮助你。
编辑:我从头开始build立一个新的项目,删除所有其他variables..我把一个裸UIViewController到一个UINavigationController。 我把一个UIScrollView放到我的View中,查看整个视图的大小。 以下代码是整个项目。
事实certificate,这个问题(下面描述)只有在UIScrollView上的PAGING被启用后才会出现! 跆拳道? 🙂
这里是一个链接,下载一个基本的项目,只有几行代码来演示这个问题。 只要点击滚动视图,你会看到它随着边界的变化而变化。 http://inadaydevelopment.com/stackoverflow/WeirdScrollViews.zip
我怎么可以在我的滚动视图上启用分页,而不会在滚动和移动导航栏下的所有内容时出现界限?
可以将导航栏设置为不透明,避免出现问题,但理想情况是具有标准的iOS7行为,以便在内容视图放大后,允许内容位于导航栏下方,并通过半透明正常显示。
- (void) viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; NSArray *colors = @[ [UIColor blueColor], [UIColor orangeColor], [UIColor magentaColor], ]; NSArray *zoomerColors = @[ [UIColor greenColor], [UIColor yellowColor], [UIColor purpleColor], ]; self.scroller.pagingEnabled = YES; [self.scroller setContentSize:CGSizeMake(self.scroller.frame.size.width*colors.count, self.scroller.frame.size.height)]; CGRect subviewFrame = CGRectMake(0, 0, 160, 240); for (int index=0; index < colors.count; index++) { UIColor *color = [colors objectAtIndex:index]; UIColor *zoomerColor = [zoomerColors objectAtIndex:index]; UIView *subview = [[UIView alloc] initWithFrame:subviewFrame]; subview.backgroundColor = color; CGRect zoomerFrame = CGRectMake(index*self.scroller.frame.size.width, 0, self.scroller.frame.size.width, self.scroller.frame.size.height); UIScrollView *zoomer = [[UIScrollView alloc] initWithFrame:zoomerFrame]; [zoomer addSubview:subview]; zoomer.backgroundColor = zoomerColor; [self.scroller addSubview:zoomer]; } }
这是一个iOS的错误。 我创build了UIScrollView
的以下子类,以获得随着时间推移发生的事情的日志以及谁在推动它:
@implementation CSScrollView - (void)setContentOffset:(CGPoint)contentOffset { NSLog(@"%0.0f %@", contentOffset.y, [NSThread callStackSymbols]); NSLog(@"[%@]", self.layer.animationKeys); [super setContentOffset:contentOffset]; } @end
(并改变了故事板中的视图类)
当释放你的手指时,一个名为UIScrollView _smoothScrollDisplayLink:
的方法UIScrollView _smoothScrollDisplayLink:
开始将滚动视图animation到其最终位置。 根据第二个日志,不涉及CAAnimation
,滚动视图使用自己的显示链接进行自己的转换。 这个自定义代码看起来会导致animation从y = whatever
到y = 0
的错误,而不考虑内容偏移量。
作为一个概念certificate黑客我改变了代码:
@implementation CSScrollView - (void)setContentOffset:(CGPoint)contentOffset { contentOffset.y = -64.0f; [super setContentOffset:contentOffset]; } @end
不出所料,问题就消失了。
你可能不想硬编码-64.0f
但我可以得出结论:
- 这是一个iOS的错误;
- 通过使用合适的自定义实现
- setContentOffset:
来通过UIScrollView
的子类拒绝无意义的值来解决这个问题。
一个明智的通用手段可能是检查self.panGestureRecognizer
的state
– 这将允许您区分用户负责的滚动和其他滚动,而不依赖任何未公开的API或复杂的委托事件捕获。 然后,如果有必要,从当前值contentOffset.y
正确的contentOffset.y
而不是硬编码它。
只需closures调整滚动查看插图
我已经检查你在viewController.m文件中使用下面的代码
-(void)viewDidLoad { if ([[UIDevice currentDevice] systemVersion].floatValue>=7.0) { self.edgesForExtendedLayout = UIRectEdgeNone; } }
它工作正常…
我pagesScrollView有contentInset.top = 64和bounds.origin.y = -64(这似乎很奇怪,但这就是系统自动设置为我),这工作得很好。 我的屏幕看起来不错!
因为iOS 7在所有滚动视图上将contentInset.top设置为64。 只需将这行代码添加到您的视图控制器,所有将按预期工作:
-(UIRectEdge)edgesForExtendedLayout { return UIRectEdgeNone;
}
我检查了你的例子项目。
- 如何在Javascript / Sencha中听键盘打开/closures?
- Swift – 分段控制 – 切换多个视图
- NSURLErrorDomain代码= -1000“不良url”:这是什么意思?
- 转换后的date比较为零
- “构build设置”中的“Objective-C桥接头”条目不会出现在Xcode 8.3中
- 强制应用程序在iOS 8中使用Apple Keyboard
- UIActivityViewController与iOS中的UIDocumentInteractionController
- NSMutableArray分配init与NSMutableArray数组
- 它如何才能迅速closures它的类的引用属性运行?