iOS开发——实战技术OC篇&点击状态栏ScrollView(包括子控件)自动滚到顶部

点击状态栏ScrollView(包括子控件)自动滚到顶部

其实这种方式我们平时见的还是比较多的,而且适合用户的需求,所以就搬来琢磨了一下,感觉效果还不错

这里就直接将解决思路一一写出来不将代码分段展示了,在代码中我加了详细的注释objective-c的套路和swift基本一样,在最后会将Swift和objective-c的代码一起放上,如果需要直接解决问题的童鞋可以直接将代码拷贝到工程里即可

  • 首先创建一个topWindow继承至NSObject,这里我们考虑将这个功能完全封装起来,所以所有的方法都用的类方法,所以用最基本的类就可以
  • 在initialize方法中初始化topWIndow,将topWIndow的级别改成最高的UIWindowLevelAlert级别,设置topWindow位置,并且添加点击手势
  • 在topWIndow被点击调用的方法中,我们拿出UIApplication的keyWindow,遍历keyWindow的所有子控件,如果满足是scrollView同时又显示在当前keyWindow条件时,将subView的contentOffset的y值回复到原始
  • 然后采用递归的套路在遍历subView内时候有满足条件的子控件,直到没有满足条件时会停止

Swift的代码

 1 import UIKit
 2 class TopWindow: UIWindow {
 3     private static let window_: UIWindow = UIWindow()
 4     ///  类初始化方法,保证window_只被创建一次
 5     override class func initialize() {
 6         window_.frame = CGRectMake(0, 0, global.appWidth, 20)
 7         window_.windowLevel = UIWindowLevelAlert
 8         window_.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "topWindowClick"))
 9     }
10     class func topWindowClick() {
11         // 遍历当前主窗口所有view,将满足条件的scrollView滚动回原位
12         searchAllowScrollViewInView(UIApplication.sharedApplication().keyWindow!)
13     }
14     private class func searchAllowScrollViewInView(superView: UIView) {
15         for subview: UIView in superView.subviews as! [UIView] {
16             if subview.isKindOfClass(UIScrollView.self) && superView.viewIsInKeyWindow() {
17                 // 拿到scrollView的contentOffset
18                 var offest = (subview as! UIScrollView).contentOffset
19                 // 将offest的y轴还原成最开始的值
20                 offest.y = -(subview as! UIScrollView).contentInset.top
21                 // 重新设置scrollView的内容
22                 (subview as! UIScrollView).setContentOffset(offest, animated: true)
23             }
24             // 递归,让子控件再次调用这个方法判断时候还有满足条件的view
25             searchAllowScrollViewInView(subview)
26         }
27     }
28     ///  添加topWindow,使手势生效
29     class func showTopWindow() {
30         window_.hidden = false
31     }
32     ///  隐藏topWindow,移除手势
33     class func hiddenTopWindow() {
34         window_.hidden = true
35     }
36 }
37 ///  对UIView的一个扩展
38 extension UIView {
39     ///  判断调用方法的view是否在keyWindow中
40     func viewIsInKeyWindow() -> Bool {
41         let keyWindow = UIApplication.sharedApplication().keyWindow!
42         // 将当前view的坐标系转换到window.bounds
43         let viewNewFrame = keyWindow.convertRect(self.frame, fromView: self.superview)
44         let keyWindowBounds = keyWindow.bounds
45         // 判断当前view是否在keyWindow的范围内
46         let isIntersects = CGRectIntersectsRect(viewNewFrame, keyWindowBounds)
47         // 判断是否满足所有条件
48         return !self.hidden && self.alpha > 0.01 && self.window == keyWindow && isIntersects
49     }
50 }
在AppDelegate里,程序启动完成方法时添加就OK了
1 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
2     // 添加顶部的window
3     TopWindow.showTopWindow()
4     return true
5   }

需要注意添加了自定义的window后,控制器的改变状态栏状态方法会失效,可以在info.plist中将改变状态栏的管理权交给UIApplication解决,或者在需要改变状态栏的控制器中调用TopWindow.hiddenTopWindow()即可,或者直接改info.plist,用UIApplication.sharedApplication().setStatusBarStyle来管理

