Accessing the Status Bar - ios

So, I'd like to receive touches from the status bar anywhere, any view, from the app. Well actually only specific views, like home screens and root view controllers say from a view of a tab view controller.
So my goal is to: hold down the status bar to dismiss the current view, like a back button.
The reason why I'm using this approach as a back button is because the app I am making is a utility, like fully functional apps within one app. Therefore I do not want to use up space on the navbar item to display a back button.
Other fissures would be nice, like swipe left/right or double tap, but mostly holding down. I've seen alternatives like using a UIScrollView and use the - scrollsToTop method. Hmm not what I am looking for.

Hope this can help you.
When you tap the top area, which has 44 height, the event would be triggered.
- (void)viewDidLoad{
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(navigationBack:)];
[self.view addGestureRecognizer:tapGesture];
}
- (void)navigationBack:(UITapGestureRecognizer *)tapGesture {
CGPoint p = [tapGesture locationInView:self.view];
if (CGRectContainsPoint(CGRectMake(0, 0, self.view.frame.size.width, 44), p)) {
NSLog(#"this where you put you navigation back event");
}
}

Related

Xcode iOS UIView with tap gesture allowing input on subviews

So I have a homepage view that people see when they first boot up the app, it has several different options. Yesterday I added a tutorial overlay, so the first time they open the app I have a view that is 0.5 alpha black and is fullscreen over the other view, this view has white text and arrows pointing to functions on the page. I attached a tap gesture recognizer to this view and its action is to call the next tutorial screen ( 3 in total). Afterwords they all are hidden and the app acts as normal. This all works, except even though my view is full screen, with User Interaction Enabled checked and a gesture tap recognizer, the gestures / touches on the sub view still work. So if I just tap some white space on the app the tutorial and tap gesture work as expected, cycle me through the pages etc and works. However if I accidentally press a sub view button or do a gesture from the subview it will do the action (take you to a new page or w/e)
So basically as far as I can tell my view despite being on top of the other and having a tap gesture recognizer attached to the view the sub views are still getting pressed, any ideas?
Check the tap event view before doing any operation..
- (IBAction)yourTapEvent:(UITapGestureRecognizer *)gestureRecognizer
{
UIView *piece = [gestureRecognizer view];
if(piece == (view on which you have added gesture))
{
//Do your necessary operation
}
}
try this it would help you to disable gesture on its subviews
- (void)tapAction:(UITapGestureRecognizer *) gestureRecognizer{
UIView *v = [gestureRecognizer view];// Guesture added view
NSArray *temp = [self.view subviews];
for (int i = 0; i<temp.count; i++) {
if([temp objectAtIndex:i]== v){
// Do your swipe tap action here
}
}
}

PanGestureRecognizer fails to fire on UIScrollView when SWRevealController is being used

I am using the SWRevealViewController project by John Lluch for my application and I have run into one minor issue that I can't seem to get straight.
I am using the SWRevealViewController to access my apps options menu from anywhere in my app just by swiping to the right and the main view slides to reveal the menu behind it.
This is handled by a swipe gesture recognizer that is added to the main view. To improve UX, I create a button to cover the main view when it gets swiped out of the way so all the user has to do to close the menu is tap the small part of the view that is showing or grab the view and pull it back.
It works great except on one of my views in which the majority of the view is a UIScrollView. To get it to work I have to add the gesture recognizer to the UIScrollView as well as the super view. But for some reason, once the view is swiped out of the way, the swipe gesture recognizer stops responding. But this only happen on the view where the majority of the screen is a scroll view thus, what the user grabs to pull the screen back is the scroll view.
Hopefully that was understandable. Any light that you guys can shine on this will be very helpful.
-(void)viewDidAppear:(BOOL)animated {
// so the user can tap the button to show the menu
[menuButton addTarget:self.revealViewController action:#selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
// so the user can swipe to show the menu
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
// so the user can swipe the scrollview to show the menu
[mainScrollView addGestureRecognizer:self.revealViewController.panGestureRecognizer];
self.revealViewController.delegate = self;
}
- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position {
if (position == FrontViewPositionRight) {
//create the button so the use can tap to close the menu
returnButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[returnButton addTarget:self.revealViewController action:#selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:returnButton];
} else {
[returnButton removeFromSuperview];
returnButton = nil;
}
}
So I just discovered that this issue has already been addressed within the SWRevealViewController Project. This post pointed me in the right direction. They have added a tap gesture recognizer that has the behaviour I was creating with the dynamically created button.
Adding
[self.view addGestureRecognizer:self.revealViewController.tapGestureRecognizer];
removes the need for the button, thus allowing the view to respond to both recognizers.

I've hidden the navigation bar and the status bar, now the screen edge pan gesture to go back won't work, is this typical?

I'm curious, if I set the navigationBar to hidden, and also hide the status bar, my view controller no longer responds to the screen edge gesture to pop the view controller.
Is this expected behaviour? I tried to set the interactivePopGestureRecognizer to enabled in viewDidLoad after I hide the navigation bar, but it still won't work.
[self.navigationController.navigationBar setHidden:YES];<--doesn't remove pop gesture
[self.navigationController setNavigationBarHidden:YES];<-- disables pop gesture
Simply use the first option, and in your root controller's viewDidAppear method use:
[self.navigationController.navigationBar setHidden:NO];
Are you sure you've done things right? I've put together an example that seems to work for me. All I did was make the navigationController.navigationBar.hidden = YES and [[UIApplication sharedApplication] setStatusBarHidden:YES]
-edit-
After closer inspection, it looks like there are two different properties on UINavigationController. There is navigationBar which is the UINavigationBar view, and there is navigationBarHidden which is a boolean. When you set navigationBarHidden to true, the swipe gesture stops working. But if you set that actual view to be hidden with navigationBar.hidden then the gesture still works. Check the Git repository for an example.
A very simple work around:
Link a swipe gesture method to your navigation back button. Make the current view controller the target of the gesture recognizer (self), with the selector popThisViewController. Then install the gesture recognizer into the view that the user will swipe on. Don't forget to add your go back action
edit added swipe gesture for reference to other coders that don't know
Cleaner code will look like this:
UISwipeGestureRecognizer *gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(goBack:)];
gesture.numberOfTouchesRequired = 1;
gesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeRight];
}
-(IBAction)goBack:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}

