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

101

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

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

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

Wfbarksdale
источник

Ответы:

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-совместимый