如何从另一个 UIView 类访问 UIControl 的值

Posted

技术标签:

【中文标题】如何从另一个 UIView 类访问 UIControl 的值【英文标题】:How to access the value of a UIControl from another UIView class 【发布时间】:2020-01-18 02:52:01 【问题描述】:

初学者问题。我在故事板上有一个 UISlider,在 ViewController 之外的另一个 UIView 类中,我想使用滑块的值来更改 makeShape() 函数中的路径/形状变量。

我试过了:

a) 在OtherView中,尝试直接引用ViewController的全局变量val。这会导致“未解析的标识符”

b) 在 ViewController 中,尝试将 mySlider.value 分配给在 OtherView 中声明的变量 otherVal。这会导致“Instance member 'otherVal' cannot be used on type '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)
    

【问题讨论】:

在视图控制器中创建 UIView 对象的 IBOutlet 实例。 @IBOutlet weak var otherView: UIView! 喜欢吗?我把它放在另一个插座下方的 ViewController 中,然后尝试func setOtherVal() otherView.otherVal = val,我得到“'UIView' 类型的值没有成员'otherVal'”。这是你的意思吗? “我把它放在 ViewController 中,就在另一个插座的下方”我没看到。 编辑了问题。 otherView.otherVal = sender.value;其他ViewmakeShape() 【参考方案1】:

现在,您正尝试访问 OtherVal 类的 ViewController 中的 otherVal 属性,该属性在整个应用程序中全局共享,而不是您在 @987654324 中创建的 OtherVal 实例上的属性@。

这里最简单的解决方法是将您创建的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 可以使用。

编辑:如 cmets 中所述,您还可以在情节提要/笔尖中设置自定义视图并创建插座。现在看起来你的代码并没有设置为可以使用它。

【讨论】:

以上是关于如何从另一个 UIView 类访问 UIControl 的值的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 从另一个函数访问 UIView 的实例

如何从另一个类执行 collectionView 方法?

如何从另一个类访问小部件

如何从另一个类访问mysql数据库中的变量?

如何从另一个类访问函数?

使用 UIView 中的按钮从另一个 ViewController 触发方法