Как получить доступ к значению UIControl из другого класса UIView - PullRequest
0 голосов
/ 18 января 2020

Вопрос новичка. У меня есть UISlider на раскадровке, и в другом классе UIView, кроме ViewController, я хотел бы использовать значение ползунка для изменения переменных пути / формы в функции makeShape ().

Я попытался:

a) В OtherView попробуйте напрямую обратиться к глобальной переменной ViewController val. Это приводит к «неразрешенному идентификатору»

b) В ViewController попытайтесь присвоить mySlider.value переменной, объявленной в OtherView, otherVal. Это приводит к тому, что «член экземпляра otherVal нельзя использовать для типа« OtherView »».

Может кто-нибудь помочь мне узнать, как это сделать правильно?

ViewController.swift:

class ViewController: UIViewController {

    var val: CGFloat = 0.0

    @IBOutlet weak var mySlider: UISlider!

    @IBOutlet weak var otherView: UIView!

    @IBAction func mySliderChanged(_ sender: Any) {
        val = CGFloat(mySlider.value)
        setOtherVal()
    }

    func setOtherVal() {
        otherView.otherVal = val
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let otherView = OtherView(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 100, height: 100)))

        self.view.addSubview(otherView)
    }
}

OtherView.swift:

class OtherView: UIView {

    var path: UIBezierPath!

    var otherVal: CGFloat = 0.0

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.backgroundColor = UIColor.clear
        makeShape()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func makeShape() {
        let width: CGFloat = self.frame.size.width
        let height: CGFloat = self.frame.size.height

        let path1 = UIBezierPath(ovalIn: CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 50, height: 50)))

        let shapeLayer1 = CAShapeLayer()
        shapeLayer1.path = path1.cgPath
        shapeLayer1.fillColor = UIColor.blue.cgColor

        self.layer.addSublayer(shapeLayer1)

        shapeLayer1.position = CGPoint(x: otherVal, y: height)
    }
}

1 Ответ

0 голосов
/ 18 января 2020

Прямо сейчас вы пытаетесь получить доступ к свойству otherVal в ViewController класса OtherVal, который используется глобально для всего приложения, а не к свойству экземпляра OtherVal, который вы создали в ViewController.

Самое простое решение - сохранить экземпляр OtherView, созданный вами в viewDidAppear, и использовать это свойство для обновления представления.

class ViewController: UIViewController {

    var val: Float = 0.0
    @IBOutlet weak var mySlider: UISlider!

    // Add a property to hold on to the view after you create it. 
    var otherView: OtherView?

    @IBAction func mySliderChanged(_ sender: Any) {
        val = mySlider.value
        setOtherVal()
    }

    func setOtherVal() {
        // `val` is a Float and `otherVal` is a `CGFloat` so we have to convert first.
        let newValue = CGFloat(self.val)
        // Use the property that's holding your view to update with the new value from the slider.
        self.otherView?.otherVal = newValue
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let otherView = OtherView(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 100, height: 100)))

        // Set the property to the view you just created so you can update it later.
        self.otherView = otherView

        self.view.addSubview(otherView)
    }
}

В настоящее время, хотя он не выглядит вы на самом деле обновляете OtherView после установки нового значения, поэтому вы захотите сделать что-то подобное там. Сохраняйте ссылку на CAShapeLayer, которую вы создаете, и обновляйте позицию при изменении otherVal.

Также обратите внимание, что viewDidAppear может вызываться несколько раз в течение жизненного цикла контроллера представления. Если вы хотите добавить представление только один раз, вы должны использовать viewDidLoad, который гарантирует, что у вас будет только что созданный self.view для работы.

Редактировать: Как уже упоминалось в комментариях, вы также можете настроить собственное представление в раскадровке / перо и создать розетку. Хотя сейчас не похоже, что ваш код настроен для работы с этим.

...