如何从另一个 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 的值的主要内容,如果未能解决你的问题,请参考以下文章