简体   繁体   English

从Swift中的另一个类访问ViewController中的变量

[英]Access variable in ViewController from a different class in Swift

I have a slider sliderLineSize and a variable lineSize in a ViewController. 我在ViewController中有一个滑块sliderLineSize和一个变量lineSize The UISlider sliderLineSize changes lineSize . UISlider sliderLineSize更改lineSize However, lineSize actually used in the drawRect section of the viewLine class which attaches to a UIView. 然而, lineSize实际上是在使用drawRect的第viewLine其附着到UIView类。

Question: 题:

How do I pass or make accessible the variable lineSize which is set in the ViewController to the class viewLine where it is used in drawRect ? 我如何传递或访问变量lineSize ,该变量在ViewController中设置为在drawRect使用的类viewLine

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myView: UIView!
    @IBOutlet weak var myImageView: UIImageView!

    var lineSize: Int = 1

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        myImageView.alpha = 0.5
    }

    @IBAction func sliderLineSize(sender: UISlider) {
        lineSize = Int(sender.value)
    }

}

class viewLine: UIView {

    let path=UIBezierPath()
    var incrementalImage:UIImage?
    var previousPoint:CGPoint = CGPoint.zero
    var strokeColor:UIColor?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func drawRect(rect: CGRect) {
            incrementalImage?.drawInRect(rect)
            path.lineWidth = lineSize
            path.stroke()
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touch: AnyObject? = touches.first
        let currentPoint = touch!.locationInView(self)
        path.moveToPoint(currentPoint)
        previousPoint=currentPoint
        self.setNeedsDisplay()
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let touch: AnyObject? = touches.first
        let currentPoint = touch!.locationInView(self)
        let midPoint = self.midPoint(previousPoint, p1: currentPoint)
        path.addQuadCurveToPoint(midPoint,controlPoint: previousPoint)
        previousPoint=currentPoint
        path.moveToPoint(midPoint)
        self.setNeedsDisplay()
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        self.drawBitmap()
        self.setNeedsDisplay()
        path.removeAllPoints()
    }

    func midPoint(p0:CGPoint,p1:CGPoint)->CGPoint {
        let x=(p0.x+p1.x)/2
        let y=(p0.y+p1.y)/2
        return CGPoint(x: x, y: y)
    }

    func drawBitmap() {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, 1)
        strokeColor?.setStroke()
        if((incrementalImage) == nil){
            let rectPath:UIBezierPath = UIBezierPath(rect: self.bounds)
            UIColor.whiteColor().setFill()
            rectPath.fill()
        }
        incrementalImage?.drawAtPoint(CGPointZero)
        path.stroke()
        incrementalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    }

}

There are two main ways to do this. 有两种主要方法可以做到这一点。

Option 1: 选项1:

Give your ViewLine class its own lineSize property: 给您的ViewLine类自己的lineSize属性:

class ViewLine: UIView {
    var lineSize = 1
}

Give ViewController a reference to ViewLine , and use a property observer to update the property inside viewLine whenever it changes in ViewController : ViewController一个对ViewLine的引用,并使用属性观察器在viewLine的属性在ViewController更改时进行更新:

class ViewController: UIViewController {

    // v~~~ be sure to connect this outlet in interface builder
    @IBOutlet weak var viewLine: ViewLine!

    var lineSize = 1 {
        didSet {
            viewLine.lineSize = lineSize
        }
    }
}

Now your ViewLine class will have its own lineSize property that can be accessed from within its drawRect method directly. 现在,您的ViewLine类将具有其自己的lineSize属性,可以直接从其drawRect方法内对其进行访问。

Option 2: 选项2:

Give your ViewLine class a reference to ViewController : 给您的ViewLine类提供对ViewController的引用:

class ViewLine: UIView {

    // v~~~ be sure to connect this outlet in interface builder
    @IBOutlet weak var controller: ViewController!
}

Now, in your drawRect method, replace path.lineWidth = lineSize with path.lineWidth = controller.lineSize . 现在,在您的drawRect方法中,将path.lineWidth = lineSize替换为path.lineWidth = controller.lineSize

Basically, one of your classes needs a reference to the other in order for them to be able to communicate. 基本上,您的一个类需要引用另一个类,以便它们能够进行通信。

You should make Singleton Model class. 您应该制作Singleton Model类。 A singleton class can be accessed from anywhere. 可以从任何地方访问单例类。 Here is how you should create a singleton class in swift. 这是您应该如何快速创建单例类的方法。

class ApplicationModel {

    class var sharedInstance: ApplicationModel {
        get {
            struct Static {
                static var instance: ApplicationModel? = nil
                static var token: dispatch_once_t = 0
            }
            dispatch_once(&Static.token, {
                Static.instance = ApplicationModel()
            })
            return Static.instance!
        }
    }

    var lineSize = 1
}

Inside ViewController 内部ViewController

override func viewDidLoad() {
        super.viewDidLoad()

        //Instantiate ApplicationModel
        //GET
        let lineSize = ApplicationModel.sharedInstance.lineSize

        //SET
        ApplicationModel.sharedInstance.lineSize = 5
    }

Inside viewLine 内视线

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

     //Access Application Model


            //GET
            let lineSize = ApplicationModel.sharedInstance.lineSize

            //SET
            ApplicationModel.sharedInstance.lineSize = 5
}

Hope this helps! 希望这可以帮助!

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

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