Обработка события касания в UILabel и его подключение к IBAction


101

Итак, у меня есть UILabelсозданный в построителе интерфейса, который отображает некоторый текст по умолчанию «нажмите, чтобы начать».

Когда пользователь нажимает « UILabelЯ хочу», запускается метод IBAction: -(IBAction)next;который обновляет текст на этикетке, чтобы сказать что-то новое.
Было бы очень удобно, если бы это позволяло мне просто перетащить соединение из моего метода на мою метку, а затем выбрать ретушь внутри, как с помощью кнопки. но, увы, нет сигары.

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

Ответы:


255

Проверить это:

UILabel *label = ...
label.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture =
      [[UITapGestureRecognizer alloc] initWithTarget:self 
                                              action:@selector(labelTap)];
[label addGestureRecognizer:tapGesture];

Уловка состоит в том, чтобы обеспечить взаимодействие с пользователем.


1
Что делать, если у меня несколько ярлыков? как я могу отличить, какой из них был задействован?
— ученик

1
@learner попробуйте свойство тега. не забудьте использовать labelTap: вместо labelTap. и используйте - (void) labelTap: (id) sender ;.
— thedjaney

1
@thedjaney Отправителем является UITapGestureRecognizer, а не UILabel
— h4labs

TapGestureRecognizer - это не то же самое, что подкрашивание внутри, и он теряет соответствие и доступность человеческому интерфейсу.

1
@ h4labs вы можете использовать UITapGestureRecognizer * tapGesture = sender; затем получите тег ярлыка с помощью tapGesture.view.tag
— DJTano

70

UILabel наследуется от UIView, который наследуется от UIResponder. Все объекты UIresponder могут обрабатывать события касания. Итак, в вашем файле класса, который знает о вашем представлении (который содержит UIlabel), выполните:

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;

В построителе интерфейса установите значение тега UILabel. когда касания происходят в вашем методе touchesBegan, проверьте значение тега представления, которому этот тег принадлежит:

UITouch *touch = [touches anyObject];

if(touch.view.tag == MY_TAG_VAL)
label.text = @"new text";

Вы связываете свой код в файле класса с объектом UILabel в построителе интерфейса, объявляя переменную экземпляра UILabel с префиксом IBOutlet:

IBOutlet UILabel *label;

Затем в конструкторе интерфейсов вы можете их подключить.


31
Одно замечание: вы должны убедиться, что вы отметили «Взаимодействие с пользователем включено» в построителе интерфейса, иначе это не сработает.
— midas06

У меня возникла одна проблема с этим методом. Он работал нормально, когда контроллер представления загружался напрямую, но когда я создал контроллер навигации, подтолкнул контроллер, содержащий метку, к контроллеру навигации, а затем отобразил его, прикосновения, похоже, больше не доходили до метки. Любые идеи?
— midas06

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

5
Аналогичный метод, для которого не требуются теги, - просто проверить, совпадает ли touch.view с розеткой, установленной для метки. Я предпочитаю это, так как это означает, что мне не нужно отслеживать теги.
— Defragged

отличное решение. Я рекомендую вам не устанавливать для любого тега значение 0, потому что щелчок в любом другом месте имеет значение тега 0. Это связано с тем, что ваше представление, скорее всего, будет иметь значение тега 0. В противном случае вы можете установить тег своего представления на что-то вроде -1, а затем вы можете использовать значение тега 0 где-нибудь еще, например, кнопку
— kevinl 07

30

Вы можете использовать UIButton, сделать его прозрачным, т.е. произвольный тип без изображения, и добавить на него UILabel (по центру). Затем подключите обычные события кнопок.


Я согласен, пользовательский тип кнопки должен дать вам пользовательский интерфейс типа UILabel.
— stitz

2
+1, красиво и просто. Я пробовал это раньше, установив для обычной кнопки значение opactiy 0, что не сработало, но совет по изменению типа на пользовательский работал отлично.
— Брайан Моэскау,

Непрозрачность повлияет на кнопку и все ее подпредставления, поэтому opacity = 0 сделает все это невидимым.
— Eiko

10
Ой. Это взлом по сравнению с другими решениями в этой теме. Используйте распознаватель жестов касания на этикетке, если вы хотите распознать жест касания на этикетке. (Видите, как это читается, как будто это было предназначено для этого?)
— Джеймс Бутчер

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

17

Swift 3

У вас есть IBOutlet

@IBOutlet var label: UILabel!

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

label.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userDidTapLabel(tapGestureRecognizer:)))
label.addGestureRecognizer(tapGesture)

И, наконец, возьмите кран

func userDidTapLabel(tapGestureRecognizer: UITapGestureRecognizer) {
  // Your code goes here
}

2
Мне пришлось добавить @objc в userDidTapLabel, чтобы это работало. Может быть, быстрая 4 штука.
— POSIX-совместимый
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.