Столкнулся с проблемой, не работает. Когда я назначаю касание элементу StackView и использую симулятор, ничего не происходит. Расскажите пожалуйста подробно, в чем проблема, что я не так понимаю.
Я создал UITableView, который содержит CustomCell. CustomCell содержит ViewWrap, а ViewWrap содержит StackView с View в качестве элементов. Я назначаю UITapGestureRecouncer представлению, содержащему StackView.
P.S. В дальнейшем я изменю код и создам два пользовательских класса (для тапов будут разные функции) для всех представлений, которые входят в StackView.
class CustomCell: UITableViewCell {
static let ident = "cell"
let viewWrapp: UIView = {
let vwWrapp = UIView()
vwWrapp.translatesAutoresizingMaskIntoConstraints = false
return vwWrapp
}()
let stackView: UIStackView = {
var st = UIStackView()
st.translatesAutoresizingMaskIntoConstraints = false
st.axis = .horizontal
st.distribution = .fillEqually
st.alignment = .bottom
st.spacing = 0
st.isUserInteractionEnabled = true
return st
}()
var view11: UILabel = {
let vw = UILabel()
vw.translatesAutoresizingMaskIntoConstraints = false
vw.text = "4"
vw.font = UIFont(name: "LittleBird", size: 47)
vw.textAlignment = .center
vw.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: CustomCell.self, action: #selector(tabTab))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
vw.addGestureRecognizer(tapGesture)
return vw
}()
var view22: UILabel = {
let vw = UILabel()
vw.translatesAutoresizingMaskIntoConstraints = false
vw.text = "+"
vw.font = UIFont(name: "LittleBird", size: 30)
vw.textAlignment = .center
vw.layer.borderColor = CGColor(red: 1, green: 0, blue: 0, alpha: 1)
vw.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: CustomCell.self, action: #selector(tabTab))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
vw.addGestureRecognizer(tapGesture)
return vw
}()
// ... ...
// ... ...
// ... ...
var view77: UILabel = {
let vw = UILabel()
vw.translatesAutoresizingMaskIntoConstraints = false
vw.text = "4"
vw.font = UIFont(name: "LittleBird", size: 47)
vw.textAlignment = .center
vw.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: CustomCell.self, action: #selector(tabTab))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
vw.addGestureRecognizer(tapGesture)
return vw
}()
var view88: UILabel = {
let vw = UILabel()
vw.translatesAutoresizingMaskIntoConstraints = false
vw.text = " = "
vw.font = UIFont(name: "LittleBird", size: 30)
vw.textAlignment = .center
return vw
}()
var view99: UILabel = {
let vw = UILabel()
vw.translatesAutoresizingMaskIntoConstraints = false
vw.textAlignment = .center
vw.font = UIFont(name: "LittleBird", size: 47)
vw.layoutIfNeeded()
vw.numberOfLines = 0
return vw
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
isUserInteractionEnabled = true
contentView.addSubview(viewWrapp)
stackView.addArrangedSubview(view11)
stackView.addArrangedSubview(view22)
stackView.addArrangedSubview(view33)
stackView.addArrangedSubview(view44)
stackView.addArrangedSubview(view55)
stackView.addArrangedSubview(view66)
stackView.addArrangedSubview(view77)
stackView.addArrangedSubview(view88)
stackView.addArrangedSubview(view99)
viewWrapp.addSubview(stackView)
setConstraints()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
isUserInteractionEnabled = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
@objc func tabTab(){
print("Tab Tab")
}
func setConstraints() {
NSLayoutConstraint.activate([
viewWrapp.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
viewWrapp.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
viewWrapp.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
stackView.leadingAnchor.constraint(equalTo: viewWrapp.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: viewWrapp.trailingAnchor),
stackView.heightAnchor.constraint(equalToConstant: 60)
])
}
}
Я попытался назначить UITapGestureRecouncer представлению, которое находится в StackView, но ответа на нажатие не последовало. Также добавлен isUserInteractionEnabled = true
в:
Кстати, было бы намного проще использовать UIButton
вместо UILabel
. Тогда вам не нужны никакие жесты касания.
Подводя итог вашей проблеме,
вы пытаетесь добавить жест касания в представление (в вашем случае это UILabel
), но он не работает.
Есть аналогичная проблема, которую вы можете проверить Как установить событие клика в UIStackview
Чтобы решить вашу проблему, одно из многих решений — сделать все
UILabel
var
на lazy var
и измените UITapGestureRecognizer
target
параметр CustomCell.self
на self
.
Помимо решения,
Вы добавили translatesAutoresizingMaskIntoConstraints
каждому дочернему элементу UILabel
, что не требуется, поскольку вы устанавливаете NSLayoutConstraint
только в viewWrapp
и stackView
.
Я добавил рабочее решение из предоставленного вами фрагмента кода.
class CustomCell: UITableViewCell {
static let ident = "cell"
lazy var viewWrapp: UIView = {
let vwWrapp = UIView()
vwWrapp.translatesAutoresizingMaskIntoConstraints = false
return vwWrapp
}()
lazy var stackView: UIStackView = {
var st = UIStackView()
st.translatesAutoresizingMaskIntoConstraints = false
st.axis = .horizontal
st.distribution = .fillEqually
st.alignment = .bottom
st.spacing = 0
st.isUserInteractionEnabled = true
return st
}()
lazy var view11: UILabel = {
let vw = UILabel()
vw.text = "4"
vw.font = UIFont(name: "LittleBird", size: 47)
vw.textAlignment = .center
vw.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tabTab))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
vw.addGestureRecognizer(tapGesture)
return vw
}()
lazy var view22: UILabel = {
let vw = UILabel()
vw.text = "+"
vw.font = UIFont(name: "LittleBird", size: 30)
vw.textAlignment = .center
vw.layer.borderColor = CGColor(red: 1, green: 0, blue: 0, alpha: 1)
vw.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tabTab))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
vw.addGestureRecognizer(tapGesture)
return vw
}()
lazy var view77: UILabel = {
let vw = UILabel()
vw.text = "4"
vw.font = UIFont(name: "LittleBird", size: 47)
vw.textAlignment = .center
vw.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tabTab))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
vw.addGestureRecognizer(tapGesture)
return vw
}()
lazy var view88: UILabel = {
let vw = UILabel()
vw.text = " = "
vw.font = UIFont(name: "LittleBird", size: 30)
vw.textAlignment = .center
return vw
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
stackView.addArrangedSubview(view11)
stackView.addArrangedSubview(view22)
stackView.addArrangedSubview(view77)
stackView.addArrangedSubview(view88)
contentView.addSubview(viewWrapp)
viewWrapp.addSubview(stackView)
setConstraints()
}
func setConstraints() {
NSLayoutConstraint.activate([
viewWrapp.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
viewWrapp.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
viewWrapp.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
stackView.topAnchor.constraint(equalTo: viewWrapp.topAnchor),
stackView.bottomAnchor.constraint(equalTo: viewWrapp.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: viewWrapp.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: viewWrapp.trailingAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func tabTab(){
print("Tab Tab")
}
}
Помимо моего решения, эту проблему можно решить разными способами.
Например: добавление кнопок, упомянутых в комментариях @HangarRash.
Добавление lazy
совершенно не меняет результат.
Вопрос, на который вы ссылаетесь, не имеет ничего общего с этим вопросом. Этот ОП не пытается добавить жест касания в UIStackView.
@HangarRash, ты протестировал мой пример кода? Прежде чем опубликовать сообщение, я протестировал это решение в Xcode 15.3 :(
Я не говорил, что ваше решение не работает (я его не пробовал). Но в вашем ответе указано, что решение состоит в том, чтобы добавить lazy
. Но добавление lazy
в данном случае ничего не меняет. Если ваш ответ сработал, то, скорее всего, это потому, что вы также изменили параметр target
на self
для всех жестов касания (как я уже упоминал в своем комментарии под вопросом). В вашем ответе не упоминается об этом важном изменении.
@HangarRash без добавления lazy
, добавьте параметр target
к self
, который не работает. Ссылку, которую я предложил, вы можете проверить stackoverflow.com/a/78392494/6634614
@HangarRash Спасибо, что упомянули об этом. Я редактирую решение.
Ах да, я забыл, что это должно быть lazy
для ссылки self
. Но все же ключевым моментом вашего ответа является смена цели жеста касания. Добавление lazy
— это всего лишь побочный продукт использования self
. lazy
само по себе не является решением.
@Md Abul Kashem большое спасибо за подробный, информативный ответ и разъяснение упоминания о лени и точно понял меня и мой вопрос) Я читал и искал информацию в интернете, но похоже не уделил достаточного внимания к цели. Похоже я не на 100% понял информацию. Можете объяснить, как правильно понять, что нужно использовать в таргете?
@HangarRash Большое спасибо за быстрый ответ) Вы правы, использование кнопок, вероятно, было бы более привлекательным решением. Я задал аналогичный вопрос в чате местного форума, но не получил приемлемого ответа и решил просто выбрать ярлык. Видимо я не правильно понял вопрос с таргетом, в каких случаях и что выбирать и что нужно подавать в таргет. Не могли бы вы дать мне несколько советов о том, как работать с Target?
@VladislavZhelezniak, под target
я хотел изменить значение let tapGesture = UITapGestureRecognizer(target: CustomCell.self, action: #selector(tabTab))
target
на let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tabTab))
, которое используется для установки жеста касания внутри вашей метки. В вашем случае var view77: UILabel
@VladislavZhelezniak Вы можете проголосовать за любой ответ, если он работает. Проверьте Meta.stackoverflow.com/a/269683/6634614 как сказать спасибо в StackOverflow?
@Md Абул Кашем Благодарен за ваш ответ. Я понял, что допустил ошибку, когда передал целевой CustomCell.self вместо self. Это то, что предлагает XCode. Буду изучать целевой параметр)
Во всех жестах касания замените
CustomCell.self
наself
.