motionBegan not being called in whole application
-
24-10-2019 - |
Question
Hi all I have an app where I allow the user to post something on their pinwall of facebook. I used the DemoApp directly from Facebook to set it up.
I have implemented a shake detection that does something when the user shakes the device. However, since those two functions are in the same viewcontroller, both of them dont work anymore.
- When Facebook pops the login window, the keyboard doesn't appear anymore.
- Shakes are not detected anymore.
I suppose it has something to do with the first responders. I have tried a lot of things but I was not able to solve it. Here is the neccessary part of my code.
Post something on facebook pinwall:
- (IBAction)publishStream{
FactsAppDelegate *appDelegate = (FactsAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableDictionary *dictionary = [[[NSMutableDictionary alloc] init]autorelease];
[dictionary setObject:@"Du postest diesen Fact:" forKey:@"user_message_prompt"];
[dictionary setObject:[[appDelegate.facts objectAtIndex:currentFactId] fact] forKey:@"message"];
[_facebook dialog:@"feed" andParams:dictionary andDelegate:self];
}
Shake detection:
#pragma mark Motion catching
// shake motion began
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (motion != UIEventSubtypeMotionShake) return;
// load next fact
[self next];
// vibrate
[self vibrate];
}
Method needed for shake detection:
#pragma mark Shake events are only detectable by the first responder
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self resignFirstResponder];
}
Can anyone tell me what I have to change to get both (facebook, shake) working? Thanks a lot, doonot
Solution 3
Thanks to XJones I was finally able to fix my problem.
@XJones, I was reducing my app to the default functions and found out why I was not able to catch motions and why I had problems with the facebook keyboard.
My MainWindow.xib file was totally wrong and delegate was not set either. I deleted the xib file, mapped delegate and window and that's it, I can now catch motions and even facebook posting works like a charm :)
Thanks a lot for taking care and offering your help!!
OTHER TIPS
I created a simple view based project in XCode and the following works for me. I didn't add Facebook to the mix but the UITextField should simulate it. What this does is:
Touching the UIButton or shaking the device will toggle editing of the UITextField including showing/hiding the keyboard
The UILabel
statusLabel
will display the last touch or shake action and then timeout to display the default text.
You can create a similar project and copy/paste this in or try to work with your existing app.
EDITED TO ADD .H FILE
Header:
// ShakeShakeShakeViewController.h
#import <UIKit/UIKit.h>
@interface ShakeShakeShakeViewController : UIViewController {
UITextField * _textField;
UILabel * _statusLabel;
UIButton * _actionButton;
}
@property (nonatomic, retain) IBOutlet UITextField * textField;
@property (nonatomic, retain) IBOutlet UILabel * statusLabel;
@property (nonatomic, retain) IBOutlet UIButton * actionButton;
- (IBAction)userInvokedActionWithControl:(id)sender;
- (void)resetStatusLabel;
- (void)toggleTextFieldEditing;
@end
Source:
// ShakeShakeShakeViewController.m
#import "ShakeShakeShakeViewController.h"
@implementation ShakeShakeShakeViewController
@synthesize textField = _textField,
statusLabel = _statusLabel,
actionButton = _actionButton;
- (void)dealloc
{
self.textField = nil;
self.statusLabel = nil;
self.actionButton = nil;
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[self resetStatusLabel];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.textField = nil;
self.statusLabel = nil;
self.actionButton = nil;
}
- (void)viewDidAppear:(BOOL)animated
{
[self becomeFirstResponder];
}
- (IBAction)userInvokedActionWithControl:(id)sender
{
NSLog(@"Touched");
self.statusLabel.text = @"Touched";
[self toggleTextFieldEditing];
}
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (motion != UIEventSubtypeMotionShake) return;
NSLog(@"Shaking...");
self.statusLabel.text = @"Shaking...";
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
if (motion != UIEventSubtypeMotionShake) return;
NSLog(@"Done shaking...");
self.statusLabel.text = @"Done shaking";
[self toggleTextFieldEditing];
}
- (void)toggleTextFieldEditing
{
if ([self.textField isFirstResponder]) {
[self becomeFirstResponder];
}
else {
[self.textField becomeFirstResponder];
}
[self performSelector:@selector(resetStatusLabel) withObject:nil afterDelay:2];
}
- (void)resetStatusLabel
{
self.statusLabel.text = @"Shake me";
}
@end
Try to insert [self becomeFirstResponder] in viewDidAppear
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
Here the documentation