objective-c代码

.h文件只暴露显示和隐藏方法

1  @interface WNXTopWindow : NSObject
2 + (void)show;
3 + (void)hide;
4 @end

.m文件

 1 #import "WNXTopWindow.h"
 2 @implementation WNXTopWindow
 3 static UIWindow *window_;
 4 //初始化window
 5 + (void)initialize {
 6     window_ = [[UIWindow alloc] init];
 7     window_.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 20);
 8     window_.windowLevel = UIWindowLevelAlert;
 9     [window_ addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(windowClick)]];
10 }
11 + (void)show {
12     window_.hidden = NO;
13 }
14 + (void)hide {
15     window_.hidden = YES;
16 }
17 // 监听窗口点击
18 + (void)windowClick {
19     UIWindow *window = [UIApplication sharedApplication].keyWindow;
20     [self searchScrollViewInView:window];
21 }
22 + (void)searchScrollViewInView:(UIView *)superview {
23     for (UIScrollView *subview in superview.subviews) {
24         // 如果是scrollview, 滚动最顶部
25         if ([subview isKindOfClass:[UIScrollView class]] && [subview isShowingOnKeyWindow]) {
26             CGPoint offset = subview.contentOffset;
27             offset.y = - subview.contentInset.top;
28             [subview setContentOffset:offset animated:YES];
29         }
30         // 递归继续查找子控件
31         [self searchScrollViewInView:subview];
32     }
33 }
34 + (BOOL)isShowingOnKeyWindow:(UIView *)view {
35     // 主窗口
36     UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
37     // 以主窗口左上角为坐标原点, 计算self的矩形框
38     CGRect newFrame = [keyWindow convertRect:view.frame fromView:view.superview];
39     CGRect winBounds = keyWindow.bounds;
40     // 主窗口的bounds 和 self的矩形框 是否有重叠
41     BOOL intersects = CGRectIntersectsRect(newFrame, winBounds);
42     return !view.isHidden && view.alpha > 0.01 && view.window == keyWindow && intersects;
43 }
44 @end
45 同样,也是在程序初始化完成AppDelegate文件中显示topWindow,整个工程这个问题就统统解决了
46
47 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
48     // 添加一个window, 点击这个window, 可以让屏幕上的scrollView滚到最顶部
49     [WNXTopWindow show];
50     return YES;
51 }
时间: 2024-08-02 06:59:06

iOS开发——实战技术OC篇&点击状态栏ScrollView(包括子控件)自动滚到顶部的相关文章

iOS开发——实战技术OC篇&关于蒙板和弹出菜单

