Это моя кнопка:
import UIKit
class PassButton: UIButton {
var videoVC: VideoGameVC?
required init(isEnabled: Bool = false) {
super.init(frame: .zero)
self.isEnabled = true
self.addTarget(self, action: #selector(pressed(_:)), for: .touchUpInside)
let imageViewBackground = UIImageView(frame: CGRect(x:0, y:0, width: 70, height: 80))
imageViewBackground.image = UIImage(named: "pass_button")
imageViewBackground.contentMode = UIView.ContentMode.scaleAspectFill
addSubview(imageViewBackground)
sendSubviewToBack(imageViewBackground)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func pressed(_ sender: UIButton) {
print("presovan")
}
}
и вот как я добавляю его в другой контроллер представления:
func configPassButton() {
passButton = PassButton()
guard let passButton = passButton else { return }
view.addSubview(passButton)
passButton.translatesAutoresizingMaskIntoConstraints = false
passButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
passButton.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 20).isActive = true
}
он отображается так, как я хочу, но область, которую можно коснуться, очень мала. Постукивать можно только в верхнем левом углу, причем очень маленьком (около 10% всей поверхности). Как я могу исправить, чтобы все можно было нажимать?
@ Ларме, ты прав. Однако imageViewBackground является частью кнопки, разве он не должен быть также доступен для нажатия? Я не понимаю...
@VladimirDespotovic, пожалуйста, проверьте это stackoverflow.com/a/78422934/23301405
@VladimirDespotovic - «imageViewBackground является частью кнопки, разве на нее тоже нельзя нажимать?» -- нет... вы добавили подпредставление, выходящее за пределы кнопки. Вам следует использовать .setBackgroundImage
. Если вам нужна «кнопка изображения» с .scaleAspectFill
, вам нужно сначала изменить размер и обрезать изображение или использовать UIImageView
и добавить жест касания.
Вместо того, чтобы вручную добавлять подпредставление для фонового изображения, возможно, используйте свойство .setBackgroundImage() кнопки. Кроме того, размер кадра был установлен для ImageView, но, если я не заметил этого, размер кадра не был установлен для самой кнопки. Возможно, поэтому область нажатия кнопки не полностью соответствует размеру изображения.
Чтобы исправить это, удалите эти строки, устанавливающие фоновое изображение:
let imageViewBackground = UIImageView(frame: CGRect(x:0, y:0, width: 70, height: 80))
imageViewBackground.image = UIImage(named: "pass_button")
imageViewBackground.contentMode = UIView.ContentMode.scaleAspectFill
addSubview(imageViewBackground)
sendSubviewToBack(imageViewBackground)
И замените приведенные выше строки этими, чтобы установить фоновое изображение кнопки, режим содержимого, ширину и высоту:
self.setBackgroundImage(UIImage(named: "pass_button"), for: .normal)
self.layoutIfNeeded()
self.subviews.first?.contentMode = .scaleAspectFill
self.widthAnchor.constraint(equalToConstant: 70).isActive = true
self.heightAnchor.constraint(equalToConstant: 80).isActive = true
После этих изменений кнопка должна стать полностью доступной для нажатия.
Другой вариант
Мне только что пришло в голову, что если вы хотите использовать подпредставление imageViewBackground вместо .setBackgroundImage(), установка размера кнопки, а затем обрезка фонового изображения также будет работать. Например, добавив это после sendSubviewToBack():
self.widthAnchor.constraint(equalToConstant: 70).isActive = true
self.heightAnchor.constraint(equalToConstant: 80).isActive = true
self.clipsToBounds = true
Предположим, у вас есть изображение с соотношением сторон 70:80. например это:
Ваш код отображает это следующим образом:
но, как вы знаете, вы можете нажать только в верхнем левом углу.
Если мы добавим к кнопке красную рамку в 2 точки:
passButton.layer.borderColor = UIColor.red.cgColor
passButton.layer.borderWidth = 2
это выглядит так:
рамка кнопки - это только 30 x 34
... и 70 x 80
imageView выходит за пределы кнопки. Таким образом, можно нажать только на саму рамку кнопки.
Если вы задаете ограничения ширины и высоты кнопки:
passButton.widthAnchor.constraint(equalToConstant: 70.0).isActive = true
passButton.heightAnchor.constraint(equalToConstant: 80.0).isActive = true
то мы видим это:
и всю кнопку можно нажать.
Однако добавление UIImageView
в качестве подпредставления — ужасный подход.
Гораздо более уместно установить свойство фонового изображения:
// safely handle optional
if let img = UIImage(named: "pass_button") {
setBackgroundImage(img, for: [])
}
Опять же, нам также необходимо установить ограничения ширины и высоты, но теперь мы используем «стандартную» кнопку вместо подкласса с добавленными подпредставлениями:
let passButton = UIButton()
passButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(passButton)
NSLayoutConstraint.activate([
passButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20.0),
passButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20.0),
passButton.widthAnchor.constraint(equalToConstant: 70.0),
passButton.heightAnchor.constraint(equalToConstant: 80.0),
])
if let img = UIImage(named: "pass_button") {
passButton.setBackgroundImage(img, for: [])
}
Если соотношение сторон вашего изображения не такое же, как у вашей кнопки, нужно еще немного поработать... но при использовании исходного кода у вас возникнет та же проблема - поэтому я предполагаю, что вы используете изображение с соотношением сторон 70:80
. для начала.
addSubview(imageViewBackground)
, подумайте, что это представление блокирует... Вы можете использовать иерархию представлений отладки, и вы можете это увидеть.