Я пытаюсь создать UIView
непрямоугольной формы с сенсорной областью не прямоугольной формы. Я уже знаю, как нарисовать мою фигуру с помощью более изящных контуров.
Согласно этому комментарию , мне нужно переопределить point(inside:with:)
, чтобы создать сенсорную область произвольной формы.
Итак, я попробовал это:
class MyView: UIView {
override func draw(_ rect: CGRect) {
let path = UIBezierPath()
path.move(to: .zero)
path.addLine(to: CGPoint(x: 0, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.midY))
path.addLine(to: CGPoint(x: bounds.midX, y: bounds.midY))
path.addLine(to: CGPoint(x: bounds.midX, y: 0))
path.addLine(to: CGPoint(x: 0, y: 0))
UIColor.red.setFill()
path.fill()
}
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
print("point(inside:with:) called")
func isInRegion(_ point: CGPoint) -> Bool {
return (0...bounds.midX).contains(point.x) || (bounds.midY...bounds.maxY).contains(point.y)
}
guard let touches = event?.touches(for: self) else { return false }
guard !touches.isEmpty else { return false }
print("passed all the guards")
let first = touches.first!
print("first touch: \(first.location(in: self))")
return touches.map { $0.location(in: self) }.contains(where: isInRegion)
}
}
Метод draw
рисует красную форму L. И я попробовал включить касание только внутри формы L.
Я создал MyView
с именем blueView
, сделал его фон синим, чтобы область касания была красной, а область без касания - синей.
Я также добавил обычный зеленый UIView
под частью синего, как это:
Я включил взаимодействие с пользователем для обоих этих видов и добавил UITapGestureRecogniser
с, чтобы при нажатии на красную область печаталось blue view tapped
. Если нажать на зеленый вид, будет напечатано green view tapped
.
override func viewDidLoad() {
super.viewDidLoad()
blueView.isUserInteractionEnabled = true
greenView.isUserInteractionEnabled = true
blueView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(blueViewTapped)))
greenView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(greenViewTapped)))
}
@objc func blueViewTapped() {
print("Blue view tapped")
}
@objc func greenViewTapped() {
print("Green view tapped")
}
Когда я запускаю приложение и нажимаю на красный бит, только point(inside:with:) called
печатается дважды и ничего больше. Я ожидал, что blue view tapped
и все другие операторы печати в point(inside:with:)
также будут выполнены. Если я коснусь синего бита, одно и то же сообщение будет напечатано дважды снова. Если я коснусь зеленого бита, который покрыт синим битом, Green view tapped
печатается после того, как point(inside:with:) called
напечатано дважды.
Почему blue view tapped
не напечатано? Должно быть, я неправильно реализовал point(inside:with:)
, верно?
EDIT:
После некоторой отладки я обнаружил, что причина, по которой point(inside:with:)
не возвращает true, заключается в том, что event.allTouches
пусто. Это очень странно, потому что я на 100% уверен, что коснулся вида!