問題
開發(fā)中可能會遇到這樣的問題:使一個View在屏幕中不被任何視圖遮蓋?
如果遇到類似的問題泄伪,這篇文章及示例可能對你有所啟發(fā)蹬屹。
效果圖
superview.gif
實現(xiàn)
UIWindow了解
要想實現(xiàn)這樣的效果缚态,首先要明白知道UIWindow以及一個應(yīng)用如何通過UIWindow顯示到屏幕扮碧。這里有一篇文章的講的很詳細趟章。
關(guān)于UIWindow,這里講兩點:
UIWindow是一個特殊的UIView,一個app至少要有一個UIWindow,不論是UIView還是UIViewController,最終還是要通過UIWindow將視圖繪制到屏幕上慎王,才能顯示蚓土。
-
UIWindow 有分層級(windowLevel),層級越高柬祠,顯示在屏幕最上方北戏。層級相同時负芋,后面調(diào)用的UIWindow顯示在上方漫蛔。官方提供了三個常用層級:
- UIWindowLevelNormal ---> 0
- UIWindowLevelAlert ---> 2000
- UIWindowLevelStatusBar ---> 1000
鍵盤所在的UIRemoteKeyboardWindow 層級是10000000。
SuperView的實現(xiàn)原理
- 創(chuàng)建一個獨立的UIWindow, 尺寸和SuperView一樣旧蛾。調(diào)用window 的
makeKeyAndVisible
方法莽龟。別忘了調(diào)整superView在window 的frame。
- (void)show {
UIWindow *currentKeyWindow = [UIApplication sharedApplication].keyWindow;
NSLog(@"super view frame: %@", NSStringFromCGRect(self.frame));
if (!_superviewWindow) {
_superviewWindow = [[BQSuperViewWindow alloc] initWithFrame:_currentFrame];
_superviewWindow.rootViewController = [ BQSuperViewController new];
} else {
_superviewWindow.frame = _currentFrame;
}
[_superviewWindow makeKeyAndVisible];
self.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
self.layer.cornerRadius = self.frame.size.width <= self.frame.size.height ? self.frame.size.width / 2.0 : self.frame.size.height / 2.0;
[_superviewWindow addSubview:self];
// keep the original keyWindow to avoid some unpredictable problems
[currentKeyWindow makeKeyWindow];
}
要顯示在屏幕最上方锨天,窗口的windowLevel要夠大毯盈。
- 添加拖動手勢,根據(jù)拖動位置更新window的frame病袄。
至于多動的邊界控制其實挺簡單搂赋,詳細代碼后面有鏈接赘阀。
[UIView animateWithDuration:.25 animations:^{
_superviewWindow.center = newCenter;
//
if (_superviewWindow.hidden == YES) {
self.center = newCenter;
}
// record frame for superview back to superviewWindow
_currentFrame = _superviewWindow.frame;
}];
- 添加鍵盤彈出和隱藏的通知,
鍵盤顯示時脑奠,隱藏獨立的window基公。然后將superView在屏幕中的frame換算到UIRemoteKeyboardWindow中顯示。
鍵盤隱藏時宋欺,重新顯示獨立的window轰豆,根據(jù)superView(frame可能變化)的最新frame設(shè)置window的位置并顯示。
- (void)keyboardIsShown:(NSNotification *)note {
[self convertSuperViewToKeyboardWindow];
}
- (void)keyboardDidHide {
[self show];
}
- (void)convertSuperViewToKeyboardWindow {
//hide the superViewWindow
[self hide];
// add superView in keyboardWindow
self.frame = _currentFrame;
[[self keyboardWindow] addSubview:self];
}
最后的最后
1.完整的實現(xiàn)代碼在這里齿诞!
2.如果有更好的實現(xiàn)酸休,可以給在評論區(qū)留言〉昏荆或者在github上提出斑司,我會及時跟進。
3.別忘了點贊哈但汞!別忘了點贊哈陡厘!別忘了點贊哈!