上面提到一個朦朧遮罩的實現方式
接下來介紹另外一種實現,利用iOS7所提供的 UIVisualEffectView 來實現(自行百度一下這個類的介紹)
並且前提先要了解清楚:
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
hitTest這個方法結合UIWindow,經常來配合使用,比較多的場景有置頂操作,朦朧遮罩層的實現等等
最重要的功能是這個方法可以穿透視圖層,這樣你可以鎖定你要響應的對象,這裏記住這個話,以後大大有所用
一、定義UIWindow類,作爲響應罩面:
#import <UIKit/UIKit.h>
@interface OverheadView : UIWindow
@end
實現:
#import "OverheadView.h"
@implementation OverheadView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
id obj = [super hitTest:point withEvent:event];
if ([obj isKindOfClass:NSClassFromString(@"HyRoundMenuView")]) {
return obj;
}
return nil;
}
@end
稍微解釋一下:出現朦朧遮罩面時候,返回obj響應對象,否則,穿透該window層級(無視它)
二、定義遮罩層視圖
#import <UIKit/UIKit.h>
#import "HyRoundMenuModel.h"
typedef enum : NSUInteger
{
HyRoundMenuViewBackgroundViewTypeBlur NS_ENUM_AVAILABLE_IOS(9_0) = 0,
HyRoundMenuViewBackgroundViewTypeCustomColors = 1,
} HyRoundMenuViewBackgroundViewType;
@interface HyRoundMenuView : UIControl
@property (nonatomic, assign) UIBlurEffectStyle blurEffectStyle;
@property (nonatomic, nonnull, copy ) UIColor *customBackgroundViewColor;
@property (nonatomic, assign) HyRoundMenuViewBackgroundViewType backgroundViewType;
+ (__nonnull instancetype) shareInstance;
@end
#import "HyRoundMenuView.h"
#import "OverheadView.h"
#define IH_DEVICE_HEIGHT [[UIScreen mainScreen] bounds].size.height
#define IH_DEVICE_WIDTH [[UIScreen mainScreen] bounds].size.width
@interface HyRoundMenuView ()
@property (nonatomic, nonnull, strong) UIView *backgroundView;
@property (nonatomic, nonnull, strong) OverheadView *topView;
@end
@implementation HyRoundMenuView
static HyRoundMenuView* _instance = nil;
+(instancetype) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL] init] ;
}) ;
return _instance ;
}
- (instancetype) init
{
self = [super init];
if (self) { [self initUI]; }
return self;
}
- (void)initUI
{
self.frame = [UIScreen mainScreen].bounds;
self.backgroundColor = [UIColor clearColor];
self.userInteractionEnabled = true;
_blurEffectStyle = UIBlurEffectStyleLight;
_backgroundViewType = HyRoundMenuViewBackgroundViewTypeBlur;
//backgroundView
if (!_backgroundView) {
_backgroundView = [[UIVisualEffectView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_backgroundView.hidden = YES;
_backgroundView.backgroundColor = [UIColor clearColor];
((UIVisualEffectView *)_backgroundView).effect = nil;
}
[_backgroundView setFrame:self.bounds];
[self addSuperView];
}
- (void)addSuperView
{
_topView = [[OverheadView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_topView.backgroundColor = [UIColor colorWithWhite:1 alpha:0];
_topView.windowLevel = UIWindowLevelAlert;
_topView.hidden = NO;
_topView.alpha = 1;
[_topView makeKeyAndVisible];
UIViewController *vc = [UIViewController new];
_topView.rootViewController = vc;
[_topView addSubview:_backgroundView];
[_topView addSubview:self];
}
- (void)startBackgroundViewAnimationIsOpen:(BOOL)isMasking
{
if (isMasking)
{
((UIVisualEffectView *)_backgroundView).hidden = (_backgroundViewType == HyRoundMenuViewBackgroundViewTypeCustomColors);
[UIView animateWithDuration:0.3f animations:^{//customBackgroundViewColor
if (_backgroundViewType != HyRoundMenuViewBackgroundViewTypeCustomColors) ((UIVisualEffectView *)_backgroundView).effect = [UIBlurEffect effectWithStyle:_blurEffectStyle];
if (_backgroundViewType == HyRoundMenuViewBackgroundViewTypeCustomColors) self.backgroundColor = _customBackgroundViewColor;
}];
}
else
{
[UIView animateWithDuration:0.3f animations:^{
if (_backgroundViewType != HyRoundMenuViewBackgroundViewTypeCustomColors) ((UIVisualEffectView *)_backgroundView).effect = nil;
if (_backgroundViewType == HyRoundMenuViewBackgroundViewTypeCustomColors) self.backgroundColor = [UIColor clearColor];
} completion:^(BOOL finished) {
_backgroundView.hidden = _backgroundViewType == HyRoundMenuViewBackgroundViewTypeCustomColors;
}];
}
}
static BOOL isMasking = false;
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
isMasking = !isMasking;
[self startBackgroundViewAnimationIsOpen:isMasking];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
id obj = [super hitTest:point withEvent:event];
return obj;
}
@end
具體實現,也沒什麼好說的,千萬記得hitTest在這裏面的功用就行了,其實遮罩層的hitTest方法並沒有達到什麼作用,但是爲什麼保留呢?
因爲這個方法在“過濾”的效果非常好用,以後在別的需求會講到這個方法的作用
實現是轉載學習於:
https://github.com/wwdc14/HyRoundMenuView