UIView ішінен UIView ішінде жылжыту (UIPanGestureRecognizer)

UIView ішіндегі UIImageView элементін жылжыту үшін келесі кодты пайдаланамын.

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {

CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                     recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];

}

Мен UIView ата-ана көрінісінен тыс қозғалмайтындай етіп жасағым келеді. Минутта сурет көрінісі бүкіл экранда жылжи алады.

12

8 жауаптар

Алдымен UIImageView жаңа жақтауын алыңыз және CGRectContainsRect() әдісін қолданып, өзінің толық көрінісінде екенін тексеріңіз. Егер иә болса, жаңа кодқа UImageView's кадрын орнатыңыз.

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {

    CGPoint translation = [recognizer translationInView:self.view];
    CGRect recognizerFrame = recognizer.view.frame;
    recognizerFrame.origin.x += translation.x;
    recognizerFrame.origin.y += translation.y; 

   //Check if UIImageView is completely inside its superView
    if (CGRectContainsRect(self.view.bounds, recognizerFrame)) {
        recognizer.view.frame = recognizerFrame;
    }
   //Else check if UIImageView is vertically and/or horizontally outside of its
   //superView. If yes, then set UImageView's frame accordingly.
   //This is required so that when user pans rapidly then it provides smooth translation.
    else {
       //Check vertically
        if (recognizerFrame.origin.y < self.view.bounds.origin.y) {
            recognizerFrame.origin.y = 0;
        }        
        else if (recognizerFrame.origin.y + recognizerFrame.size.height > self.view.bounds.size.height) {
            recognizerFrame.origin.y = self.view.bounds.size.height - recognizerFrame.size.height;
        }

       //Check horizantally
        if (recognizerFrame.origin.x < self.view.bounds.origin.x) {
            recognizerFrame.origin.x = 0;
        }
        else if (recognizerFrame.origin.x + recognizerFrame.size.width > self.view.bounds.size.width) {
            recognizerFrame.origin.x = self.view.bounds.size.width - recognizerFrame.size.width;
        }
    }

   //Reset translation so that on next pan recognition
   //we get correct translation value
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}

CGRects екеуі де бірдей координат жүйесінде болу үшін UIImageView суперView және frame bounds өтуіңізге көз жеткізіңіз.

11
қосылды
@micantox Мен сіздердің кейбір сұрақтарыңызбен келісемін және менің жауапымды жаңарттым. СуперView үшін, мен self.view болып табылады imageView суперView біледі, өйткені ол өзін өзі суперView өз кодында пайдаланды.
қосылды автор Geek, көзі
@IconicDigital Менің барлық жаңартылған жауаптарымды барлық жағдайларда дұрыс аудару әсері болуы үшін қараңыз.
қосылды автор Geek, көзі
@ReidBelton recognizer.view.frame пайдалану керек. Неліктен ол қозғалмайды деп «себебі сіз өзіңіздің құндылығын мүлде өзгертпесіз» немесе «Сіз апарғыңыз келмегеннен басқа көзқарасты өзгертсеңіз» болуы мүмкін.
қосылды автор Geek, көзі
Мен жоғалтқаныма сенімді емеспін, бірақ UIPanGestureRecognizer-мен отыратын жерімнен «кадр» сипаты жоқ ... сондықтан recognizeizer.frame жұмыс істемейді. Танератор.view.frame-ні пайдалана аламын, бірақ танымал файлға танымал файлды таниушы.view.frame-ні тану, ештеңе істемейді, себебі мен дәл сол мәнді өзіме тапсырамын. Мен төменде әртүрлі әдісті қолдандым, ол маған жақсы жұмыс істейді, бірақ әлі күнге дейін бұл туралы қызықтырады. Егер біреу кеңес берсе, оны бағалаймын, рахмет.
қосылды автор Reid Belton, көзі
Барлық жақсы және жақсы, қоспағанда: танылмайтын файлдың танымалығы - self.view және егер пайдаланушы шындығында шекараның сыртында шынымен жылдам болса, онда сіз танктердің ортасында мұздатудың шірік әсерін аласыз шолу шектерінің. Соңында, егер бұл пайдаланушы панорамалауды жалғастыра берсе, көрініс пайдаланушы саусағының астында қалмай, айналдырады. Тұтастай алғанда сіз жақсы жұмыс істей аласыз.
қосылды автор micantox, көзі

