简体   繁体   English

为什么'UIView'类型的值没有引用UIView变量的成员?

[英]Why value of type 'UIView' has no member from reference UIView variable?

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. 但是,存在一个错误,名为Value of type 'UIView' has no member 'lineTo'显然, whatSelectObject变量包含成员所在的类。 So I used If statement, "optional binding." 因此,我使用了If语句“可选绑定”。 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. 我可以直接引用object变量,但是我必须whatSelectView引用whatSelectView

Why does cause an error in the reference variable? 为什么在参考变量中引起错误? Or was I wrong with the Optional binding? 还是我对Optional绑定有误?

Indeed UIView does not have any member nor method called lineTo , and you have to use casting ( as? in your case) 实际上,UIView没有任何名为lineTo成员或方法,并且您必须使用强制转换(在您的情况下as? )。

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. 除此之外,对whatSelectView的引用应该是弱的,因为视图已经保持了对它的强引用,因为它的对象是一个子视图。

And you don't need the if condition at all, you already have reference to the view using object. 而且您根本不需要if条件,您已经具有使用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
    }
}
if let s = whatSelectView as? ObjectView {
   view.layer.addSublayer(s.lineTo(connectToObj: object2))
}

this should resolve your problem. 这应该可以解决您的问题。

Change 更改

var whatSelectView: UIView?

to

var whatSelectView: ObjectView?

and it will compile. 它将编译。 As @Larme said, when you declare it as a simple UIView , then you can't access any members & functions that are on subclasses of UIView . 正如@Larme所说,当您将其声明为简单的UIView ,您将无法访问UIView 子类上的任何成员和函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM