Как отключить мультитач?
В моем приложении есть несколько кнопок, которые запускают разные события. Пользователь НЕ должен иметь возможность удерживать несколько кнопок. Во всяком случае, нажатие нескольких кнопок приводит к сбою приложения.
Итак, я пытаюсь отключить multi-touch в своем приложении.
Я снял флажок "Множественное касание" во всех xib файлах, и, насколько я могу судить, свойства "multipleTouchEnabled" и "exclusiveTouch" свойств определяют, использует ли вид мультитач. Итак, в моем приложенииDidFinishLaunching я добавил следующее:
self.mainViewController.view.multipleTouchEnabled=NO;
self.mainViewController.view.exclusiveTouch =YES;
И в каждом из моих контроллеров представления я поместил это в viewDidLoad
self.view.multipleTouchEnabled=NO;
self.view.exclusiveTouch=YES;
Однако он еще принимает несколько касаний. Я мог бы сделать что-то вроде отключения других кнопок после получения события касания, но это было бы уродливым взломом. Наверняка есть способ правильно отключить multi-touch?
Ответы
Ответ 1
Если вы хотите, чтобы только одна кнопка реагировала на касания одновременно, вам нужно установить для этой кнопки эксклюзивную кнопку, а не для родительского представления. Кроме того, вы можете отключить другие кнопки, когда кнопка получает событие "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
Ответ 2
- (void)viewDidLoad {
[super viewDidLoad];
for(UIView* v in self.view.subviews)
{
if([v isKindOfClass:[UIButton class]])
{
UIButton* btn = (UIButton*)v;
[btn setExclusiveTouch:YES];
}
}
}
Ответ 3
- (void)viewDidLoad {
[super viewDidLoad];
for(UIView* v in self.view.subviews)
{
if([v isKindOfClass:[UIButton class]])
{
UIButton* btn = (UIButton*)v;
[btn setExclusiveTouch:YES];
}
}
}
Этот код протестирован и отлично работает для меня. Нет приложения сбой при нажатии более чем одной кнопки за раз.
Ответ 4
Ваше приложение аварийно завершает работу. Изучите дальше, используйте отладчик, посмотрите, что неправильно, а не пытайтесь скрыть ошибку.
Edit:
ОК, хорошо, я должен признать, что я был немного суровым. Вы должны установить свойство exclusiveTouch на каждой кнопке. Все это. Свойство multipleTouchEnabled не имеет значения.
Ответ 5
На основе ответа 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];
... выполнит трюк.
Ответ 6
Об этом часто сообщают наши тестеры. Один из подходов, которые я иногда использую, хотя он должен использоваться сознательно, заключается в создании категории для UIView
, как этот:
@implementation UIView (ExclusiveTouch)
- (BOOL)isExclusiveTouch
{
return YES;
}
Ответ 7
Чтобы отключить мультитач в SWIFT:
Вам нужно сначала иметь выход каждой кнопки, а затем просто установить эксклюзивное касание к true. Поэтому у вас viewDidLoad()
будет:
yourButton.exclusiveTouch = true
.
//не нужно, но вы также можете добавить:
self.view.multipleTouchEnabled = false
Ответ 8
Довольно просто, вы можете использовать использование свойства ExclusiveTouch в этом случае
[youBtn setExclusiveTouch:YES];
Это логическое значение, указывающее, обрабатывает ли получатель исключительно события касания.
Установка этого свойства в YES заставляет приемник блокировать доставку событий касания к другим представлениям в том же окне. Значением по умолчанию этого свойства является NO.
Ответ 9
Мой опыт в том, что по умолчанию новый проект даже не позволяет мультитач, вы должны включить его. Но я полагаю, это зависит от того, как вы начали. Вы использовали пример mutlitouch в качестве шаблона?
Прежде всего, вы абсолютно уверены, что мультитач включен? Это позволяет быстро создавать отдельные штрихи в последовательности. Multitouch больше о том, что вы делаете с двумя или более пальцами, когда они находятся на поверхности. Возможно, у вас есть одно касание, но они неправильно относятся к тому, что происходит, если две кнопки нажаты почти одновременно.
Ответ 10
У меня была именно эта проблема.
Решение, с которым мы столкнулись, состояло в том, чтобы просто наследовать новый класс из UIButton, который переопределяет метод initWithCoder, и использовать его там, где нам понадобилось одно нажатие кнопки за раз (т.е. везде):
@implementation ExclusiveButton
(id)initWithCoder: (NSCoder*)decoder
{
[self setExclusiveTouch:YES];
return [super initWithCoder:decoder]
}
@end
Обратите внимание, что это работает только с кнопками, загружаемыми из файлов nib.
Ответ 11
Я создал расширение класса 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];
}
Ответ 12
Если вы хотите отключить мультитач программно, или если вы используете 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
}
Ответ 13
Отключите все кнопки в представлении "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;
}
------
------
}
Ответ 14
Я решил эту проблему следующим образом:
NSTimeInterval intervalButtonPressed;
- (IBAction)buttonPicturePressed:(id)sender{
if (([[NSDate date] timeIntervalSince1970] - intervalButtonPressed) > 0.1f) {
intervalButtonPressed = [[NSDate date] timeIntervalSince1970];
//your code for button
}
}
Ответ 15
Просто установите для всех соответствующих свойств UIView exclusiveTouch значение false делает трюк.
Ответ 16
Я боролся с некоторыми нечетными случаями при перетаскивании объектов вокруг представления, где, если бы вы коснулись другого объекта одновременно, он упустил бы метод touchhesBegan. Моя работа заключалась в том, чтобы отключить взаимодействие с пользователем для родительского представления до тех пор, пока не будет вызвано касаниеEnded или touchsCancelled.
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
}