I want to reference a variable to a specific function.
However, there is an error called Value of type 'UIView' has no member 'lineTo'
Clearly, the whatSelectObject
variable contains the classes in which a member exists.
So I used If statement, "optional binding." But the results are the same.
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
class ObjectView: UIView {
var outGoingLine : CAShapeLayer?
var inComingLine : CAShapeLayer?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func lineTo(connectToObj: ObjectView) -> CAShapeLayer {
let path = UIBezierPath()
path.move(to: CGPoint(x: self.frame.maxX, y: self.frame.midY))
path.addLine(to: CGPoint(x: connectToObj.frame.minX, y: connectToObj.frame.midY))
let line = CAShapeLayer()
line.path = path.cgPath
line.lineWidth = 5
line.fillColor = UIColor.clear.cgColor
line.strokeColor = UIColor.gray.cgColor
connectToObj.inComingLine = line
outGoingLine = line
return line
}
}
class MyViewController : UIViewController {
var whatSelectView: UIView?
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let object = ObjectView(frame: CGRect(x: 10, y: 100, width: 100, height: 100))
object.backgroundColor = UIColor.orange
view.addSubview(object)
whatSelectView = object
let object2 = ObjectView(frame: CGRect(x: 200, y: 200, width: 100, height: 100))
object2.backgroundColor = UIColor.red
view.addSubview(object2)
if let s = whatSelectView {
view.layer.addSublayer(s.lineTo(connectToObj: object2)) // error
}
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
!This code is an example of a reduced code in question to help the respondent understand it.
I can refer directly to the object
variable, but I must refer to whatSelectView
without fail.
Why does cause an error in the reference variable? Or was I wrong with the Optional binding?
Indeed UIView does not have any member nor method called lineTo
, and you have to use casting (as?
in your case)
like this:
if let s = whatSelectView as? ObjectView {
view.layer.addSublayer(s.lineTo(connectToObj: object2)) // error
}
Beside that, the reference to whatSelectView
should be weak because view already keeps a strong reference to it since it object is a subview.
And you don't need the if condition at all, you already have reference to the view using object.
So, Here is my proposal for better implementation
class MyViewController : UIViewController {
weak var whatSelectView: ObjectView?
override func loadView() {
let view = UIView()
view.backgroundColor = .white
let object = ObjectView(frame: CGRect(x: 10, y: 100, width: 100, height: 100))
object.backgroundColor = UIColor.orange
view.addSubview(object)
whatSelectView = object
let object2 = ObjectView(frame: CGRect(x: 200, y: 200, width: 100, height: 100))
object2.backgroundColor = UIColor.red
view.addSubview(object2)
let shape = object.lineTo(connectToObj: object2)
view.layer.addSublayer(shape)
self.view = view
}
}