UIButton PanGesture выходит за пределы экрана

Я создал небольшое тестовое приложение для применения жеста панорамирования к UIButton. Я успешно применил жест панорамирования и смог переместить кнопку. Но проблема в том, что я могу двигать кнопку даже за пределы экрана. Как привязать его к перемещению только на экране iPhone? Вот мой код:

    - (void)viewDidLoad
{
    [super viewDidLoad];

    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [panGesture setMinimumNumberOfTouches:1];
    [_shareButton addGestureRecognizer:panGesture];
}

-(IBAction)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint trans =[recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x+trans.x, recognizer.view.center.y+trans.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];


}

Как ограничить перемещение кнопки за пределы экрана? Я использую iOS 7, xcode 5.0.


person z22    schedule 25.01.2014    source источник


Ответы (5)


Попробуй это:

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[pan setDelegate:self];
[shareButton addGestureRecognizer:pan]; 

-(void)handlePan:(UIGestureRecognizer*)panGes{
    CGPoint point = [panGes locationInView:self.view];
    if (point.x >20 && point.x <280 && point.y<400 && point.y>30) {
        CGRect newframe = CGRectMake(point.x, point.y, shareButton.frame.size.width, shareButton.frame.size.height);
        shareButton.frame = newframe;
    }
}

и замените 20 280 и 400,30 соответствующими лимитами.

person Ajay    schedule 25.01.2014
comment
спасибо, я получил подсказку от этого, и я сделал то, что ответил. Спасибо - person z22; 25.01.2014

Это сработает для вас. Но я написал это на Swift:

func callMe(sender: UIPanGestureRecognizer)
{
    let translation = sender.translationInView(self.view)

    let newX = sender.view!.center.x + translation.x
    let newY = sender.view!.center.y + translation.y
    let senderWidth = sender.view!.bounds.width / 2
    let senderHight = sender.view!.bounds.height / 2

    if newX <= senderWidth
    {
        sender.view!.center = CGPoint(x: senderWidth, y: sender.view!.center.y + translation.y)
    }
    else if newX >= self.view.bounds.maxX - senderWidth
    {
        sender.view!.center = CGPoint(x: self.view.bounds.maxX - senderWidth, y: sender.view!.center.y + translation.y)
    }
    if newY <= senderHight
    {
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: senderHight)
    }
    else if newY >= self.view.bounds.maxY - senderHight
    {
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: self.view.bounds.maxY - senderHight)
    }
    else
    {
        sender.view!.center = CGPoint(x: sender.view!.center.x + translation.x, y: sender.view!.center.y + translation.y)
    }

    sender.setTranslation(CGPointZero, inView: self.view)
}

Я надеюсь, что это поможет любому, кто ищет самый простой способ сделать это.

person Soufian Hossam    schedule 19.10.2016

Отредактируйте свой код следующим образом:

-(IBAction)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint trans =[recognizer translationInView:self.view];
        if (CGRectContainsPoint([self.view frame], trans)) 
        {
            recognizer.view.center = trans;
        }
}

Здесь то, что вы делаете, это независимо от того, лежит ли точка в кадре обзора или нет. Если это. вы перемещаете центр перетаскиваемой кнопки .. дайте мне знать, если это не решит вашу проблему.

Обновление 2:

Вместо реализации PanGesture вы также можете использовать событие onDrag:

- (IBAction)onButtonDrag:(id)sender forEvent:(UIEvent *)event {

    CGPoint point = [[[event allTouches] anyObject] locationInView:sender.view];
    UIControl *control = sender;
    if (CGRectContainsPoint([self.view frame], point)) {
        control.center = point;
        [self.view touchesEnded:[event allTouches] withEvent:event];
    }

}
person Prince Agrawal    schedule 25.01.2014
comment
добавил это, все то же самое. Кнопка выходит за пределы экрана - person z22; 25.01.2014
comment
@z22 предложил альтернативное решение - person Prince Agrawal; 25.01.2014

Понятно. Кодируется следующим образом:

    -(IBAction)pan:(UIPanGestureRecognizer *)recognizer
{
    CGPoint trans =[recognizer translationInView:self.view];
    CGFloat sumx = _shareButton.frame.origin.x+_shareButton.frame.size.width+5;
        CGFloat sumy = _shareButton.frame.origin.y+_shareButton.frame.size.height+5;

    CGFloat sumxm = _shareButton.frame.origin.x;
    CGFloat sumym = _shareButton.frame.origin.y;

    NSLog(@"position : %f, %f ", _shareButton.frame.origin.x, _shareButton.frame.origin.y);
    NSLog(@"screen : %f, %f ", self.view.frame.size.width ,self.view.frame.size.height);


    if (sumx > self.view.frame.size.width ||  sumy > self.view.frame.size.height )
    {
        CGRect shareButton = _shareButton.frame;
        shareButton.origin.y -= 1;
                shareButton.origin.x -= 1;
        _shareButton.frame = shareButton;

        return;
    }

    else if(sumxm < 0 || sumym < 0) {
        CGRect shareButton = _shareButton.frame;
        if(sumxm < 0)
        {
        shareButton.origin.x =0;
        }
        if(sumym < 0){
        shareButton.origin.y =0;
        }
        _shareButton.frame = shareButton;
        NSLog(@"share button : %f, %f", _shareButton.frame.origin.x, _shareButton.frame.origin.y);
        return;
    }

           recognizer.view.center = CGPointMake(recognizer.view.center.x+trans.x, recognizer.view.center.y+trans.y);

           [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];




}
person z22    schedule 25.01.2014

Связанный предел вашей рамки жеста. Это просто размер окна. Ширина и высота.

Ниже приведен учебник по жестам. Я знаю, что это для игр, но найдите свою логику в этом туториале.

http://www.raywenderlich.com/2343/cocos2d-tutorial-for-ios-how-to-drag-and-drop-sprites

Отключение жеста панорамирования при обнаружении выхода за границы< /сильный>

- (CGPoint)boundLayerPos:(CGPoint)newPos {
    CGSize winSize = [CCDirector sharedDirector].winSize;
    CGPoint retval = newPos;
    retval.x = MIN(retval.x, 0);
    retval.x = MAX(self.position.x); 
    retval.y = self.position.y;
    return retval;
}
person Renish Dadhaniya    schedule 25.01.2014
comment
stackoverflow.com/questions/13881006/ также подсказка - person Renish Dadhaniya; 25.01.2014