在 Swift 中的 ONE ViewController 中的视图之间传递数据

Posted

技术标签:

【中文标题】在 Swift 中的 ONE ViewController 中的视图之间传递数据【英文标题】:Passing data between views in ONE ViewController in Swift 【发布时间】:2015-04-29 03:57:59 【问题描述】:

我所做的所有搜索都集中在视图控制器之间传递数据。这不是我真正想要做的。我有一个 ViewController 里面有多个视图。 ViewController 有一个可以正常工作的滑块:

var throttleSetting = Float()
@IBAction func changeThrottleSetting(sender: UISlider)

    throttleSetting = sender.value   

然后,在同一个 ViewController 中包含的一个视图中,我有一个基本行(现在)设置一个初始值,稍后在代码的 DrawRect 部分中使用该值:

var RPMPointerAngle: CGFloat 
    var angle: CGFloat = 2.0
    return angle

我想要做的是将 ViewController 中的滑块值传递给 ViewController 中包含的 View 以允许 drawRect 是动态的。

感谢您的帮助!

【问题讨论】:

Views是指其他ViewController的Views被一个ContainerViewController控制吗? 不,我认为我的问题可能是我并没有真正使用 MVC 方法,因为它应该被使用(我还在学习)。现在我的应用只有一个 ViewController。在那个 ViewController 中,我有多个视图(即您可以从对象库中拖动的通用视图。其中一个视图专门用于使用我最终希望来自其他视图的变量来绘制一堆 BezierPaths屏幕(现在变量只是静态值,所以我可以让 BezierPaths 看起来正确)。我希望滑块能够影响不同视图中的值。 我不太确定你做了什么(因为你提供的代码是有限的)但我认为要更改滑块,你可以使用委托。如果你不知道什么是委托,我可以为你解释一下。 【参考方案1】:

编辑:对不起,当我创建这个答案时,我想到了 ViewControllers。更简单的方法是在 SomeView 中创建一个方法并直接与其对话。

例子:

class MainViewController: UIViewController 

    var view1: SomeView!
    var view2: SomeView!

    override func viewDidLoad() 
        super.viewDidLoad()

        // Create the views here
        view1 = SomeView()
        view2 = SomeView()

        view.addSubview(view1)
        view.addSubview(view2)
    

    @IBAction func someAction(sender: UIButton) 
        view1.changeString("blabla")
    


class SomeView: UIView 

    var someString: String?

    func changeString(someText: String) 
        someString = someText
    

代表:

首先你创建一个协议:

protocol NameOfDelegate: class      // ": class" isn't mandatory, but it is when you want to set the delegate property to weak
    func someFunction()              // this function has to be implemented in your MainViewController so it can access the properties and other methods in there

在您的视图中,您必须添加:

class SomeView: UIView, NameOfDelegate 

    // your code

    func someFunction() 

        // change your slider settings
    

最后一步,您必须添加委托的属性,以便您可以与它“交谈”。就我个人而言,我认为这个属性是某种门,位于两个类之间,因此它们可以相互交谈。

class MainViewController: UIViewController 

    weak var delegate: NameOfDelegate?

    @IBAction func button(sender: UIButton) 
        if delegate != nil 
            let someString = delegate.someFunction()
        
    

我在这里使用了一个按钮来展示如何使用委托。只需将其替换为滑块即可更改视图的属性

编辑:我忘了提到的一件事是,您需要以某种方式将 SomeView 指定为委托。但就像我说的,我不知道你是如何创建视图等的,所以我无法帮助你。

【讨论】:

谢谢!我会试一试,然后回复你。 所以,当我输入所有代码时,除了 UIView 之外,一切似乎都正常工作,我收到一条错误消息,提示“Type SomeView”不符合“NameOfDelegate”。对此有什么想法吗? 这意味着您没有在SomeView 中实现所需的功能。在这种情况下,这意味着您将拥有与您在委托协议中创建的方法完全相同的方法:func someFunction() -> String。我注意到示例正在返回一个字符串,我认为您不需要它。以防万一,我会编辑我的答案。 谢谢!您的编辑回答了 90% 的问题。这是我现在在 ViewController 中的内容:@IBOutlet weak var compactEngineView: BasicEngineGuagesUIView! @IBAction func changeThrottleSetting(sender: UISlider) compactEngineView.RPMPointerAngleInt = Int(sender.value) println("\(compactEngineView.RPMPointerAngleInt)") 然后在 View 中,我有这个:var RPMPointerAngleInt = Int() 代码运行得很好,但是当 View 中的 var 为由滑块更新。有什么技巧可以让 DrawRect 不断更新吗? 100% 解决了!在你和@Foebe 之间,我得到了它的工作!非常感谢!【参考方案2】:

在 MVC 模型中,视图不能直接相互通信。 总是有一个视图控制器来管理视图。视图就像控制器的奴才一样。 所有通信都通过视图控制器进行。

如果您想对某些视图更改做出反应,可以设置IBAction。然后,您可以在该方法中更改您可能拥有IBOutlet 的其他视图。

因此,在您的示例中,您可能有一个 IBAction 用于更改滑块的值(如在您的原始问题中),您可以从中设置一些您想要更改的视图的公共属性。如有必要,您还可以在目标视图上调用 setNeedsDisplay() 以使其重绘。

【讨论】:

以上是关于在 Swift 中的 ONE ViewController 中的视图之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift中将字符串“One”的字符转换为整数“1”[关闭]

从 App Delegate (Swift) 调用 ViewControllers 方法或 Segue

在 Swift 中使用 Set 时出现编译器分段错误

在iOS8中使用Swift更改特定ViewControllers的状态栏颜色

iPhone 上 Swift 中的图像缩放问题

ios swift 判断uiviewcontroller时push present 进来的 还是pop进来的