Как отключить мультитач?

Мое приложение имеет несколько кнопок, которые запускают различные события. Пользователь НЕ должен иметь возможность удерживать несколько кнопок. Во всяком случае, нажатие нескольких кнопок приводит к сбою приложения.

И вот, я пытаюсь отключить мультитач в своем приложении.

Я не проверял "Multiple Touch" во всех xib-файлах, и, насколько я могу понять, свойства 'множественный_прикосновение \'; и "exclusiveTouch" контролировать, использует ли представление мультитач. Поэтому в моем приложении DidFinishLaunching я поместил это:

self.mainViewController.view.multipleTouchEnabled=NO;
self.mainViewController.view.exclusiveTouch =YES;

И в каждом из моих контроллеров представления я помещаю это в viewDidLoad

self.view.multipleTouchEnabled=NO;
self.view.exclusiveTouch=YES;

Тем не менее, этоstill принимает несколько касаний. Я мог бы сделать что-то вроде отключения других кнопок после получения события касания, но это было бы уродливым хаком. Наверняка есть способ правильно отключить мультитач?

Ответы на вопрос(18)

Для отключения глобального мультитача вXamarin.iOS

Скопируйте и вставьте код ниже:

[DllImport(ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
internal extern static IntPtr IntPtr_objc_msgSend(IntPtr receiver, IntPtr selector, bool isExclusiveTouch);
static void SetExclusiveTouch(bool isExclusiveTouch)
{
    var selector = new ObjCRuntime.Selector("setExclusiveTouch:");
    IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, isExclusiveTouch);
}

И установите его на AppDelegate:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    ...
    SetExclusiveTouch(true); // setting exlusive to true disables the multitouch
    ...
}

Если вы хотите отключить мультитач во всем приложении и не хотите писать код для каждой кнопки, вы можете просто использоватьAppearance кнопки. Напишите ниже строку вdidFinishLaunchingWithOptions.

UIButton.appearance().isExclusiveTouch = true

Замечательно!!UIAppearance

Вы даже можете использовать его для любого изUIView класс, так что если вы хотите отключить мультитач для нескольких кнопок. Сделайте CustomClass из кнопки, а затем

CustomButton.appearance().isExclusiveTouch = true

Есть еще одно преимущество, которое может вам помочь. В случае, если вы хотите отключить мультитач кнопок в конкретномViewController

UIButton.appearance(whenContainedInInstancesOf: [ViewController2.self]).isExclusiveTouch = true

Довольно просто, вы можете использовать сделать использование свойства ExclusiveTouch в этом случае

[youBtn setExclusiveTouch:YES];

Это логическое значение, которое указывает, обрабатывает ли получатель исключительно события касания.

Если для этого свойства задано значение YES, получатель блокирует доставку сенсорных событий другим представлениям в том же окне. Значение по умолчанию этого свойства - НЕТ.

Я сталкивался с некоторыми странными случаями при перетаскивании объектов вокруг вида, когда при касании другого объекта одновременно запускается метод touchesBegan. Мой обходной путь заключался в том, чтобы отключить взаимодействие с пользователем для родительского представления до тех пор, пока не будет вызвано touchesEnded или touchesCancelled.

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
   // whatever setup you need
   self.view.userInteractionEnabled = false 
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
   // whatever setup you need
   self.view.userInteractionEnabled = true
}

override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
   // whatever setup you need
   self.view.userInteractionEnabled = true
}

Чтобы отключить мультитач в SWIFT:

Сначала вам нужно иметь розетку для каждой кнопки, а затем просто установить эксклюзивное прикосновение на true. Поэтому в васviewDidLoad() будет иметь:

yourButton.exclusiveTouch = true.

// не обязательно, но вы также можете добавить:

self.view.multipleTouchEnabled = false

Просто установите все соответствующие свойства UIView exclusiveTouch в false, чтобы сделать свое дело.

Об этом часто сообщают наши тестеры. Один из подходов, который я иногда использую, хотя и должен использоваться сознательно, заключается в создании категории дляUIView, как этот:

@implementation UIView (ExclusiveTouch)

- (BOOL)isExclusiveTouch
{
    return YES;
}

Я решил эту проблему следующим образом:

NSTimeInterval intervalButtonPressed;

- (IBAction)buttonPicturePressed:(id)sender{ 

    if (([[NSDate date] timeIntervalSince1970] - intervalButtonPressed) > 0.1f) {
        intervalButtonPressed = [[NSDate date] timeIntervalSince1970];
        //your code for button
    }
}
- (void)viewDidLoad {
    [super viewDidLoad];

    for(UIView* v in self.view.subviews)
    {
        if([v isKindOfClass:[UIButton class]])
        {
            UIButton* btn = (UIButton*)v;
            [btn setExclusiveTouch:YES];
        }
    }
}

Этот код протестирован и работает отлично для меня. Нет сбоя приложения при нажатии более одной кнопки за раз.

Отключить все кнопки в представлении в"Touch Down" событие и включить их в"Touch Up Inside" событие.

например

