如何从另一个 UIView 访问 UIControl 的值 class
How to access the value of a UIControl from another UIView class
初学者问题。我在故事板上有一个 UISlider,在另一个 UIView class 除了 ViewController 之外,我想使用滑块的值来更改 makeShape() 函数中的 path/shape 变量。
我试过:
a) 在OtherView中,尝试直接引用ViewController的全局变量val
。这导致 "unresolved identifier"
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)
}
}
现在您正在尝试访问 class OtherVal
上的 ViewController
中的 otherVal
属性,该 otherVal
属性 通过整个应用程序在全球范围内共享,而不是您在 ViewController
中创建的 OtherVal 实例上的 属性。
此处最简单的解决方法是存储您在 viewDidAppear
中创建的 OtherView
实例并使用该 属性 更新视图。
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
可以使用。
编辑:如评论中所述,您还可以在情节提要/笔尖中设置自定义视图并创建插座。不过,现在看起来您的代码并未设置为使用它。
初学者问题。我在故事板上有一个 UISlider,在另一个 UIView class 除了 ViewController 之外,我想使用滑块的值来更改 makeShape() 函数中的 path/shape 变量。
我试过:
a) 在OtherView中,尝试直接引用ViewController的全局变量val
。这导致 "unresolved identifier"
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)
}
}
现在您正在尝试访问 class OtherVal
上的 ViewController
中的 otherVal
属性,该 otherVal
属性 通过整个应用程序在全球范围内共享,而不是您在 ViewController
中创建的 OtherVal 实例上的 属性。
此处最简单的解决方法是存储您在 viewDidAppear
中创建的 OtherView
实例并使用该 属性 更新视图。
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
可以使用。
编辑:如评论中所述,您还可以在情节提要/笔尖中设置自定义视图并创建插座。不过,现在看起来您的代码并未设置为使用它。