2013-10-26 27 views
27

Utknąłem z problemem ustalania, jak wykryć UIView jest dotknięty i UIView jest dotknięty. Kiedy zostanie dotknięty, chcę, aby UIView zmienił kolor tła. Kiedy zostanie dotknięty, chciałbym, aby UIView wykonał pewne zadania. Chciałbym wiedzieć, jak jestem w stanie rozwiązać ten problem.Wykrywanie iOS stuknij i dotknij UIView

-(void)viewDidLoad 
{   
    UITapGestureRecognizer *dismissGestureRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDismissDoubleTap:)]; 
    dismissGestureRecognition.numberOfTapsRequired = 1; 
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureRecognition]; 

    UITapGestureRecognizer *dismissGestureDownRecognition = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissGestureDownRecognition:)]; 
    dismissGestureRecognition.numberOfTouchesRequired = 1; 
    [sectionDismissDoubleView addGestureRecognizer:dismissGestureDownRecognition]; 
} 

- (void)handleDismissDoubleTap:(UIGestureRecognizer*)tap { 
    SettingsDismissDoubleViewController *settingsDouble = [[SettingsDismissDoubleViewController alloc] initWithNibName:@"SettingsDismissDoubleViewController" bundle:nil]; 
    [self.navigationController pushViewController:settingsDouble animated:YES]; 
} 

- (void)dismissGestureDownRecognition:(UIGestureRecognizer*)tap { 
    NSLog(@"Down"); 
} 

Odpowiedz

34

geście Rozpoznawanie jest chyba przesadą, co chcesz. Prawdopodobnie chcesz użyć kombinacji -touchesBegan:withEvent: i -touchesEnded:withEvent:.

To jest wadliwe, ale powinno dać ci pojęcie o tym, co chcesz zrobić.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    self.touchDown = YES; 
    self.backgroundColor = [UIColor redColor]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    // Triggered when touch is released 
    if (self.isTouchDown) { 
     self.backgroundColor = [UIColor whiteColor]; 
     self.touchDown = NO; 
    } 
} 

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    // Triggered if touch leaves view 
    if (self.isTouchDown) { 
     self.backgroundColor = [UIColor whiteColor]; 
     self.touchDown = NO; 
    } 
} 

Kod ten powinien iść w niestandardowej podklasy UIView tworzonej. Następnie użyj tego niestandardowego typu widoku zamiast UIView, aby uzyskać obsługę dotykową.

1

Po pierwsze, przez selektor handleDismissDoubleTap:, bym zakładać szukasz podwójny kran o zwolnieniu. Aby to osiągnąć, należy robić: dismissGestureRecognition.numberOfTapsRequired = 2;

Po drugie, jeśli przez dotyk w dół na myśli przedłużoną kurek (lub „naciśnij i przytrzymaj”) rodzaj gestu, należy użyć UILongPressGestureRecognizer zamiast UITapGestureRecognizer.

6

W każdej podklasy UIControl (UIButton, etc), można użyć tego, aby zapisać się do określonego zestawu UIControlEvent:

addTarget:action:forControlEvents 

należy dodać cel z odpowiednim przełącznikiem na UIControlEventTouchDown i innym docelowym/selektora dla zdarzenia UIControlEventTouchUpInside .

UIControl reference

+4

pytanie dotyczy uiview nie uicontrol – trickster77777

0

Dzięki Holly's answer zbudowałem wygodną klasę ButtonView.

Edytuj: Ponieważ ten answer mówi, UILongPressGestureRecognizer reaguje dość szybko, więc zaktualizowałem swoją klasę.

Zastosowanie:

let btn = ButtonView() 
btn.onNormal = { btn.backgroundColor = .clearColor() } 
btn.onPressed = { btn.backgroundColor = .blueColor() } 
btn.onReleased = yourAction // Function to be called 

Klasa:

/** View that can be pressed like a button */ 

import UIKit 

class ButtonView : UIView { 

    /* Called when the view goes to normal state (set desired appearance) */ 
    var onNormal = {} 
    /* Called when the view goes to pressed state (set desired appearance) */ 
    var onPressed = {} 
    /* Called when the view is released (perform desired action) */ 
    var onReleased = {} 

    override init(frame: CGRect) 
    { 
     super.init(frame: frame) 

     let recognizer = UILongPressGestureRecognizer(target: self, action: Selector("touched:")) 
     recognizer.delegate = self 
     recognizer.minimumPressDuration = 0.0 
     addGestureRecognizer(recognizer) 
     userInteractionEnabled = true 

     onNormal() 
    } 

    func touched(sender: UILongPressGestureRecognizer) 
    { 
     if sender.state == .Began { 
      onPressed(self) 
     } else if sender.state == .Ended { 
      onNormal(self) 
      onReleased() 
     } 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 
+0

W końcu zmieniłem wersję na "UIControl", która nie reaguje tak szybko, ale ma inne zalety: możesz przeciągnąć "UIScrollView" poniżej, jeśli przeciągniesz po przycisku. W ten sposób widok przewijania nie utknie podczas próby przeciągnięcia, a gest przeciągania zaczyna się od miejsca, w którym znajduje się przycisk. http://stackoverflow.com/a/40740616/1121497 –

27

enter image description here

Metoda ta nie wymaga instacji czegokolwiek. Po prostu dodajesz do widoku UILongPressGestureRecognizer i ustawiasz zero na. Następnie sprawdzasz stan, w którym wywoływane są zdarzenia gestów, aby sprawdzić, czy zdarzenie dotykowe się rozpoczyna lub kończy.

Oto cały kod projektu dla przykładowego obrazu powyżej.

import UIKit 
class ViewController: UIViewController { 

    @IBOutlet weak var myView: UIView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Add "long" press gesture recognizer 
     let tap = UILongPressGestureRecognizer(target: self, action: #selector(tapHandler)) 
     tap.minimumPressDuration = 0 
     myView.addGestureRecognizer(tap) 
    } 

    // called by gesture recognizer 
    func tapHandler(gesture: UITapGestureRecognizer) { 

     // handle touch down and touch up events separately 
     if gesture.state == .Began { 
      myView.backgroundColor = UIColor.darkGrayColor() 
     } else if gesture.state == .Ended { 
      myView.backgroundColor = UIColor.lightGrayColor() 
     } 
    } 
} 

Dzięki this answer za pomysł.

+2

To zapobiegnie przewijaniu nadrzędnego przewijania przez przewijanie – xleon

+0

zdecydowanie najlepszą odpowiedzią (jak zwykle w przypadku Suragcha!) – Fattie