问题
我尝试以编程方式完成所有操作,因此创建了这个ResultController。不知道为什么,我的两个按钮可以用,但另外三个不可以。程序甚至不会注意到触摸事件。我读过很多关于这个主题的文章,但没有一个解决方案对我有效。
两个按钮是语言按钮和交换按钮,它们嵌入在屏幕顶部的堆栈视图中。不起作用的3个按钮是下图所示结果卡上的soundButton
、loopButton
和addFlashcardButton
。
问题
我需要做什么才能让这些按钮响应触摸事件?
下面是这个viewController的代码,以及结果的图片。我将张贴的重要部分和整个代码供参考。按钮分为两个功能,setupResultsView()
和setupScrollView()
:
按钮示例化
var soundButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(systemName: "speaker.3.fill"), for: .normal)
button.backgroundColor = .white
button.tintColor = .black
button.addTarget(self, action: #selector(soundButtonPressed), for: .touchUpInside)
return button
}()
var loopButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(systemName: "repeat"), for: .normal)
button.backgroundColor = .white
button.tintColor = .black
button.addTarget(self, action: #selector(loopButtonPressed), for: .touchUpInside)
return button
}()
var addFlashcardButton: UIButton = {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
button.setImage(UIImage(systemName: "plus"), for: .normal)
button.backgroundColor = K.Colors.purple
button.tintColor = .white
button.roundCorners(cornerRadius: 15)
button.addTarget(self, action: #selector(addFlashcardButtonPressed), for: .touchUpInside)
return button
}()
选择器功能
@objc func soundButtonPressed() {
print("soundButton")
}
@objc func loopButtonPressed() {
print("loopButton")
}
@objc func addFlashcardButtonPressed() {
print("adding flashcard")
}
完整编码
import UIKit
class ResultsController: UIViewController {
//MARK: - Info
let cellID = "SoundItOutCell"
//MARK: - Views
var centerTitle: UILabel = {
let label = UILabel(frame: CGRect(x: 10, y: 0, width: 50, height: 40))
label.backgroundColor = K.Colors.purple
label.font = UIFont.boldSystemFont(ofSize: 30)
label.text = "Aura"
label.numberOfLines = 2
label.textColor = .white
label.textAlignment = .center
return label
}()
var languageBarView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.setUnderlineStyle(color: K.Colors.purple)
return view
}()
var langStackView: UIStackView = {
let stackView = UIStackView()
stackView.backgroundColor = .white
stackView.alignment = .center
stackView.distribution = .fillEqually
return stackView
}()
var languageButton: UIButton = {
let button = UIButton()
button.setTitle("Japanese", for: .normal)
button.addTarget(self, action: #selector(languageButtonPressed), for: .touchUpInside)
button.backgroundColor = .white
button.setTitleColor(UIColor.systemBlue, for: .normal)
return button
}()
var swapButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(systemName: "repeat"), for: .normal)
button.addTarget(self, action: #selector(swapButtonPressed), for: .touchUpInside)
button.tintColor = .black
button.backgroundColor = .white
return button
}()
var englishLabel: UILabel = {
let label = UILabel()
label.text = "English"
label.textColor = .black
label.backgroundColor = .white
label.textAlignment = .center
return label
}()
var textViewBackgroundView = UIView()
var textView: UITextView = {
let textView = UITextView()
textView.returnKeyType = .search
textView.text = "Enter text"
textView.textColor = .lightGray
textView.font = .systemFont(ofSize: 20)
textView.textContainerInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 50)
return textView
}()
var cancelButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(systemName: "multiply"), for: .normal)
button.backgroundColor = .white
button.tintColor = .black
button.addTarget(self, action: #selector(cancelButtonPressed), for: .touchUpInside)
button.isHidden = true
return button
}()
var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.backgroundColor = K.Colors.lightGrey
return scrollView
}()
var contentView: UIView = {
let view = UIView()
view.backgroundColor = K.Colors.lightGrey
return view
}()
var resultCardView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.roundCorners(cornerRadius: 10)
return view
}()
var topLabel = UILabel()
var bottomLabel = UILabel()
var soundButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(systemName: "speaker.3.fill"), for: .normal)
button.backgroundColor = .white
button.tintColor = .black
button.addTarget(self, action: #selector(soundButtonPressed), for: .touchUpInside)
return button
}()
var loopButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(systemName: "repeat"), for: .normal)
button.backgroundColor = .white
button.tintColor = .black
button.addTarget(self, action: #selector(loopButtonPressed), for: .touchUpInside)
return button
}()
var lineDividerView: UIView = {
let view = UIView()
view.backgroundColor = K.Colors.purple
return view
}()
var addFlashcardButton: UIButton = {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
button.setImage(UIImage(systemName: "plus"), for: .normal)
button.backgroundColor = K.Colors.purple
button.tintColor = .white
button.roundCorners(cornerRadius: 15)
button.addTarget(self, action: #selector(addFlashcardButtonPressed), for: .touchUpInside)
return button
}()
// Background Views
let resultBackgroundView = UIView ()
let addFlashcardBackgroundView = UIView()
//MARK: - Class Functions
override func viewDidLoad() {
super.viewDidLoad()
setupView()
view.backgroundColor = K.Colors.lightGrey
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setupShadows()
}
}
extension ResultsController {
//MARK:- View Setup Functions
func setupView() {
self.setupToHideKeyboardOnTapOnView()
setupNavBar()
setupLanguageSelectionView()
setupTextView()
setupScrollView()
}
func setupShadows() {
textViewBackgroundView.setShadow(color: UIColor.black, opacity: 0.3, offset: .init(width: 0, height: 3), radius: 2)
resultBackgroundView.setShadow(color: .black, opacity: 0.3, offset: CGSize(width: 5, height: 5), radius: 2, cornerRadius: 10)
addFlashcardBackgroundView.setShadow(color: .black, opacity: 0.5, offset: CGSize(width: 2, height: 2), radius: 2, cornerRadius: 15)
}
func setupNavBar() {
// Add Center Title
self.navigationItem.titleView = centerTitle
// Add userbutton
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "person"),
style: .plain,
target: self,
action: #selector(profileButtonTapped))
// Make bar color purple, and buttons white
self.navigationController?.navigationBar.tintColor = .white
self.navigationController?.navigationBar.barTintColor = K.Colors.purple
}
func setupLanguageSelectionView() {
// Add Language Bar View
view.addSubview(languageBarView)
languageBarView.anchor(top: view.safeAreaLayoutGuide.topAnchor,
bottom: nil, leading: view.leadingAnchor,
trailing: view.trailingAnchor,
height: 60,
width: nil)
// Add Stack View
languageBarView.addSubview(langStackView)
langStackView.anchor(top: languageBarView.topAnchor,
bottom: languageBarView.bottomAnchor,
leading: languageBarView.leadingAnchor,
trailing: languageBarView.trailingAnchor,
height: nil,
width: nil,
padding: UIEdgeInsets(top: 0, left: 0, bottom: -2, right: 0))
// Add Language Button
langStackView.addArrangedSubview(languageButton)
// Add Swap Button
langStackView.addArrangedSubview(swapButton)
// Add English Label
langStackView.addArrangedSubview(englishLabel)
}
func setupTextView() {
// Add View
view.addSubview(textViewBackgroundView)
textViewBackgroundView.anchor(top: langStackView.bottomAnchor,
bottom: nil,
leading: view.leadingAnchor,
trailing: view.trailingAnchor,
height: 60,
width: nil,
padding: UIEdgeInsets(top: 2, left: 0, bottom: 0, right: 0))
// Add TextView
textView.delegate = self
view.addSubview(textView)
textView.anchor(top: textViewBackgroundView.topAnchor,
bottom: textViewBackgroundView.bottomAnchor,
leading: textViewBackgroundView.leadingAnchor,
trailing: textViewBackgroundView.trailingAnchor,
height: nil,
width: nil,
padding: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
// Add X Button
view.addSubview(cancelButton)
cancelButton.anchor(top: textView.topAnchor,
bottom: nil,
leading: nil,
trailing: textView.trailingAnchor,
height: 40,
width: 40,
padding: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
}
func setupScrollView() {
// Add scroll view and content view
view.addSubview(scrollView)
view.sendSubviewToBack(scrollView)
scrollView.addSubview(contentView)
// Anchor Scroll View
scrollView.anchorXCenter(top: textView.topAnchor,
bottom: view.safeAreaLayoutGuide.bottomAnchor,
centerAnchor: view.centerXAnchor,
width: view.widthAnchor,
height: nil)
// Anchor Content View
contentView.anchorXCenter(top: scrollView.topAnchor,
bottom: scrollView.bottomAnchor,
centerAnchor: scrollView.centerXAnchor,
width: scrollView.widthAnchor,
height: nil)
// Setup Results Background
contentView.addSubview(resultBackgroundView)
resultBackgroundView.anchorXCenter(top: contentView.topAnchor,
bottom: nil,
centerAnchor: contentView.centerXAnchor,
width: contentView.widthAnchor,
height: nil,
padding: UIEdgeInsets(top: 90, left: 0, bottom: 0, right: 0),
widthOffset: -40)
// Setup Results Card
resultBackgroundView.addSubview(resultCardView)
resultCardView.anchorXCenter(top: resultBackgroundView.topAnchor,
bottom: resultBackgroundView.bottomAnchor,
centerAnchor: resultBackgroundView.centerXAnchor,
width: resultBackgroundView.widthAnchor,
height: nil)
setupResultsView(resultCardView)
}
func setupResultsView(_ resultCardView: UIView) {
let searchInput = "Hello"
let searchOutput = "Yo what's up dog congratulations"
// Configure Top Label
topLabel.attributedText = NSAttributedString(string: searchInput)
topLabel.configureBasedOnInput()
// Configure Bottom Label
bottomLabel.attributedText = NSAttributedString(string: searchOutput)
bottomLabel.configureBasedOnInput()
// Add Flashcard Button to its Background View
addFlashcardBackgroundView.addSubview(addFlashcardButton)
addFlashcardButton.anchor(top: addFlashcardBackgroundView.topAnchor,
bottom: addFlashcardBackgroundView.bottomAnchor,
leading: addFlashcardBackgroundView.leadingAnchor,
trailing: addFlashcardBackgroundView.trailingAnchor,
height: nil,
width: nil)
// Add subviews to Result Card
resultCardView.addSubview(topLabel)
resultCardView.addSubview(bottomLabel)
resultCardView.addSubview(soundButton)
resultCardView.addSubview(loopButton)
resultCardView.addSubview(lineDividerView)
resultCardView.addSubview(addFlashcardBackgroundView)
// Autolayout Constraints For Result Card Subviews
topLabel.translatesAutoresizingMaskIntoConstraints = false
topLabel.topAnchor.constraint(equalTo: resultCardView.topAnchor, constant: 10).isActive = true
topLabel.centerXAnchor.constraint(equalTo: resultCardView.centerXAnchor, constant: 0).isActive = true
topLabel.leadingAnchor.constraint(greaterThanOrEqualTo: resultCardView.leadingAnchor, constant: 10).isActive = true
topLabel.trailingAnchor.constraint(lessThanOrEqualTo: resultCardView.trailingAnchor, constant: -10).isActive = true
lineDividerView.anchor(top: topLabel.bottomAnchor,
bottom: nil, leading: resultCardView.leadingAnchor,
trailing: resultCardView.trailingAnchor,
height: 1,
width: nil,
padding: UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0))
loopButton.anchor(top: lineDividerView.bottomAnchor,
bottom: nil,
leading: nil,
trailing: resultCardView.trailingAnchor,
height: nil,
width: nil,
padding: UIEdgeInsets(top: 10, left: 0, bottom: 0, right: -10))
soundButton.anchor(top: lineDividerView.bottomAnchor,
bottom: nil,
leading: nil,
trailing: loopButton.leadingAnchor,
height: nil,
width: nil,
padding: UIEdgeInsets(top: 10, left: 0, bottom: 0, right: -10))
bottomLabel.translatesAutoresizingMaskIntoConstraints = false
bottomLabel.topAnchor.constraint(equalTo: soundButton.bottomAnchor, constant: 10).isActive = true
bottomLabel.centerXAnchor.constraint(equalTo: resultCardView.centerXAnchor, constant: 0).isActive = true
bottomLabel.leadingAnchor.constraint(greaterThanOrEqualTo: resultCardView.leadingAnchor, constant: 10).isActive = true
bottomLabel.trailingAnchor.constraint(lessThanOrEqualTo: resultCardView.trailingAnchor, constant: -10).isActive = true
addFlashcardBackgroundView.anchor(top: bottomLabel.bottomAnchor,
bottom: resultCardView.bottomAnchor,
leading: nil,
trailing: resultCardView.trailingAnchor,
height: 30,
width: 30,
padding: UIEdgeInsets(top: 10, left: 0, bottom: -10, right: -10))
}
//MARK:- Selector Functions
@objc func profileButtonTapped() {
print(0)
}
@objc func languageButtonPressed() {
print(1)
}
@objc func swapButtonPressed() {
print(2)
}
@objc func cancelButtonPressed() {
textView.text = ""
textView.textColor = .lightGray
textView.text = "Enter text"
cancelButton.isHidden = true
}
@objc func soundButtonPressed() {
print("soundButton")
}
@objc func loopButtonPressed() {
print("loopButton")
}
@objc func addFlashcardButtonPressed() {
print("adding flashcard")
}
}
输出:带圆圈的按钮是不工作的按钮
1条答案
按热度按时间vlurs2pr1#
我也遇到过类似的棘手问题,这让我损失了宝贵的生产时间......所以如果你有一个UIView,在这种情况下,一个UIButton作为另一个UIView的子视图。UILabel,确保父视图的
isUserInteractionEnabled = true
因为如果不是这样的话它会影响到所有其他的子视图