问题
I want to create custom navigation bar like WhatsApp uses to display call indicator in the application as given below.
I have successfully added view like above but it's not responsive because I am not able to detect touch on status bar. I can touch only part below "Touch to return to call".
Code is as given below.
@property (nonatomic) UIView *navigationBarTopView;
UIWindow *window = [UIApplication sharedApplication].keyWindow;
if (_navigationBarTopView == nil) {
_navigationBarTopView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, window.frame.size.width, 60.0)];
[_navigationBarTopView setBackgroundColor:[UIColor colorWithRed:76.0/255.0 green:217.0/255.0 blue:100.0/255.0 alpha:1]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, _navigationBarTopView.frame.size.height - 15, window.frame.size.width, 10)];
[label setText:@"Touch to return to call"];
[label setTextColor:[UIColor whiteColor]];
[label setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]];
[label setTextAlignment:NSTextAlignmentCenter];
[_navigationBarTopView addSubview:label];
//The setup code (in viewDidLoad in your view controller)
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[_navigationBarTopView addGestureRecognizer:singleFingerTap];
UITapGestureRecognizer *singleFingerTap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[label addGestureRecognizer:singleFingerTap1];
}
[window addSubview:_navigationBarTopView];
I have also tried to add touch on status bar as give below but it doesn't work.
How do I detect touches on UIStatusBar/iPhone
Also navigation bar is not coming downside. I have tried to set keyWindow
frame. But that is also not working.
回答1:
UIStatusBar has higher priority than your application's window, so you won't get any touch event through status bar.
To get touch event through status bar you need a window with higher window level than UIStatusBar.
Try below code:
#import "AppDelegate.h"
@interface AppDelegate ()
@property (nonatomic) UIWindow *buttonWindow;
@property (nonatomic) UIWindow *textWindow;
@property (nonatomic) CGFloat callViewHeight;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if (@available(iOS 11.0, *)) {
if (([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top > 20.0)) {
self.callViewHeight = 55.0f;
} else {
self.callViewHeight = 35.0f;
}
} else {
self.callViewHeight = 35.0f;
}
return YES;
}
-(void)showVideoCallButton{
self.textWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.callViewHeight)];
self.textWindow.windowLevel = self.window.windowLevel + 1;
self.textWindow.hidden = FALSE;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.callViewHeight)];
view.backgroundColor = [UIColor colorWithRed:76.0/255.0 green:217.0/255.0 blue:100.0/255.0 alpha:1];
view.clipsToBounds = TRUE;
UILabel *lblName = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.callViewHeight)];
lblName.textAlignment = NSTextAlignmentCenter;
[lblName setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]];
lblName.text = @"";
UILabel *lblTouch = [[UILabel alloc] initWithFrame:CGRectMake(0, self.callViewHeight - 20.0f, [UIScreen mainScreen].bounds.size.width, 20.0f)];
lblTouch.textAlignment = NSTextAlignmentCenter;
[lblTouch setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]];
lblTouch.text = @"Touch to return to call";
lblTouch.textColor = UIColor.whiteColor;
[view addSubview:lblTouch];
[view addSubview:lblName];
[self.textWindow addSubview:view];
self.buttonWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.callViewHeight)];
self.buttonWindow.windowLevel = UIWindowLevelStatusBar + 1;
self.buttonWindow.hidden = FALSE;
UIButton *button = [[UIButton alloc] initWithFrame:lblName.bounds];
[button setTitle:@"" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonTouched) forControlEvents:UIControlEventTouchUpInside];
[self.buttonWindow addSubview:button];
self.textWindow.transform = CGAffineTransformMakeTranslation(0, -self.callViewHeight);
self.buttonWindow.transform = CGAffineTransformMakeTranslation(0, -self.callViewHeight);
[UIView animateWithDuration:0.25
animations:^{
self.textWindow.transform = CGAffineTransformIdentity;
self.buttonWindow.transform = CGAffineTransformIdentity;
if (@available(iOS 11.0, *)) {
if (([[[UIApplication sharedApplication] delegate] window].safeAreaInsets.top > 20.0)) {
self.window.frame = CGRectMake(0, self.callViewHeight - 40.0f, self.window.bounds.size.width, self.window.bounds.size.height - self.callViewHeight + 40.0f);
} else {
self.window.frame = CGRectMake(0, self.callViewHeight - 20.0f, self.window.bounds.size.width, self.window.bounds.size.height - self.callViewHeight + 20.0f);
}
} else {
self.window.frame = CGRectMake(0, self.callViewHeight - 20.0f, self.window.bounds.size.width, self.window.bounds.size.height - self.callViewHeight + 20.0f);
}
}];
}
-(void)hideVideoCallButton{
[UIView animateWithDuration:0.25
animations:^{
self.textWindow.transform = CGAffineTransformMakeTranslation(0, -self.callViewHeight);
self.buttonWindow.transform = CGAffineTransformMakeTranslation(0, -self.callViewHeight);
self.window.frame = [UIScreen mainScreen].bounds;
} completion:^(BOOL finished) {
dispatch_async(dispatch_get_main_queue(), ^{
self.buttonWindow.hidden = TRUE;
self.buttonWindow = nil;
self.textWindow.hidden = TRUE;
self.textWindow = nil;
});
}];
}
-(void)buttonTouched{
NSLog(@"Button Touched");
}
@end
回答2:
I tried in singleViewcontroller and UITabbar Controller also, the sample project I attached here, for status bar Tap action I followed Flar answer
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[self createDummyView];
});
}
-(void)createDummyView{
if (_navigationBarTopView == nil) {
float statusBarHeight = [self statusBarHeight];
CGFloat width = [UIScreen mainScreen].bounds.size.width;
_navigationBarTopView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, self.navigationController.navigationBar.frame.size.height + statusBarHeight)];
[_navigationBarTopView setBackgroundColor:[UIColor colorWithRed:76.0/255.0 green:217.0/255.0 blue:100.0/255.0 alpha:1]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, _navigationBarTopView.frame.size.height - 15,width, 10)];
[label setText:@"Touch to return to call"];
[label setTextColor:[UIColor whiteColor]];
[label setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setUserInteractionEnabled:YES];
[_navigationBarTopView addSubview:label];
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[_navigationBarTopView addGestureRecognizer:singleFingerTap];
[self.navigationController.view addSubview:_navigationBarTopView];
}
-(float) statusBarHeight
{
CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
return MIN(statusBarSize.width, statusBarSize.height);
}
-(void)handleSingleTap:(UITapGestureRecognizer*)recognizer{
NSLog(@"recognizer == %@", recognizer.view.tag);
}
来源:https://stackoverflow.com/questions/55336527/add-customview-in-navigation-bar-like-whatsapp