Келесі әрекеттерді орындап көріңіз:

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer 
{
    if (gesture.state==UIGestureRecognizerStateChanged || gesture.state == UIGestureRecognizerStateEnded){
        UIView *superview = recognizer.view.superview;
        CGSize superviewSize = superview.bounds.size;
        CGSize thisSize = recognizer.view.size;
        CGPoint translation = [recognizer translationInView:self.view];
        CGPoint center = CGPointMake(recognizer.view.center.x + translation.x,
                                 recognizer.view.center.y + translation.y);

        CGPoint resetTranslation = CGPointMake(translation.x, translation.y);

        if(center.x - thisSize.width/2 < 0)
            center.x = thisSize.width/2;
        else if (center.x + thisSize.width/2 > superviewSize.width)
            center.x = superviewSize.width-thisSize.width/2;
        else
            resetTranslation.x = 0; //Only reset the horizontal translation if the view *did* translate horizontally

        if(center.y - thisSize.height/2 < 0)
            center.y = thisSize.height/2;
        else if(center.y + thisSize.height/2 > superviewSize.height)
            center.y = superviewSize.height-thisSize.height/2;
        else
            resetTranslation.y = 0; //Only reset the vertical translation if the view *did* translate vertically

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

Осылайша, ол ата-аналық көзқарас шеңберінен шығып кетпейді және оны шекарасынан жылжытуға тырыссаңыз, ол тек «шегелейді»!

8
қосылды
шеберліктер сияқты жұмыс істейді! Рақмет сізге
қосылды автор MBH, көзі

Келесі әрекеттерді орындап көріңіз:

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer 
{
    if (gesture.state==UIGestureRecognizerStateChanged || gesture.state == UIGestureRecognizerStateEnded){
        UIView *superview = recognizer.view.superview;
        CGSize superviewSize = superview.bounds.size;
        CGSize thisSize = recognizer.view.size;
        CGPoint translation = [recognizer translationInView:self.view];
        CGPoint center = CGPointMake(recognizer.view.center.x + translation.x,
                                 recognizer.view.center.y + translation.y);

        CGPoint resetTranslation = CGPointMake(translation.x, translation.y);

        if(center.x - thisSize.width/2 < 0)
            center.x = thisSize.width/2;
        else if (center.x + thisSize.width/2 > superviewSize.width)
            center.x = superviewSize.width-thisSize.width/2;
        else
            resetTranslation.x = 0; //Only reset the horizontal translation if the view *did* translate horizontally

        if(center.y - thisSize.height/2 < 0)
            center.y = thisSize.height/2;
        else if(center.y + thisSize.height/2 > superviewSize.height)
            center.y = superviewSize.height-thisSize.height/2;
        else
            resetTranslation.y = 0; //Only reset the vertical translation if the view *did* translate vertically

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

Осылайша, ол ата-аналық көзқарас шеңберінен шығып кетпейді және оны шекарасынан жылжытуға тырыссаңыз, ол тек «шегелейді»!

8
қосылды
шеберліктер сияқты жұмыс істейді! Рақмет сізге
қосылды автор MBH, көзі

recognizer.view.center параметрін оның ата-аналық көрінісінің жиектері ішінде болған жағдайда ғана жаңа мәнге орнатуға тура келеді. recognizer.view.superview.bounds және recognizer.view.frame ішінде CGRectContainsRect сөзін пайдаланыңыз.

Егер сурет көрінісінің ата-ана көрінісінен тыс жылжуға рұқсат бергіңіз келсе, көріністің орталық нүктесі ата-ана шекарасынан тыс болғанша UIView convertPoint: toView әдісін қолдануға болады > және жаңа CGPoint ата-ана шегінен тыс екенін тексеріңіз.

1
қосылды

recognizer.view.center параметрін оның ата-аналық көрінісінің жиектері ішінде болған жағдайда ғана жаңа мәнге орнатуға тура келеді. recognizer.view.superview.bounds және recognizer.view.frame ішінде CGRectContainsRect сөзін пайдаланыңыз.

Егер сурет көрінісінің ата-ана көрінісінен тыс жылжуға рұқсат бергіңіз келсе, көріністің орталық нүктесі ата-ана шекарасынан тыс болғанша UIView convertPoint: toView әдісін қолдануға болады > және жаңа CGPoint ата-ана шегінен тыс екенін тексеріңіз.

1
қосылды

Микронокс жауаптарының жылдам нұсқасы

let gesture = UIPanGestureRecognizer(target: self, action: #selector(self.wasDragged(gestureRecognizer:)))
imageView.addGestureRecognizer(gesture)
imageView.isUserInteractionEnabled = true

@objc func wasDragged(gestureRecognizer: UIPanGestureRecognizer) {
if gestureRecognizer.state == UIGestureRecognizerState.changed || gestureRecognizer.state == UIGestureRecognizerState.ended {
   let superview = gestureRecognizer.view?.superview
   let superviewSize = superview?.bounds.size
   let thisSize = gestureRecognizer.view?.frame.size
   let translation = gestureRecognizer.translation(in: self.view)
   var center = CGPoint(x: gestureRecognizer.view!.center.x + translation.x, y: gestureRecognizer.view!.center.y + translation.y)
   var resetTranslation = CGPoint(x: translation.x, y: translation.y)

   if center.x - (thisSize?.width)!/2 < 0 {
       center.x = (thisSize?.width)!/2
       } else if center.x + (thisSize?.width)!/2 > (superviewSize?.width)! {
       center.x = (superviewSize?.width)!-(thisSize?.width)!/2
       } else {
         resetTranslation.x = 0 //Only reset the horizontal translation if the view *did* translate horizontally
       }

   if center.y - (thisSize?.height)!/2 < 0 {
       center.y = (thisSize?.height)!/2
      } else if center.y + (thisSize?.height)!/2 > (superviewSize?.height)! {
       center.y = (superviewSize?.height)!-(thisSize?.height)!/2
      } else {
        resetTranslation.y = 0 //Only reset the vertical translation if the view *did* translate vertically
      }

      gestureRecognizer.view?.center = center
      gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    } 
}
0
қосылды
if (gesture.state==UIGestureRecognizerStateChanged){

CGPoint translation = [recognizer translationInView:self.view];

CGRect rectToCheck=CGRectMake(yourView.frame.origin.x+translation.x,       yourView.frame.origin.y+translation.y, CGRectGetWidth(yourView.frame),     CGRectGetHeight(yourView.frame));

     if(CGRectContainsRect(self.view.bounds,rectToCheck))// check that the rect that is   going to form lies within the bounds of self.view
     {

     yourView.frame=CGRectMake(yourView.frame.origin.x+translation.x,  yourView.frame.origin.y+translation.y, CGRectGetWidth(yourView.frame),  CGRectGetHeight(yourView.frame)); 
     }
     [gesture setTranslation:CGPointZero yourView];//important to set this 

 }

P.S. Қимыл-қозғалыс күйі блогын бастау, алып тастау, алып тастау үшін пайдаланыңыз. яғни UIGestureRecognizerStateBegan UIGestureRecognizerStateChanged UIGestureRecognizerStateEnded

0
қосылды
if (gesture.state==UIGestureRecognizerStateChanged){

CGPoint translation = [recognizer translationInView:self.view];

CGRect rectToCheck=CGRectMake(yourView.frame.origin.x+translation.x,       yourView.frame.origin.y+translation.y, CGRectGetWidth(yourView.frame),     CGRectGetHeight(yourView.frame));

     if(CGRectContainsRect(self.view.bounds,rectToCheck))// check that the rect that is   going to form lies within the bounds of self.view
     {

     yourView.frame=CGRectMake(yourView.frame.origin.x+translation.x,  yourView.frame.origin.y+translation.y, CGRectGetWidth(yourView.frame),  CGRectGetHeight(yourView.frame)); 
     }
     [gesture setTranslation:CGPointZero yourView];//important to set this 

 }

P.S. Қимыл-қозғалыс күйі блогын бастау, алып тастау, алып тастау үшін пайдаланыңыз. яғни UIGestureRecognizerStateBegan UIGestureRecognizerStateChanged UIGestureRecognizerStateEnded

0
қосылды