Disabling UIGestureRecognizers in underlying ViewController

In a View Controller I'm building a grid of icons.
Each icon opens the same pop-up view , but filled in with different information.
I'm creating the grid in this way:
for (int i=0; i<NUM_BADGES; i++) {
BadgeThumbView *thumb = [[BadgeThumbView alloc] initWithFrame:CGRectMake(posX, posY, 70, 100)
andWithLabel:[NSString stringWithFormat:#"BADGE NAME N. %d", i]];
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onBadgeTapped:)];
[thumb addGestureRecognizer:gestureRecognizer];
[thumb setTag:i];
[more code here....]
}
And in onBadgeTapped method I'm creating the pop up.
Now my problem is that everything works fine, but I just realized that when the pop up is opened, while interacting with its buttons I'm still triggering the gesture recognizer in the underlying view controller.
Is there a way to disable all GestureRecognizers in underlying view? Is my strategy wrong? And: is there a way to use a single UIGestureRecognizer for all my icons, in order to disable/enable in a easier way?
Thanks a lot
You can remove the recognizer from view or set userInteractionEnabled to temporarily disable it. Depending on how your popup is implemented, you may be able to disable them all at once.
One solution would to be adding thumbs as a subview of a container UIView, and adding that container to your parent view. You could then enable/disable all by setting userInteractionEnabled on the container view.
I think you should do some thing like disabling the userInteraction for all thumb views when the popup is appearing and re-enabling when disappearing like this
[[yourSuperView subviews]makeObjectsPerformSelector:#selector(setUserInteractionEnabled:) withObject:[NSNumber numberWithBool:FALSE]];
Else add all thumbViews to one subview( say 'b') then add view 'b' to superview(say 'a') as subView and turn off the user interaction to view b when popup appeared and turn on when popup disappears

UITapGestureRecognizer Recognize taps on main view (not inputs or buttons)

I would like to get notified when a user clicks any part of the background of my UIView; basically if the user clicks outside of any control that is on my UIView (tables, textfields, buttons, etc).
How do I go about it? I tried doing this:
if ([touch.view isKindOf:[UIView class]]) {
do something....
}
But, obviously all controls extend UIView... so, I'm a bit stuck.
You should be able to do the following:
backgroundView.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapHit:)] autorelease];
[backgroundView addGestureRecognizer:tap];
-(void) tapHit:(UITapGestureRecognizer *tap) {
NSLog( #"background tapped" );
}
One way you could do this is add a separate background view that is a child of your VC's main view. You can simply make it transparent so it doesn't interfere with your styling. Place is in the behind all the other children views. Then register your GR on that view.

Resources