[英]UIButton's .touchUpInside event not working
I am working on adding buttons to UICollectionViewCell
at runtime and having the button registered to the event according to its type, at runtime. 我正在努力在运行时向
UICollectionViewCell
添加按钮, UICollectionViewCell
在运行时根据事件的类型将按钮注册到事件。 The type of the button can be, for instance, utterance button and action button, and both should be registered to separate events. 按钮的类型可以是例如发声按钮和操作按钮,并且应该将两者注册为单独的事件。
The hierarchy of UI elements is like UICollectionView
-> UICollectionViewCell
-> StackView
-> Multiple ( UIView
-> UIButton
). UI元素的层次结构是像
UICollectionView
- > UICollectionViewCell
- > StackView
- >海报( UIView
- > UIButton
)。
The problem is that I am unable to register the .touchUpInside
events. 问题是我无法注册
.touchUpInside
事件。
What I have tried yet is calling becomeFirstResponder()
through button's instance, moving the event method inside the UIViewController
and adding target in cellForItemAt
method after having the view hierarchy set up, trying isUserInteractionEnabled
with values true
and false
on UICollectionView
, UICollectionViewCell
, UIStackView
, UIView
and UIButton
. 我已经试过没被调用
becomeFirstResponder()
通过按钮的情况下,移动内部的事件方法UIViewController
并添加目标cellForItemAt
具有视图层次建立,努力之后方法isUserInteractionEnabled
与价值观true
和false
的UICollectionView
, UICollectionViewCell
, UIStackView
, UIView
和UIButton
。
EDIT 1: So the code looks like the following: 编辑1:因此,代码如下所示:
class AssistantViewController: UIViewController {
private var assistantManager: AssistantManager
private var conversationSection: UICollectionView
private let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout.init()
private var multipleChoiceMessageCell = MultipleChoiceMessageCell()
private var conversationCells: [BaseCollectionViewCell] {
return [
multipleChoiceMessageCell
]
}
override func viewDidLoad() {
super.viewDidLoad()
construct()
assistantManager.performGreetingUtterance()
}
}
extension AssistantViewController: UICollectionViewDataSource {
@objc func didTapUtteranceButton() {
print ("elo I a m here")
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) ->
UICollectionViewCell {
let conversationItem = assistantManager.conversationItems[indexPath.row]
let cellId = self.getCellIdentifier(for: conversationItem)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId,
for: indexPath) as? ConversationItemCell
if let conversationCell = cell {
conversationCell.layoutIfNeeded()
conversationCell.configure(with: conversationItem)
switch conversationItem {
case let .multipleChoiceMessage(chatMessage, multipleChoice): do {
for item in multipleChoice.multipleChoice.items {
switch item {
case .utteranceButton(let utteranceButton): do {
utteranceButton.button.isUserInteractionEnabled = true
utteranceButton.button.addTarget(self,
action: #selector(didTapUtteranceButton),
for: .touchUpInside)
//utteranceButton.button.becomeFirstResponder()
print("added")
}
}
}
}
default: print("Todo")
}
}
return cell!
}
class AssistantManager {
public func parseAssistantSnippets(
snippets: [Snippet]) -> ConversationCellModel {
var interactableItems: [MessageContent] = []
var utteredText:String = ""
for snippet in snippets {
switch snippet {
case .text(let text): utteredText = text.displayText
case .utteranceButton(let utteranceButton): do {
let button = UtteranceButton(buttonTitle: utteranceButton.displayText,
maxWidth: ConversationCell.elementMaxWidth,
utteranceText: utteranceButton.utteranceText,
onPress: performUserUtterance)
let messageContent = MessageContent.utteranceButton(button)
interactableItems.push(messageContent)
}
default: print("TODO")
}
}
return ConversationCellModel.init(message: utteredText,
multipleChoice: interactableItems)
}
public func performGreetingUtterance() {
self.addTypingIndicator()
performUtteranceOperation(utterance: "hi")
}
public func performUtteranceOperation(utterance: String) {
let context = UtteranceRequest.UserContext(cid: "1",
location: CLLocationCoordinate2D(),
storeID: "1",
timeZoneOffset: 0)
let request = UtteranceRequest(utterance: utterance,
context: context)
provider.conveyUtterance(request) { [weak self] result in
switch result {
case .success(let snippetResponse): do {
let snippetResponseTransformed = SnippetResponse.init(snippetResponse)
let ConversationCellModel = self?.parseAssistantSnippets(
snippets: snippetResponseTransformed.snippets)
if let model = ConversationCellModel {
self?.addMessageFromAssistant(interactableItems: model.multipleChoice,
utteredText: model.message)
}
}
case .failure(let error): return
}
}
}
}
class MultipleChoiceMessageCell: ConversationCell {
public func configure(with conversationItem: ConversationItem) {
switch conversationItem {
case let .multipleChoiceMessage(chatMessage, multipleChoice): do {
let isCellFromUser = chatMessage.metadata.isFromUser
let avatarBackgroundColor = chatMessage.metadata.avatarBackgroundColor
let avatarTintColor = chatMessage.metadata.avatarTintColor
let messageTextBackgroundColor = chatMessage.metadata.textContainerBackgroundColor
let messageTextColor = chatMessage.metadata.textColor
self.messageTextLabel.text = chatMessage.message
self.avatarImageView.image = chatMessage.metadata.avatarImage
self.messageTextContainer.backgroundColor = messageTextBackgroundColor
self.messageTextLabel.textColor = messageTextColor
self.avatarImageView.backgroundColor = avatarBackgroundColor
self.avatarImageView.tintColor = avatarTintColor
self.rightMessageHorizontalConstraint?.isActive = isCellFromUser
self.leftMessageHorizontalConstraint?.isActive = !isCellFromUser
self.rightAvatarHorizontalConstraint?.isActive = isCellFromUser
self.leftAvatarHorizontalConstraint?.isActive = !isCellFromUser
configureCellWith(interactablesSection: multipleChoice.multipleChoice.itemsContainer)
}
default:
logIncorrectMapping(expected: "message", actual: conversationItem)
}
}
func configureCellWith(interactablesSection: UIStackView) {
let stackViewTop = NSLayoutConstraint(
item: interactablesSection,
attribute: .top,
relatedBy: .equal,
toItem: self.messageTextContainer,
attribute: .bottom,
multiplier: 1,
constant: 10)
let stackViewLeading = NSLayoutConstraint(
item: interactablesSection,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1,
constant: ConversationCell.avatarMaxSize +
ConversationCell.messageContainerMaxLeadingMargin +
ConversationCell.avatarMaxMargin)
self.addAutoLayoutSubview(interactablesSection)
self.addConstraints([stackViewTop,
stackViewLeading])
}
}
class InteractableItem {
let contentView: UIView
var height: CGFloat
init() {
contentView = UIView()
height = 0
}
}
class CellPrimaryButton: InteractableItem {
let button: CorePrimaryButton
init(buttonTitle titleLabel: String, maxWidth: CGFloat) {
button = CorePrimaryButton()
button.setTitle(titleLabel, for: .normal)
button.setBackgroundColor(CoreColor.white, for: .normal)
button.setTitleColor(CoreColor.black, for: .normal)
button.layer.borderColor = CoreColor.black.cgColor
button.layer.borderWidth = 1
//button.becomeFirstResponder()
super.init()
contentView.isUserInteractionEnabled = true
// button.addTarget(self, action: #selector(didTapUtteranceButton), for: .touchUpInside)
setConstraints(maxWidth: maxWidth)
}
func setConstraints(maxWidth: CGFloat) {
let buttonHorizontal = NSLayoutConstraint(item: self.button,
attribute: .leading,
relatedBy: .equal,
toItem: self.contentView,
attribute: .leading,
multiplier: 1,
constant: 0)
let buttonWidth = NSLayoutConstraint(item: self.button,
attribute: .width,
relatedBy: .lessThanOrEqual,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1,
constant: maxWidth)
self.contentView.addConstraints([buttonHorizontal,
buttonWidth])
self.contentView.backgroundColor = UIColor.purple
self.height = self.button.intrinsicContentSize.height
self.contentView.addAutoLayoutSubview(self.button)
}
}
class UtteranceButton: CellPrimaryButton {
let utteranceText: String
let performUtterance: (String) -> Void
init(buttonTitle titleLabel: String,
maxWidth: CGFloat,
utteranceText: String,
onPress: @escaping (String) -> Void) {
self.utteranceText = utteranceText
self.performUtterance = onPress
super.init(buttonTitle: titleLabel, maxWidth: maxWidth)
}
}
Try this way of calling an action. 尝试使用这种方式来调用动作。
UIApplication.shared.sendAction(#selector(didTapUtteranceButton), to: self, from: nil, for: nil)
instead of this one: 而不是这个:
utteranceButton.button.addTarget(self, #selector(didTapUtteranceButton), for: .touchUpInside)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.