iOS开发基础55-利用 UIWindow 实现快速滚动到界面顶部
1.iOS开发基础1-第一个iOS程序2.iOS开发基础2-基础控件3.iOS开发基础6-懒加载、Plist 文件操作、字典转模型、自定义 View 详解4.iOS开发基础5-UIButton5.iOS开发基础4-图像资源6.iOS开发基础3-UIImage7.iOS开发基础14-KVC的应用与底层逻辑8.iOS开发基础13-深入理解 UITableView(二)9.iOS开发基础12-深入理解UITableView(一)10.iOS开发基础11-屏幕适配、Autolayout及 Masonry 框架11.iOS开发基础10-UIButton内边距和图片拉伸模式12.iOS开发基础9-提示框(UIAlertController)13.iOS开发基础8-UIScrollView14.iOS开发基础7-自定义构造方法、layoutSubviews、Xib文件与自定义View15.iOS开发基础30-UITabBarController16.iOS开发基础29-触摸事件及手势识别17.iOS开发基础28-数据存储与沙盒机制18.iOS开发基础27-导航控制器入栈与出栈机制及微博个人详情页19.iOS开发基础26-空20.iOS开发基础25-ARC和MRC深入探析21.iOS开发基础24-UIPickerView、UITextField、KVC、UIDatePicker、控制器及导航控制器22.iOS开发基础23-iOS开发中的Info.plist、UIApplication及其Delegate、UIWindow详解23.iOS开发基础22-键盘通知在iOS开发中的应用24.iOS开发基础21-深入理解通知、代理、KVO和Block在iOS开发中的应用25.iOS开发基础20-UITableView的全局及局部刷新、左滑操作与批量删除26.iOS开发基础19-深入理解和实现不等高的 UITableViewCell27.iOS开发基础18-深入理解 Objective-C Runtime 机制28.iOS开发基础16-使用 `NSTimer` 时避免内存泄露的技巧和最佳实践29.iOS开发基础15-KVO的应用与底层逻辑30.iOS开发基础65-iPad 开发指南31.iOS开发基础64-二维码32.iOS开发基础63-AVFoundation/MediaPlayer33.iOS开发基础62-音频播放34.iOS开发基础61-通讯录35.iOS开发基础60-传感器36.iOS开发基础59-内存优化37.iOS开发基础58-支付宝集成指南38.iOS开发基础57-换肤功能与静态库开发指南39.iOS开发基础56-UIDynamic物理引擎
40.iOS开发基础55-利用 UIWindow 实现快速滚动到界面顶部
41.iOS开发基础54-CoreLocation42.iOS开发基础53-MapKit 框架43.iOS开发基础47-iOS键盘44.iOS开发基础46-数据安全与HTTPS保护详解45.iOS开发基础45-UIWebview46.iOS开发基础44-网络编程之NSURLSession&AFN47.iOS开发基础43-CocoaPods48.iOS开发基础42-网络编程之文件下载与处理49.iOS开发基础41-网络编程之JSON和XML50.iOS开发基础40-网络编程之NSURLConnection51.iOS开发基础39-RunLoop52.iOS开发基础38-多线程之多图片下载及缓存处理53.iOS开发基础37-多线程之NSOperation54.iOS开发基础36-多线程之GCD55.iOS开发基础35-多线程之NSThread56.iOS开发基础34-多线程57.iOS开发基础33-核心动画(二)58.iOS开发基础33-核心动画(一)59.iOS开发基础32-Quartz2D(二)60.iOS开发基础32-Quartz2D(一)61.iOS开发基础31-Modal 与 Push 详解62.iOS开发基础76-iOS 开发中的属性修饰符详解63.iOS开发基础75-iOS开发中的Block深度解析64.iOS开发基础74-Swift他来了65.iOS开发基础73-24种性能优化技巧66.iOS开发基础72-Xcode 7 升级后的问题与解决方案详解67.iOS开发基础71-应用中的 StatusBar 详解68.iOS开发基础70-TCP与UDP69.iOS开发基础69-应用开发中的 Controller 间通信模式70.iOS开发基础68-图片轮播71.iOS开发基础67-流水布局相册缩放72.iOS开发基础66-UISearchBar 控件指南73.iOS开发基础78-iOS 国际化在现代应用中,用户体验是我们关注的重点之一,为了提升用户的使用体验,我们可以在状态栏添加一个看不见(透明)的 UIWindow
并附加一个按钮,实现点击按钮时快速滚动到当前界面的顶部。这篇文章将详细介绍如何利用 UIWindow
实现该功能,并封装成一个工具类供外部使用。
一、UIWindow 的基本介绍
在 iOS 中,UIWindow
是用于管理和协调应用程序的主要可视内容的对象,并且 UIWindow
可以设置多个层级,层级越高,显示的位置越上面。
- UIWindowLevel:
UIWindowLevelNormal
:普通窗口层次。UIWindowLevelStatusBar
:状态栏窗口层次。UIWindowLevelAlert
:警告窗口层次,该层级最高。
二、用 UIWindow 实现滚动到顶部功能
1. 创建一个新的 UIWindow
首先,我们需要创建一个新的窗口,并设置它的层级为最高的 UIWindowLevelAlert
。将这个窗口添加到状态栏位置并设置为透明,同时设置一个点击事件:
@interface AppDelegate ()
@property (nonatomic, strong) UIWindow *topWindow;
@end
@implementation AppDelegate
- (UIWindow *)topWindow {
if (_topWindow == nil) {
_topWindow = [[UIWindow alloc] init];
_topWindow.windowLevel = UIWindowLevelAlert;
_topWindow.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 20);
_topWindow.backgroundColor = [UIColor clearColor];
// 默认是隐藏的,要显示必须手动设置为NO
_topWindow.hidden = NO;
// 添加点击事件
[_topWindow addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(topWindowClick)]];
}
return _topWindow;
}
2. 遍历每一个窗口
当用户点击状态栏上的透明窗口时,触发点击事件,遍历所有窗口:
- (void)topWindowClick {
NSArray *windows = [UIApplication sharedApplication].windows;
for (UIWindow *window in windows) {
[self searchSubviews:window];
}
}
3. 遍历窗口下的所有子控件
递归遍历每个窗口的子控件,找到 UIScrollView
类的控件,判断其是否在窗口上(是否相交),如果在则滚动到顶部:
- (void)searchSubviews:(UIView *)superview {
for (UIView *subview in superview.subviews) {
[self searchSubviews:subview];
if (![subview isKindOfClass:[UIScrollView class]]) continue;
UIScrollView *scrollView = (UIScrollView *)subview;
CGRect scrollViewRect = [scrollView convertRect:scrollView.bounds toView:scrollView.window];
CGRect windowRect = scrollView.window.bounds;
if (!CGRectIntersectsRect(scrollViewRect, windowRect)) continue;
CGPoint offset = scrollView.contentOffset;
offset.y = -scrollView.contentInset.top;
[scrollView setContentOffset:offset animated:YES];
}
}
4. 程序激活时主动调用懒加载
为了确保窗口在应用激活时能够显示,我们需要在 applicationDidBecomeActive
方法中调用懒加载:
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self topWindow];
}
三、封装工具类供外部使用
为了方便在项目中多次使用,可以将上述实现封装成一个工具类。
@interface TopWindowHelper : NSObject
+ (void)setupTopWindow;
@end
@implementation TopWindowHelper
static UIWindow *topWindow;
+ (void)initialize {
[self setupTopWindow];
}
+ (void)setupTopWindow {
if (topWindow == nil) {
topWindow = [[UIWindow alloc] init];
topWindow.windowLevel = UIWindowLevelAlert;
topWindow.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 20);
topWindow.backgroundColor = [UIColor clearColor];
topWindow.hidden = NO;
[topWindow addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(topWindowClick)]];
}
}
+ (void)topWindowClick {
NSArray *windows = [UIApplication sharedApplication].windows;
for (UIWindow *window in windows) {
[self searchSubviews:window];
}
}
+ (void)searchSubviews:(UIView *)superview {
for (UIView *subview in superview.subviews) {
[self searchSubviews:subview];
if (![subview isKindOfClass:[UIScrollView class]]) continue;
UIScrollView *scrollView = (UIScrollView *)subview;
CGRect scrollViewRect = [scrollView convertRect:scrollView.bounds toView:scrollView.window];
CGRect windowRect = scrollView.window.bounds;
if (!CGRectIntersectsRect(scrollViewRect, windowRect)) continue;
CGPoint offset = scrollView.contentOffset;
offset.y = -scrollView.contentInset.top;
[scrollView setContentOffset:offset animated:YES];
}
}
@end
在 AppDelegate 中调用工具类,以确保窗口在应用激活时能够显示:
- (void)applicationDidBecomeActive:(UIApplication *)application {
[TopWindowHelper setupTopWindow];
}
结语
通过利用 UIWindow
和 UIScrollView
的结合,我们可以轻松实现点击状态栏快速滚动到页面顶部的功能。这个功能在用户体验上有很大的提升,非常适合在新闻类、社交类等应用中使用。封装成工具类后,可以方便地在项目中多次调用,促进代码的重用。
将来的你会感谢今天如此努力的你!
版权声明:本文为博主原创文章,未经博主允许不得转载。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!