Вопрос

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

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

Я снял флажок "Множественное касание" во всех файлах xib, и, насколько я могу понять, свойства "multipleTouchEnabled" и "exclusiveTouch" определяют, использует ли представление мультитач.Итак, в моем applicationDidFinishLaunching я поместил это:

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

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

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

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

Это было полезно?

Решение

Если вы хотите, чтобы одновременно на касания реагировала только одна кнопка, вам нужно установить 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

Другие советы

- (void)viewDidLoad {
    [super viewDidLoad];

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

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

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

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

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

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

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

// 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];

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

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

@implementation UIView (ExclusiveTouch)

- (BOOL)isExclusiveTouch
{
    return YES;
}

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

UIButton.appearance().isExclusiveTouch = true

Это здорово!! Внешний вид UI

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

CustomButton.appearance().isExclusiveTouch = true

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

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

Как отключить мультитач в SWIFT:

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

yourButton.exclusiveTouch = true.

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

self.view.multipleTouchEnabled = false

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

[youBtn setExclusiveTouch:YES];

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

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

Для отключения глобального мультитач в 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
    ...
}

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

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

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

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

@implementation ExclusiveButton

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

@end

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

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

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

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

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

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

Отключите все кнопки просмотра в "Приземление" событие и включите их в "Подкрасить изнутри" событие.

например

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

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

Я решил эту проблему таким образом:

NSTimeInterval intervalButtonPressed;

- (IBAction)buttonPicturePressed:(id)sender{ 

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

Я сталкивался с некоторыми странными случаями при перетаскивании объектов по виду, когда, если вы одновременно касались другого объекта, срабатывал метод 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
}

Просто установите для всего соответствующего свойства UIView exclusiveTouch значение false, и все получится.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top