Как я могу обнаружить событие касания UIImageView?

97

Я разместил изображение (UIImageView) на панели навигации. Теперь я хочу обнаружить событие касания и обработать это событие. Как я могу это сделать?

ebaccount
источник
В этой ситуации я бы (и думаю, что вам следует) использовать вместо этого настраиваемый UIButton.
titaniumdecoy
Проверить версию Swift Ответ http://stackoverflow.com/a/41328885/3177007
Мохамед Джалил Назир

Ответы:

138

С практической точки зрения, не делайте этого.

Вместо этого добавьте кнопку с пользовательским стилем (без графики кнопок, если вы не укажете изображения) поверх UIImageView. Затем прикрепите к нему любые методы, которые вы хотите вызвать.

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

Кендалл Хельмштеттер Гельнер
источник
Я добавил кнопку на панель навигации, и я также могу обрабатывать события касания. Однако я хочу добавить круглое изображение на эту кнопку. Не могли бы вы сообщить мне, как это сделать программно? Кроме того, не могли бы вы сообщить мне, как программно установить для свойства кнопки значение «custom»?
ebaccount
Посмотрите документацию для UIButton - вам нужно установить фоновые изображения для состояния управления, вам понадобятся разные изображения для нормального и выделенного / выделенного. Я полагаю, что стиль кнопки - это то, что вы установили для UIButtonStyleCustom - опять же, посмотрите документацию на свойство style в UIButton.
Кендалл Хельмштеттер Гельнер,
1
Разве добавление UIButton поверх UIImageView не является чрезмерным? Вы добавляете дополнительный объект, а можете просто реализовать методы касаний уже существующего объекта UIImageView. Нет?
samvermette
32
Если вы посмотрите на размер UIButton в памяти, это практически ничего, и у вас их всего несколько на экран. То, что вы получаете бесплатно, - это вся проводка целевого действия для разных состояний (например, касание внутри), а также приятное поведение, например, не срабатывает, когда вы нажимаете, а двигаете пальцем в сторону. По сути, кнопки являются одними из самых тонко созданных объектов во всей системе, и думать, что вы собираетесь создать собственный сенсорный код, который работает лучше, - безумие. Используйте то, что дешево и хорошо работает, сохраните заказную работу для вещей, которые фреймворки еще не обрабатывают для вас.
Кендалл Хельмштеттер Гельнер
6
Вы также можете наложить UIControl, если все, что вам нужно, это сенсорные события (через addTaget: action: forControlEvents :). Это немного дешевле, чем UIButton, у которого есть изображения и несколько состояний. Кроме того, я использую условные выражения препроцессора, чтобы изменить цвет фона наложенного элемента управления на розовый, чтобы я мог точно видеть, где они находятся (и помнить, что они существуют :-).
Джефф
115

A UIImageViewявляется производным от, UIViewкоторый является производным от, UIResponderпоэтому он готов обрабатывать события касания. Вы хотите , чтобы обеспечить touchesBegan, touchesMovedи touchesEndedметоды , и они будут вызываться , если пользователь вводит изображение. Если все, что вам нужно, это событие касания, проще просто использовать настраиваемую кнопку с изображением, установленным в качестве изображения кнопки. Но если вам нужен более точный контроль над метчиками, перемещениями и т. Д., Это то, что вам нужно.

Вы также захотите взглянуть на еще несколько вещей:

  • Переопределите canBecomeFirstResponderи верните YES, чтобы указать, что представление может стать фокусом событий касания (по умолчанию NO).

  • Установите userInteractionEnabledсвойство в YES. По умолчанию для UIViewsYES, но для UIImageViewsNO, поэтому вам нужно явно включить его.

  • Если вы хотите реагировать на события мультисенсорного ввода (например, масштабирование, масштабирование и т. Д.), Вы должны установить multipleTouchEnabledДА.

Рамин
источник
Я пробовал это, но тем не менее я не получаю события touchesBegan ... почему это так?
Маркус
5
@Markus: У меня была та же проблема, но я решил ее, установив userInteractionEnabledДА в моем родительском представлении. См. Stackoverflow.com/questions/5887305/…
Saxon Druce
51

Чтобы добавить событие касания в UIImageView, используйте в файле .m следующее:

UITapGestureRecognizer *newTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(myTapMethod)];

[myImageView setUserInteractionEnabled:YES];

[myImageView addGestureRecognizer:newTap];


-(void)myTapMethod{
    // Treat image tap
}
Ага.
источник
userInteractionEnabled = true - это часть, о которой легко забыть, спасибо.
Майкл Петерсон,
23

