美文网首页iOS开发·布局篇
iOS 解决UIScrollView布局问题(布局受status

iOS 解决UIScrollView布局问题(布局受status

作者: 成语笔记 | 来源:发表于2016-07-29 15:40 被阅读186次

    主题 UIScrollView

    iOS APP中有一个非常好用的功能,那就是当我们在滚动一个UIScrollView滚动了很远很远的时候,假如我们想让UIScrollView回到顶部,我们绝大多数人的做法就是慢慢慢慢的滚动UIScrollView直到他回到顶部,但是iOS给我们提供了一个非常有用的功能,那就是只要我们一点击屏幕上的状态栏,就能让UIScrollView自动回到顶部(初始位置),其实我也是今天学到了这个知识点才知道了这个功能:sweat_smile::joy::joy:感谢MJ

    让UIScrollView自动回到顶部(初始位置)的原理:要使UIScrollView滚动到某一个位置,无非就是设置

    CGPoint offect = scrollView.contentOffset;

    offect.y = - scrollView.contentInset.top;

    [scrollView setContentOffset:offect animated:YES];

    当控制器上只有一个UIScrollView时,系统就会去遍历主窗口上所有的view,当遍历到那个UIScrollView时,就会为他设置:

    CGPoint offect = scrollView.contentOffset;

    offect.y = - scrollView.contentInset.top;

    [scrollView setContentOffset:offect animated:YES];

    当我们一点击statusBar时,就会执行上述代码让UIScrollView回滚到初始位置

    这个功能的不足之处:

    当控制器上面只有一个UIScrollView的时候,系统才会为这个UIScrollView添加这个自动回滚到顶部的功能

    当一个控制器上有多个UIScrollView时,系统就懵了,因为他不确定到底要为那个UIScrollView设置这个自动回滚到顶部的功能,这个时候就只能有我们coder明确的告诉系统:我们要为哪个UIScrollView设置自动回滚到顶部的功能

    解决办法:

    既然系统不能在有多个UIScrollView的时候设置上述功能,那哥就自己来设置,问题是在众多的UIScrollView中,我们应该为那个UIScrollView设置这种功能呢??

    答案是:我们只为显示在用户眼前的UIScrollView设置那个功能

    1.新建一个类LXBTopWindow,我们要在里面控制window的创建,显示和隐藏,我们并不会用到系统自带的一个UIWindow的方法或者属性,因此继承自NSObject就够了,为了调用方便,过设计为类方法

    2.由于在iOS9中,所有的window都必须要有一个rootViewController,因此我们新建一个类LXBTopViewController让他作为window的rootViewController

    3.遍历window上的所有UIScrollView,为满足实际要求的UIScrollView设置回滚到初始位置的功能

    Paste_Image.png

    Paste_Image.png

    Paste_Image.png

    大家都知道自iOS7之后,statusBar的样式是交给控制器来管理的,现在我们在statusBar上盖了一个window,系统就会认为statusBar既然已经看不见了,就没必要多此一举地在用控制器去控制statusBar的样式,因此控制器中控制statusBar样式的代码将会失效

    失效代码如下:

    - (UIStatusBarStyle)preferredStatusBarStyle

    {

    return UIStatusBarStyleLightContent;

    }

    解决办法:

    1.既然这个问题是window引起的,那么自然可以从window下手,window一显示出来,控制器中控制statusBar样式的代码就要失效,因此解决之道就是让window隐藏就可以了

    2.自iOS7之后,statusBar的样式是交给控制器来管理的,但是在iOS7以前statusBar的样式是由UIApplication来管理的,既然window一显示出来,控制器中控制statusBar样式的代码就要失效,那么我们可不可以重新把statusBar样式交给UIApplication来管理呢?? 你控制器失效就失效,哥把statusBar的样式重新交给UIApplication来管理

    答案是:YES,我们可以把statusBar的样式重新交给UIApplication来管理,只需要在Info.plist文件中添加如下字典:

    Paste_Image.png

    这样statusBar的样式就会被UIApplication来管理了,我们可以通过:

    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

    去控制statusBar的样式,值得注意的是,由于此时我们对statusBar的操作是应用级别的,因此整个应用程序中的statusBar的样式都被修改为UIStatusBarStyleLightContent,但是有的地方是不能用UIStatusBarStyleLightContent的,因此我们要在合适的地方(比如这个控制器被弹出屏幕的时候),将statusBar的样式复原:

    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;

    文章二:

    如果在UINavigationController内设置一个UIViewControlller,而UIViewController的第一个子视图是UIScrollView的话,UIScrollview里面所有的subView都会发生下移,如图所示

    代码为

    - (void)viewDidLoad

    {

    [super viewDidLoad];

    UIScrollView *tempScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, 320, 200)];

    [tempScroll setBackgroundColor:[UIColor grayColor]];

    [tempScroll setContentSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height)];

    [self.view addSubview:tempScroll];

    UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    [tempButton setBackgroundColor:[UIColor redColor]];

    [tempButton setTitle:@"subView A" forState:UIControlStateNormal];

    [tempButton setFrame:CGRectMake(80, 0, 80, 100)];

    NSLog(@"%d",tempScroll.subviews.count);

    [tempScroll addSubview:tempButton];

    }

    经过验证性的代码,我发现ios7有一个机制

    在navigationBar,以及statusBar都显示的情况下,Navigation的当前VC,他的VC的view的子视图树的根部的第一个子视图,如果是Scrollview的话,这个scrollview的所有子视图都会被下移64个像素。

    发现了这个机制之后,怎么去修正呢?

    修正方案有两个

    1、把scrollview的所有子视图上移64个像素。

    UIView *targetView = self.view;

    while (targetView.subviews.count >0 && ![targetView isKindOfClass:[UIScrollView class]]) {

    targetView = [targetView.subviews objectAtIndex:0];

    }

    if ([targetView isKindOfClass:[UIScrollView class]]) {

    NSLog(@"you are a scrollview");

    CGSize tempSize = ((UIScrollView *)targetView).contentSize;

    tempSize.height -= 64;

    [(UIScrollView *)targetView setContentSize:tempSize];

    for (UIView *subView in targetView.subviews) {

    CGRect tempRect = subView.frame;

    tempRect.origin.y -= 64;

    [subView setFrame:tempRect];

    }

    }

    2、把scrollView更改地位,是它不是子视图树的根部第一个子视图。

    - (void)viewDidLoad

    {

    [super viewDidLoad];

    UIView *tempBackGround = [[UIView alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:tempBackGround];

    UIScrollView *tempScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, 320, 200)];

    [tempScroll setBackgroundColor:[UIColor grayColor]];

    [tempScroll setContentSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height)];

    [self.view addSubview:tempScroll];

    UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];

    [tempButton setBackgroundColor:[UIColor redColor]];

    [tempButton setTitle:@"subView A" forState:UIControlStateNormal];

    [tempButton setFrame:CGRectMake(80, 0, 80, 100)];

    NSLog(@"%d",tempScroll.subviews.count);

    [tempScroll addSubview:tempButton];

    }

    相关文章

      网友评论

        本文标题:iOS 解决UIScrollView布局问题(布局受status

        本文链接:https://www.haomeiwen.com/subject/uxyzjttx.html