1

I have a joystick which takes to image views for thumb and joystick base as parameters. I need to add extra path between buttons and joystick to left as it is seen in the picture below. I could not get it done because of the circle itself is image view as a base.

Here is my code below:

enter image description here

class LiveControlJoystick: UIView {
    
    public var backgroundView: UIImageView!
    public var thumbView: UIImageView!
    
    private var xValue: CGFloat = 0.0
    private var yValue: CGFloat = 0.0
    private var radius: CGFloat = 0.0
    private var margin: CGFloat = 0.0
    
    public var delegate: SingleJoystickViewDelegate?
    public var form: JoystickType?
    public var blockedX: Bool!
    public var blockedY: Bool!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        print(frame)
        commonInit()
        self.backgroundView = UIImageView()
        self.thumbView = UIImageView()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        self.backgroundView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height))
        self.thumbView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.frame.height/3, height: self.frame.height/3))
        thumbView.center = CGPoint(x: backgroundView.frame.size.width  / 2,y:
            backgroundView.frame.size.height / 2);
        self.backgroundView.image = UIImage(named: "joyStickBase")
        self.thumbView.image = UIImage(named: "jThumb")
        addSubview(backgroundView)
        self.backgroundView.addSubview(thumbView)
        self.backgroundView.isUserInteractionEnabled = true
        self.thumbView.isUserInteractionEnabled = true
    }
    
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        handleFingerTouch(touches: touches)
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        handleFingerTouch(touches: touches)
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        handleFingerTouch(touches: touches)
        initJoystickCoordinate()
        didMove(distance: 0)
        delegate?.joystickViewDidEndMoving(self)
    }
    
    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        handleFingerTouch(touches: touches)
        initJoystickCoordinate()
        didMove(distance: 0)
        delegate?.joystickViewDidEndMoving(self)
    }
    
    //MARK: Private Methods
    private func commonInit() {
        xValue = 0.0
        yValue = 0.0
        margin = 0.0
        radius = 0.0
        form = .around
    }
    
    private func updateConstants() {
        margin = thumbView.frame.width/2
        radius = (bounds.width - 2 * margin) * 0.5
        if form == .vertical {
            margin = thumbView.frame.height/2
            radius = (bounds.height - 2 * margin) * 0.5
        }
        else {
            margin = thumbView.frame.width/2
            radius = (bounds.width - 2 * margin) * 0.5
        }
    }
    
    private func initJoystickCoordinate() {
        if thumbView != nil {
            thumbView.center = CGPoint(x: self.bounds.width/2, y: self.bounds.height/2)
        }
        xValue = 0.0
        yValue = 0.0
    }
    func blockX(){
        self.blockedX = true
    }
    
    func unBlockX(){
        self.blockedX  = false
    }
    
    func blockY(){
        self.blockedY = true
    }
    
    func unBlockY(){
        self.blockedY = false
    }
    
    
    
    private func handleFingerTouch(touches: Set<UITouch>) {
        updateConstants()
        var location: CGPoint = CGPoint(x: 0, y: 0)
        if let touch: UITouch = touches.first {
            location = touch.location(in: self)
            xValue = (location.x - margin) / radius - 1.0
            yValue = 1.0 - (location.y - margin) / radius
            
            var r: CGFloat = 0.0
            // All Blocked
            if((self.blockedY == true && self.blockedX == true) || (self.blockedX == true && self.blockedY == true)){
                // pass
            }
                // Only Horizontal
            else if(self.blockedY == true){
                yValue = 0
                r = abs(xValue * radius)
                if r >= radius {
                    yValue = 0
                    xValue = radius * (xValue / r)
                    location.x = (xValue + 1) * radius + margin
                    r = radius
                }
                let newX: CGFloat = location.x - thumbView.bounds.size.width * 0.5
                thumbView.frame = CGRect(origin: CGPoint.init(x: newX, y: thumbView.frame.origin.y), size: thumbView.frame.size)
            }
                // Only Vertical
            else if(self.blockedX == true){
                xValue = 0
                r = abs(yValue * radius)
                if r >= radius {
                    xValue = 0
                    yValue = radius * (yValue / r)
                    location.y = (-yValue + 1) * radius + margin
                    r = radius
                }
                let newY: CGFloat = location.y - thumbView.bounds.size.height * 0.5
                thumbView.frame = CGRect(origin: CGPoint.init(x: thumbView.frame.origin.x, y: newY ), size: thumbView.frame.size)
            }
                // All Directions
            else{
                print("NO BLOCK")
                r = sqrt(xValue * xValue + yValue * yValue) * radius
                if r >= radius {
                    xValue = radius * (xValue / r)
                    yValue = radius * (yValue / r)
                    
                    location.x = (xValue + 1) * radius + margin
                    location.y = (-yValue + 1) * radius + margin
                    r = radius
                }
                let newX: CGFloat = location.x - thumbView.bounds.size.width * 0.5
                let newY: CGFloat = location.y - thumbView.bounds.size.height * 0.5
                thumbView.frame = CGRect(origin: CGPoint.init(x: newX, y: newY), size: thumbView.frame.size)
            }
            let dis:Float = (Float)(r/radius)
            didMove(distance: dis)
        }
    }
    
    private func didMove(distance: Float){
        let angle: Int = (Int)(-180 * atan2(Double(yValue), Double(xValue)) / Double.pi)
        delegate?.joystickView(self, didMoveto: angle, distance: distance,xPos: Double(xValue),yPos:Double(yValue))
    }
    
    
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Habil Ganbarli
  • 213
  • 2
  • 7
  • 14
  • You need to be much more clear... you show an image and say you *"need to add extra path between buttons and joystick*" --- but we have no way of knowing what you mean just by looking at that picture. – DonMag Jun 30 '20 at 13:07
  • Note that we prefer a technical style of writing here. We gently discourage greetings, hope-you-can-helps, thanks, advance thanks, notes of appreciation, regards, kind regards, signatures, please-can-you-helps, chatty material and abbreviated txtspk, pleading, how long you've been stuck, voting advice, meta commentary, etc. Just explain your problem, and show what you've tried, what you expected, and what actually happened. – halfer Aug 03 '20 at 09:38
  • `layoutSubviews()` must not create or delete views. It should only reposition existing sub views. Please move most code into `init()` and create a new `layoutSubviews()` method updating positions only. – Codo Aug 03 '20 at 10:43
  • *"I could not get it done"*: Can you be more specific? What do you expect to happen? What happens instead? Does it fail to compile? Does it crash at run-time? Does it not show up on screen? – Codo Aug 03 '20 at 10:44

0 Answers0