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.
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
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);
}