Uzun bir basma düğmesi taklit etmek istiyorum, bunu nasıl yapabilirim? Sanırım bir zamanlayıcıya ihtiyaç var. Anlıyorum UILongPressGestureRecognizer
ama bu türü nasıl kullanabilirim?
Yanıtlar:
Örneği oluşturup UILongPressGestureRecognizer
düğmeye ekleyerek başlayabilirsiniz .
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.button addGestureRecognizer:longPress];
[longPress release];
Ve sonra hareketi işleyen yöntemi uygulayın
- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
NSLog(@"Long Press");
}
}
Şimdi bu temel yaklaşım olacaktır. Ayrıca minimum baskı süresini ve ne kadar hatanın tolere edilebileceğini de ayarlayabilirsiniz. Ayrıca, hareketi tanıdıktan sonra yöntemin birkaç kez çağrıldığını ve sonunda bir şey yapmak istiyorsanız, durumunu kontrol etmeniz ve halletmeniz gerekeceğini unutmayın.
if(gesture.state == UIGestureRecognizerStateBegan)
, çünkü kullanıcı (Bitti) bıraktığında değil, hala bastığında (Başlayan durumu) bir şey olmasını bekler.
Kabul edilen cevaba alternatif olarak bu, Interface Builder kullanılarak Xcode'da çok kolay bir şekilde yapılabilir.
Sadece bir sürükle Uzun basın Gesture Tanıyıcı gelen Nesne Kitaplığı ve uzun basma eylemini istediğiniz düğmenin üstüne bırakın.
Daha sonra, yeni eklenen Uzun Basma Hareketi Tanıyıcıdan bir Eylemi , göndereni türünden seçerek görünüm denetleyicinize bağlayın UILongPressGestureRecognizer
. Bunun kodunda IBAction
, kabul edilen cevapta önerilen koda çok benzeyen şunu kullanın:
In Objective-C :
if ( sender.state == UIGestureRecognizerStateEnded ) {
// Do your stuff here
}
Veya Swift ile :
if sender.state == .Ended {
// Do your stuff here
}
Ama itiraf etmeliyim ki, denedikten sonra, @shengbinmeng tarafından yapılan öneriyi, kabul edilen cevaba bir yorum olarak tercih ediyorum.
In Objective-C :
if ( sender.state == UIGestureRecognizerStateBegan ) {
// Do your stuff here
}
Veya Swift ile :
if sender.state == .Began {
// Do your stuff here
}
Aradaki fark, Ended
parmağınızı kaldırdığınızda uzun basmanın etkisini görmenizdir. İle Began
, daha parmağınızı ekrandan kaldırmadan önce, uzun basma sistem tarafından yakalanır yakalanmaz uzun basmanın etkisini görürsünüz.
Muhtemelen çoğu kullanıcının doğal olarak bekleyeceği şey olduğu için kullanmak UIGestureRecognizerState.Began
yerine ek bir değişiklik yaptım .Ended
. İkisini de deneyin ve kendiniz görün.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// add gesture recognizer
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_:)))
self.button.addGestureRecognizer(longPress)
}
func longPress(gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began {
print("Long Press")
}
}
@IBAction func normalButtonTap(sender: UIButton) {
print("Button tapped")
}
}
Bunu dene:
viewDidLoad:
Aşağıdaki gibi düğme eklemek
-(void)viewDidLoad {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setTag:1]; //you can set any integer value as tag number
btn.title = @"Press Me";
[btn setFrame:CGRectMake(50.0, 50.0, 60.0, 60.0)];
// now create a long press gesture
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressTap:)];
[btn addGestureRecognizer:longPress];
}
Şimdi hareket yöntemini şöyle çağırın
-(void)longPressTap:(id)sender {
UIGestureRecognizer *recognizer = (UIGestureRecognizer*) sender
// Recogniser have all property of button on which you have clicked
// Now you can compare button's tag with recogniser's view.tag
// View frame for getting the info on which button the click event happened
// Then compare tag like this
if(recognizer.view.tag == 1) {
// Put your button's click code here
}
// And you can also compare the frame of your button with recogniser's view
CGRect btnRect = CGRectMake(50.0, 50.0, 60.0, 60.0);
if(recogniser.view.frame == btnRect) {
//put your button's click code here
}
// Remember frame comparing is alternative method you don't need to write frame comparing code if you are matching the tag number of button
}
recognizer.view.tag
bana tıklanan UIButton'un yanlış etiketini veriyor. Herhangi bir çözüm?
Sanırım benim çözümüme ihtiyacın var.
tek basış için bu koda sahip olmalısınız
- (IBAction)buttonDidPress:(id)sender {
NSLog("buttonDidPress");
}
ilk olarak, düğmeye uzun basma hareketi ekleyin
- (void)viewWillAppear:(BOOL)animated
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonDidLongPress:)];
[self.button addGestureRecognizer:longPress];
}
ardından uzun basma hareketi algılanırsa tek basma olayını tekrar tekrar çağırın.
- (void)buttonDidLongPress:(UILongPressGestureRecognizer*)gesture
{
switch (gesture.state) {
case UIGestureRecognizerStateBegan:
{
self.timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(buttonDidPress:) userInfo:nil repeats:YES];
NSRunLoop * theRunLoop = [NSRunLoop currentRunLoop];
[theRunLoop addTimer:self.timer forMode:NSDefaultRunLoopMode];
}
break;
case UIGestureRecognizerStateEnded:
{
[self.timer invalidate];
self.timer = nil;
}
break;
default:
break;
}
}
UIGestureRecognizer
sırasında viewWillAppear
olayını eklememelisiniz çünkü görünüm her göründüğünde başka bir hareket tanıyıcı eklenecektir. Bu, başlatma sırasında çağrılan özel bir yöntemde yapılmalıdır.
Swift 4 için, çalışması için "func longPress" in değiştirilmesi gerekir:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// add guesture recognizer
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_:)))
self.button.addGestureRecognizer(longPress)
}
@objc func longPress(_ guesture: UILongPressGestureRecognizer) {
if guesture.state == UIGestureRecognizerState.began {
print("Long Press")
}
}
@IBAction func normalButtonTap(sender: UIButton) {
print("Button tapped")
}
}
Hareket olmaksızın tek satırlık cevap:
[btn addTarget:self action:@selector(handleTouch:) forControlEvents:UIControlEventTouchDown | UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
Detaylar:
Bu üç olaylara hedef tetikler: 1- Hemen aşağı düğmesine parmak dokunuşları kez: UIControlEventTouchDown
. Bu, uzun basış başlangıcını yakalar. 2 & 3- Kullanıcı parmağını kaldırdığında: UIControlEventTouchUpOutside
& UIControlEventTouchUpInside
. Bu, kullanıcı basınının sonunu yakalar.
Not: Bu, hareket tanıyıcı tarafından sağlanan ekstra bilgi (ör. Dokunma konumu, vb.) Umurunuzda değilse işe yarar.
Gerekirse daha fazla ara etkinlik ekleyebilirsiniz, hepsini burada https://developer.apple.com/documentation/uikit/uicontrolevents?language=objc görün .
Storyboard'da: Düğmenizi yalnızca Storyboard'un seçtiği varsayılan (İçeride Rötuş Yap) değil, 3 etkinliğe bağlayın.
Uygulamam için alt sınıf bir UIButton'ım var, bu yüzden uygulamamı çıkardım. Bunu alt sınıfınıza ekleyebilirsiniz veya bu, bir UIButton kategorisi kadar kolay bir şekilde yeniden kodlanabilir.
Amacım, görünüm denetleyicilerimi tüm kodla karıştırmadan düğmeme uzun basmayı eklemekti. Hareket tanıma durumu başladığında eylemin çağrılması gerektiğine karar verdim.
Çözmeye hiç zahmet etmediğime dair bir uyarı geliyor. Olası bir sızıntı olduğunu söylüyor, kodu test ettiğimi ve sızıntı olmadığını düşündüm.
@interface MYLongButton ()
@property (nonatomic, strong) UILongPressGestureRecognizer *gestureRecognizer;
@property (nonatomic, strong) id gestureRecognizerTarget;
@property (nonatomic, assign) SEL gestureRecognizerSelector;
@end
@implementation MYLongButton
- (void)addLongPressTarget:(CGFloat)interval target:(id)target action:(SEL)selector
{
_gestureRecognizerTarget = target;
_gestureRecognizerSelector = selector;
_gestureRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongPressGestureRecognizer:)];
_gestureRecognizer.minimumPressDuration = interval;
[self addGestureRecognizer:_gestureRecognizer];
}
- (void)handleLongPressGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
NSAssert([_gestureRecognizerTarget respondsToSelector:_gestureRecognizerSelector], @"target does not respond to selector");
self.highlighted = NO;
// warning on possible leak -- can anybody fix it?
[_gestureRecognizerTarget performSelector:_gestureRecognizerSelector withObject:self];
}
}
Eylemi atamak için bu satırı viewDidLoad yönteminize ekleyin.
[_myLongButton addLongPressTarget:0.75 target:self selector:@selector(longPressAction:)];
Eylem, tüm IBActions gibi (IBAction olmadan) tanımlanmalıdır.
- (void)longPressAction:(id)sender {
// sender is the button
}
Yok dolayısıyla çalıştı ben de longpress kod yazarken çalıştı IBAction
gelen tıklama veya düğme storyboard
içinde Controller
yerine yazmaviewDidLoad
- (IBAction)btnClick:(id)sender {
tag = (int)((UIButton *)sender).tag;
// Long press here instead of in viewDidLoad
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
longPress.cancelsTouchesInView = NO;
[sender addGestureRecognizer:longPress];
}