- (void) handleTouchDown {
    for (UIButton *btn in views) {
        btn.enable = NO;
    }
}

- (void) handleTouchUpInside {
    for (UIButton *btn in views) {
        btn.enable = Yes;
    }
    ------
    ------
}

Основываясь на ответе neoevoke, только немного улучшив его, чтобы он также проверял подпредставления ' Дети, я создал эту функцию и добавил ее в свой файл утилит:

// Set exclusive touch to all children

+ (void)setExclusiveTouchToChildrenOf:(NSArray *)subviews
{
    for (UIView *v in subviews) {
        [self setExclusiveTouchToChildrenOf:v.subviews];
        if ([v isKindOfClass:[UIButton class]]) {
            UIButton *btn = (UIButton *)v;
            [btn setExclusiveTouch:YES];
        }
    }
}

Затем простой вызов:

[Utils setExclusiveTouchToChildrenOf:self.view.subviews];

... сделает свое дело.

Если вы хотите отключить мультитач программным способом или если вы используете cocos2d (без опции multipTouchEnabled), вы можете использовать следующий код в вашем делегате ccTouches:

- (BOOL)ccTouchesBegan:(NSSet *)touches
 withEvent:(UIEvent *)event {
       NSSet *multiTouch = [event allTouches];
       if( [multiTouch count] > 1) { 
            return; 
       }
       else {
           //else your rest of the code  
}

Я создал расширение класса UIView и добавил эти две функции. и когда я хочу отключить сенсорный просмотр, я просто вызываю [view makeExclusiveTouch];

- (void) makeExclusiveTouchForViews:(NSArray*)views {
    for (UIView * view in views) {
        [view makeExclusiveTouch];
    }
}

- (void) makeExclusiveTouch {
    self.multipleTouchEnabled = NO;
    self.exclusiveTouch = YES;
    [self makeExclusiveTouchForViews:self.subviews];
}
- (void)viewDidLoad {
    [super viewDidLoad];

    for(UIView* v in self.view.subviews)
    {
        if([v isKindOfClass:[UIButton class]])
        {
            UIButton* btn = (UIButton*)v;
            [btn setExclusiveTouch:YES];
        }
    }
}

У меня как раз была именно эта проблема.

Решение, которое мы нашли, состояло в том, чтобы просто унаследовать новый класс от UIButton, который переопределяет метод initWithCoder, и использовать его там, где нам нужно было одно нажатие кнопки за раз (т. Е. Везде):

@implementation ExclusiveButton

(id)initWithCoder: (NSCoder*)decoder 
{ 
   [self setExclusiveTouch:YES]; 
   return [super initWithCoder:decoder]
}

@end

Обратите внимание, что это работает только с кнопками, загруженными из файлов пера.

Решение Вопроса

Если вы хотите, чтобы только одна кнопка реагировала на прикосновения за раз, вам нужно установить для этой кнопки значение exclusiveTouch, а не для родительского представления. В качестве альтернативы вы можете отключить другие кнопки, когда кнопка получает значок «Touch Down». событие.


Вот пример последнего, который работал лучше в моем тестировании. Настройка exclusiveTouch для кнопок вроде бы работала, но приводила к некоторым интересным проблемам, когда вы убирали палец с края кнопки, а не просто нажимали на нее.

Вы должны иметь розетки в вашем контроллере, подключенные к каждой кнопке, и иметь «Touch Down», «Touch Up Inside» и «Touch Up Outside» события подключены к соответствующим методам в вашем контроллере.

#import "multibuttonsViewController.h"

@implementation multibuttonsViewController

// hook this up to "Touch Down" for each button
- (IBAction) pressed: (id) sender
{
    if (sender == one)
    {
        two.enabled = false;
        three.enabled = false;
        [label setText: @"One"]; // or whatever you want to do
    }
    else if (sender == two)
    {
        one.enabled = false;
        three.enabled = false;
        [label setText: @"Two"];  // or whatever you want to do
    }
    else
    {
        one.enabled = false;
        two.enabled = false;
        [label setText: @"Three"];  // or whatever you want to do
    }
}

// hook this up to "Touch Up Inside" and "Touch Up Outside"
- (IBAction) released: (id) sender
{
    one.enabled = true;
    two.enabled = true;
    three.enabled = true;
}

@end

Ваше приложение падает по причине. Расследуйте дальше, используйте отладчик, посмотрите, что не так, вместо того, чтобы пытаться скрыть ошибку.

Редактировать:

Хорошо, хорошо, я должен признать, что был немного резок. Вы должны установить свойство exclusiveTouch наeach button, Вот и все. Свойство multipTouchEnabled не имеет значения.

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

Прежде всего, вы абсолютно уверены, что мультитач включен? Можно генерировать отдельные касания в последовательности довольно быстро. Мультитач больше о том, что вы делаете с двумя или более пальцами, когда они находятся на поверхности. Возможно, вы нажали одну кнопку, но неправильно справляетесь с тем, что происходит, если две кнопки нажимаются практически одновременно.

Ваш ответ на вопрос