关于蒙板和弹出菜单 一:关于蒙板 蒙板的作用一般就是用来实现不能做其他操作还有一些模糊效果提示用户 我们只需要自定义一个View,并且创建两个类方法用来给外界调用实现显示和隐藏 + (void)show; + (void)hide; 显示:直接添加到window上,并且设置和window同样大小,然后设置相应的透明度(alpla) 1 + (void)show 2 3 { 4 5 6 7 8 9 iCocosCover *cover = [[self alloc] init]; 10 11 12

iOS开发——实战技术OC篇&应用帮助界面简单实现

应用帮助界面简单实现 有的时候我们可能遇到一些关于应用中的技术或者信息不够明确,所以在使用应用的时候可能会遇到一些不知道所措的情况,比如关于一些难一点的游戏应用的操作,关于应用中一些比较隐藏的功能疑惑是操作完成后需要用户去根据需求做其他相应操作的的功能,所以这里我们就实现一个简单的帮组界面,也许跟实际开发中有一些区别,但是思路理解基本上就没有什么问题了. 我们知道平时帮助界面来说,可能是使用一个掩饰案例,可能是网络连接,也能是说明文档,这里我们就简单一点使用网页结合JSON数据来实现,网页实现也

iOS开发——实战技术OC篇&产品推荐界面的实现

产品推荐界面的实现 目前很多公司都仅仅只有一个项目,所以他们关于其他的项目肯定会做相应的推广,而在APp内部使用产品推荐实现APP的推广使一种很常见的现象,因为不需要什么成本,所以今天就简单介绍一下这么去搭建一个简单的产品推荐界面. 本章重点: 1:使用JSON数据:将JSON数据序列化,然后显示到界面上 2:根据设备是否安装对应的应用显示不同的信息,比如图片 3:根据设备是否安装对应的应用点击对应的按钮实现不同的功能 好了下面就来看看关于产品推荐界面是怎么去实现的! 1:JSON数据 2:对应

iOS开发——实战总结OC篇&网易彩票开发知识点总结

网易彩票开发知识点总结 关于网易彩票开发中遇到了不少的坑,弄了好久才弄懂,或者有些犹豫很久没用就不记得了,所以这里就总结了一下,希望以后不会忘记,就算忘记也能快速查看! /***************************************&.设置状态栏样式(白色) 两种方法******************************************/ 1 -(UIStatusBarStyle)preferredStatusBarStyle 2 3 { 4 5 if ([sel

iOS开发——高级技术OC篇&运行时(Runtime)机制

运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档. 下面就来看看什么是运行时,我们要怎么在iOS开发中去使用它. 官方介绍: 这里我们主要关注的是最后一种! 下面来看看Runtime的相关总结 #pragma mark 获取属性成员 /********************************************************

iOS开发——使用技术OC篇&剪切版的实现

剪切版的实现 在iOS中,可以使用剪贴板实现应用程序之中以及应用程序之间实现数据的共享.比如你可以从iPhone QQ复制一个url,然后粘贴到safari浏览器中查看这个链接的内容. 一.在iOS中下面三个控件,自身就有复制-粘贴的功能: 1.UITextView 2.UITextField 3.UIWebView 二.UIKit framework提供了几个类和协议方便我们在自己的应用程序中实现剪贴板的功能. 1.UIPasteboard:我们可以向其中写入数据,也可以读取数据 2.UIMe

iOS开发——使用技术OC篇&项目实战总结之开发技巧

项目实战总结之开发技巧 本文收集了25个关于可以提升程序性能的提示和技巧 1.使用ARC进行内存管理 2.在适当的情况下使用reuseIdentifier 3.尽可能将View设置为不透明(Opaque) 4.避免臃肿的XIBs 5.不要阻塞主线程 6.让图片的大小跟UIImageView一样 7.选择正确的集合 8.使用GZIP压缩 9.重用和延迟加载View 10.缓存.缓存.缓存 11.考虑绘制 12.处理内存警告 13.重用花销很大的对象 14.使用Sprite Sheets 15.避免

iOS开发——使用技术OC篇&保存(获取)图片到(自定义)相册

保存(获取)图片到(自定义)相册 最近在学 iOS相关技术(绘图篇实现画板功能)的时候设计到了两个常用的知识点,那就是保存图片到相册和葱相册中获取图片. 只是个人比较好奇拓展一些技术,说的难听点叫做装牛角尖,好听点就是为了装逼而已,所以在保存相册的时候使用真及测试发现不能保存到我iPhone里 main的自定义相册里面,就查看文档和资料,也借鉴别人的分享实现了想要的功能,就把他给记录下来,这个虽然没有直接保存和获取常用但是也是一项很好的实用技术. 一:首先来看看怎么获取相册的图片: 1 // 弹

iOS开发——使用技术OC篇&简单九宫格锁屏功能的实现与封装

简单九宫格锁屏功能的实现与封装 首先来看看最后的实现界面. 在这开始看下面的内容之前希望你能先大概思考活着回顾一下如果 你会怎么做,只要知道大概的思路就可以. 由于iphone5指纹解锁的实现是的这个功能呗淘汰,但是你可能会在想,都淘汰了你还在这里说个毛线啊,其实大家都知道,编程注重的思想,当然会了这个你不可能就会了指纹技术,哪还得等笔者在后面的学习中给大家分享,只是或许有一天这种功能或者思路在哪里要用到你不觉得是一件很开心的事情吗,而且如果你是不想自己敲的话直接可以拿来用. 好了不多废话直接上