Вы также можете добавить UIGestureRecognizer. Это не требует от вас добавления дополнительных элементов в иерархию представлений, но все же предоставляет вам весь хорошо написанный код для обработки событий касания с довольно простым интерфейсом:

    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:self action:@selector(handleSwipe:)];
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    [imgView_ addGestureRecognizer:swipeRight];        
    [swipeRight release];
    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:self action:@selector(handleSwipe:)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [imgView_ addGestureRecognizer:swipeLeft];
    [swipeLeft release];
сполу
источник
10
НЕ забудьте установить UserInteractionEnabled для imgView_
Anonymous White
13

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

Я не получаю никаких событий от объекта UIImangeView, но я получаю событие от аналогичного объекта UILableс очень похожими параметрами, которые я для него устанавливаю. Под iOS 5.1.

Я уже сделал следующее:

  1. установите для setUserInteractionEnabled значение YES как для `UIImageView, так и для родительского представления.
  2. установите для setMultipleTouchEnabled значение ДА для UIImageView.
  3. Пробовал подклассы UIImageView, не помогло.

Прикрепив код ниже, в этом коде я инициализирую как, так UIImageViewи UILabelметку, которая отлично работает с точки зрения событий запуска. Я старался убрать ненужный код.

UIImageView *single_view = [[UIImageView alloc]initWithFrame:CGRectMake(200, 200, 100, 100)];
single_view.image = img;
single_view.layer.zPosition = 4;

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureCaptured:)];
[single_view addGestureRecognizer:singleTap];
[single_view setMultipleTouchEnabled:YES];
[single_view setUserInteractionEnabled:YES];
[self.myScrollView addSubview:single_view];
self.myScrollView.userInteractionEnabled = YES;

UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
testLabel.backgroundColor = [UIColor redColor];
[self.myScrollView addSubview:testLabel];
[testLabel addGestureRecognizer:singleTap];
[testLabel setMultipleTouchEnabled:YES];
[testLabel setUserInteractionEnabled:YES];
testLabel.layer.zPosition = 4;

И метод, обрабатывающий событие:

- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
    UIView *tappedView = [gesture.view hitTest:[gesture locationInView:gesture.view] withEvent:nil];
    NSLog(@"Touch event on view: %@", [tappedView class]);
}

Как сказано, метка метка получена.

Илан
источник
6

Вместо того, чтобы создавать осязаемый UIImageView, а затем размещать его на панели навигации, вы должны просто создать UIBarButtonItem, который вы делаете из UIImageView.

Сначала сделайте просмотр изображения:

UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"nameOfYourImage.png"]];

Затем сделайте элемент barbutton из представления изображения:

UIBarButtonItem *yourBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:yourImageView];

Затем добавьте элемент кнопки панели на панель навигации:

self.navigationItem.rightBarButtonItem = yourBarButtonItem;

Помните, что этот код входит в контроллер представления, который находится внутри массива контроллера представления контроллера навигации. Таким образом, этот «элемент сенсорной кнопки панели, выглядящей как изображение» будет отображаться на панели навигации только тогда, когда этот контроллер представления отображается при его отображении. Когда вы нажимаете другой контроллер представления, этот элемент кнопки панели навигации исчезает.

юджин
источник
3

Возможно, вы захотите переопределить touchesBegan:withEvent:метод UIView(или подкласса), который содержит ваше UIImageViewвложенное представление.

В этом методе проверьте, UITouchпопадает ли какое-либо касание в границы UIImageViewэкземпляра (допустим, он вызывается imageView).

То есть пересекается ли CGPointэлемент [touch locationInView]с CGRectэлементом [imageView bounds]? Посмотрите на функцию, CGRectContainsPointчтобы запустить этот тест.

Алекс Рейнольдс
источник
Спасибо за ваш ответ. Я добавил такое представление: [navBar addSubview: self.pImage]; // добавлен как часть панели навигации. Я переопределил функцию, но функция никогда не вызывается. Я установил для свойства userInteractionEnabled UIImageView значение YES. Я что-нибудь упускаю?
ebaccount
Ознакомьтесь с методом touchesBegan: withEvent:. В поисковых системах есть множество примеров того, как это работает.
Alex Reynolds
1

Сначала вы должны разместить UIButton, а затем либо добавить фоновое изображение для этой кнопки, либо вам нужно разместить UIImageView поверх кнопки.

Или:

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

Hilaj
источник
0

Для тех из вас, кто ищет решение Swift 4 для этого ответа, вы можете использовать следующее для обнаружения события касания в UIImageView.

let gestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageViewTapped))
imageView.addGestureRecognizer(gestureRecognizer)
imageView.isUserInteractionEnabled = true

Затем вам нужно будет определить свой селектор следующим образом:

@objc func imageViewTapped() {
    // Image has been tapped
}
Джош
источник
-2

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

user1240409
источник