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

Was it helpful?

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:

  1. Touching the UIButton or shaking the device will toggle editing of the UITextField including showing/hiding the keyboard

  2. 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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top