Как проверить несколько подпредставлений UIView, отображаемых друг над другом, на наличие события касания в пределах пути Безье? - PullRequest
0 голосов
/ 26 августа 2018

Я написал некоторый код, который генерирует клины колеса в UIViews, сохраняет эти UIViews в массиве и отображает эти UIViews друг над другом, внутри контейнера UIView.Это в основном рисует сегментированное колесо.

Теперь я хочу, чтобы каждый UIView получал события касания индивидуально в пределах своего заданного пути Безье и возвращал уникальный идентификатор.На практике это означало бы, что каждый клин колеса - это отдельная кнопка.

Проблема, с которой я столкнулся сейчас, заключается в том, что только последний UIView, добавленный в массив, реагирует на одно касание (у меня это есть).настроить печать местоположения касания в пределах пути Безье прямо сейчас), после чего UIView, добавленный до этого, отвечает на одно событие касания, пока я не перебрал все клинья / UIViews, и ни один из них больше не отвечает на события касания.

Вот класс, который рисует клинья;Я попытался реализовать некоторые методы, которые позволят передавать сенсорные события в другие UIViews в конце кода, но я не могу заставить его работать.

import UIKit

class WedgeDraw: UIView {

var wedgeNumber:CGFloat = 4
var wedgeLocation: CGFloat = 2

var wedgeIdentifier = 0
var wedgePath = UIBezierPath()
var touchPosition = CGPoint()


override func draw(_ rect: CGRect) {

    let startAngle = (360 / wedgeNumber - 360) * (wedgeLocation - 1) * CGFloat.pi / 180
    let endangle = (360 / wedgeNumber - 360) * wedgeLocation * CGFloat.pi / 180


    let center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)

    let outerRadius = self.bounds.midX - 3
    let innerRadius = self.bounds.width / 8

    //defines end points of simulated Bezier archs as a CGpoint
    let endPointInner = UIBezierPath(arcCenter: center, radius: innerRadius, startAngle: startAngle, endAngle: endangle, clockwise: false).currentPoint
    let endPointOuterCounterclockwise = UIBezierPath(arcCenter: center, radius: outerRadius, startAngle: endangle, endAngle: startAngle, clockwise: true).currentPoint

    //defines bezier arch curves
    let outerWedgeCurvePath = UIBezierPath(arcCenter: center, radius: outerRadius, startAngle: startAngle, endAngle: endangle, clockwise: true)
    let innerWedgeCurvePath = UIBezierPath(arcCenter: center, radius: innerRadius, startAngle: endangle, endAngle: startAngle, clockwise: false)

    //draw line path

    wedgePath.append(outerWedgeCurvePath)
    wedgePath.addLine(to: endPointInner)
    wedgePath.append(innerWedgeCurvePath)
    wedgePath.addLine(to: endPointOuterCounterclockwise)

    //sets stroke and color properties and draws the bezierpath.

    UIColor.black.setStroke()
    UIColor.white.setFill()
    wedgePath.lineWidth = 3
    wedgePath.stroke()
    wedgePath.fill()


}

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    let view = super.hitTest(point, with: event)
    if wedgePath.contains(touchPosition) {
        return nil
    } else {
        return view
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    if let touch = touches.first {
        touchPosition = touch.location(in: self)

        if wedgePath.contains(touchPosition){
            print(touchPosition)
            print(isUserInteractionEnabled)
        } else {

        }
    }
}
}

Вот код Viewcontroller, который создаетмассив и рисует колесо:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var boardContainer: UIView!

@IBAction func checkButton(_ sender: UIButton) {

}

var wedgeViewConstructorArray = [WedgeDraw]()


override func viewDidLoad() {
    super.viewDidLoad()

    //creates array of UNIQUE wedgedraw objects
    for _ in 1...6 {
        wedgeViewConstructorArray.append(WedgeDraw())
    }
    drawBoard()
}

func drawBoard() {

    for i in 0..<wedgeViewConstructorArray.count {
        wedgeViewConstructorArray[i].wedgeIdentifier = i

        wedgeViewConstructorArray[i].frame = CGRect(x: 0, y: 0, width: boardContainer.frame.width, height: boardContainer.frame.height)

        wedgeViewConstructorArray[i].wedgeNumber = CGFloat(wedgeViewConstructorArray.count)
        wedgeViewConstructorArray[i].wedgeLocation = CGFloat(i + wedgeViewConstructorArray.count + 1)
        wedgeViewConstructorArray[i].backgroundColor = UIColor.clear

        boardContainer.addSubview(wedgeViewConstructorArray[i])
    }
}  
}

Вот так выглядит рендеринг колеса и иерархия вида:

Wheelimage

Я все еще очень новичок в программировании и быстром программировании в целом, и я очень счастлив получить то, что я нахожусь, но я действительно застрял сейчас и понятия не имею, как поступить.Надеюсь, мне удалось прояснить, в чем моя проблема!Заранее спасибо!

1 Ответ

0 голосов
/ 02 сентября 2018

Хорошо, мне понадобилось время, чтобы найти ответ, но на самом деле это удивительно легко.Это то, что я получил прямо сейчас, и это прекрасно работает для того, что мне нужно.

    // checks if point inside touch event is inside bezier path and passes on to next subview if false.
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
            let location = point
            if wedgePath.contains(location) == true {
                print("\(wedgeColor)")
                return true


    }
    return false

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...