How can you move from using one UIButton to another while still holding your finger?

Imagine your keyboard. Imagine placing one finger down on one key, then (holding), moving your finger to the other key on the keyboard. Now imagine each key on the keyboard UIButton. when you hold your finger on the current key, this key ( UIButton) is highlighted. Then, when the user moves to another key, the first key is no longer highlighted, and the current key that is pressed is highlighted.

Now I have a 6 x 8 UIButtons grid each 53 x 53 pixels. So I have 48 UIButtons. I want to reproduce this idea. The button on which the user's finger is turned on will have an image that is slightly lighter (to look similar), and all the others will be slightly lighter.

Here is my idea how to do this,

1) Create all 48 UIButtonsin viewDidLoad. Add a lighter image in UIControlStateHighlightedfor everyone UIButtons.

2) Add a kind of targetfor touchUpOutside, which somehow makes the current button unlit and unusable. (maybe for selected ones and userInteractionEnablednot). But then how can I say the next button to be used? And how can I say that I want a particular UIButtonone so that the fingers of users are underneath to be highlighted and used to detect gestures and more.

Also, this method touchUpOutsidemay not work because all buttons are next to each other, and I think you need to go a long way to launch this one touchUpOutside.

, . UIImage, UIButton. , - - .

+5
2

:

  • , touchUp....

  • , , subviews, ? , , ( isKindOfClass). (, , , , - .) , , .

, , , (, , ), , , CGPoint ? >

CGPoint location = [sender locationInView:self.view];

for (UIView *subview in self.view.subviews)
{
    if (CGRectContainsPoint(subview.frame, location))
    {
        // do your appropriate highlighting

        if ([subview isKindOfClass:[UIButton class]])
        {
            // something for buttons
        }
        else if ([subview isKindOfClass:[UIImageView class]])
        {
            // something for imageviews
        }

        return;
    }
}

, - , , . , , .

, , , , ( , , , ), :

@interface SubviewGestureRecognizer : UIGestureRecognizer

@property (nonatomic,strong) UIView *firstSubview;
@property (nonatomic,strong) UIView *currentSubview;

@end

@implementation SubviewGestureRecognizer

- (id) initWithTarget:(id)target action:(SEL)action
{
    self = [super initWithTarget:target action:action];
    if (self)
    {
        self.firstSubview = nil;
        self.currentSubview = nil;
    }

    return self;
}

// you might want to tweak this `identifySubview` to only look 
// for buttons and imageviews, or items with nonzero tag properties, 
// or recursively navigate if it encounters container UIViews 
// or whatever suits your app

- (UIView *)identifySubview:(NSSet *)touches
{
    CGPoint location = [[touches anyObject] locationInView:self.view];

    for (UIView *subview in self.view.subviews)
    {
        if (CGRectContainsPoint(subview.frame, location))
        {
            return subview;
        }
    }

    return nil;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];

    if ([touches count] != 1)
    {
        self.state = UIGestureRecognizerStateFailed;
        return;
    }

    self.firstSubview = [self identifySubview:touches];
    self.currentSubview = self.firstSubview;

    if (self.firstSubview == nil)
        self.state = UIGestureRecognizerStateFailed;
    else
        self.state = UIGestureRecognizerStateBegan;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    if (self.state == UIGestureRecognizerStateFailed) return;

    self.currentSubview = [self identifySubview:touches];

    self.state = UIGestureRecognizerStateChanged;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];

    self.currentSubview = [self identifySubview:touches];

    if (self.currentSubview != nil)
        self.state = UIGestureRecognizerStateEnded;
    else
        self.state = UIGestureRecognizerStateFailed;
}

- (void)reset
{
    [super reset];

    self.firstSubview = nil;
    self.currentSubview = nil;
}

viewDidLoad:

SubviewGestureRecognizer *recognizer = [[SubviewGestureRecognizer alloc] initWithTarget:self action:@selector(handleTouches:)];
[self.view addGestureRecognizer:recognizer];

( , , setHighlighted):

- (void)handleTouches:(SubviewGestureRecognizer *)sender
{
    static UIControl *previousControl = nil;

    if (sender.state == UIGestureRecognizerStateBegan || sender.state == UIGestureRecognizerStateChanged)
    {
        if (sender.state == UIGestureRecognizerStateBegan)
            previousControl = nil;

        UIView *subview = sender.currentSubview;
        if (previousControl != subview)
        {
            // reset the old one (if any)

            [previousControl setHighlighted:NO];

            // highlight the new one

            previousControl = (UIControl *)subview;
            [previousControl setHighlighted:YES];
        }
    }
    else if (sender.state == UIGestureRecognizerStateEnded)
    {
        if (previousControl)
        {
            [previousControl setHighlighted:NO];
            NSLog(@"successfully touchdown on %@ and touchup on %@", sender.firstSubview, sender.currentSubview);
        }
    }
    else if (sender.state == UIGestureRecognizerStateCancelled || sender.state == UIGestureRecognizerStateFailed)
    {
        [previousControl setHighlighted:NO];
        NSLog(@"cancelled/failed gesture");
    }
}
+4

. , ( ). UIViewController, UIView UIGestureRecognizer.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    //get the touch object
    UITouch *myTouch = [touches anyObject];

    //get the location of the touch
    CGPoint *myPoint = [myTouch locationInView:self.view];

    //detect if the touch is in one of your buttons
    if ( CGRectContainsPoint(myButton.frame, myPoint){
        /*do whatever needs to be done when the button is pressed
        repeat the CGRectContainsPoint for all buttons,
        perhaps using a while or for loop to look through an array?*/
    }

}

, , :

touchesMoved:withEvent ,

touchesEnded:withEvent ,

touchesCancelled:withEvent: , - , ,

0

All Articles