更改variables时更新UILabel文本

我有一个UIControl类,需要根据UIImageView位置进行一些计算,这个位置可以通过touchesBegan和touchesMoved(这个类中的所有东西)来移动。 比我想显示它作为我已经编程创build的UILabel。

class control : UIControl{ ... let leftControl: UIImageView = UIImageView(image: UIImage(named: "left-control")) ... func leftValue() -> String{ var leftValue : String = "0.0" leftValue = "\(leftControl.center.x)" return leftValue } } 

和我的ViewController.swift

class ViewController:UIViewController {

 let ctrl : Control = Control() let leftLabel : UILabel = UILabel(frame: CGRect(x: 40, y: 300, width: 150, height: 30)) override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. ctrl.frame.origin = CGPoint(x: 40, y: 400) leftLabel.text = "\(ctrl.leftValue())" //displays only starting value view.addSubview(slider) view.addSubview(leftLabel) view.addSubview(rightLabel) } 

我知道它在viewDidLoad里面,所以没有正确更新。 我想知道有关scheduledTimer,但不知道是否是好的解决scheme。

你可以使用协议和委托来实现这一点 – 在你的Control文件添加这个:

 protocol ControlDelegate: class { func controlPositionDidChange(leftValue: String) } 

并添加一个weak var delegate: ControlDelegate? 内部Control类。

在视图控制器的文件进行以下更改:

 class ViewController: UIViewController, ControllDelegate { let ctrl : Control = Control() let leftLabel : UILabel = UILabel(frame: CGRect(x: 40, y: 300, width: 150, height: 30)) override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. ctrl.frame.origin = CGPoint(x: 40, y: 400) ctrl.delegate = self leftLabel.text = "\(ctrl.leftValue())" //displays only starting value view.addSubview(slider) view.addSubview(leftLabel) view.addSubview(rightLabel) } func controlPositionDidChange(leftValue: String) { leftLabel.text = leftValue } } 

现在,只要你想通知代表你的控件已经改变了位置,只需在适当的位置调用self.delegate?.controlPositionDidChange(self.leftValue())

通常情况下, 文档中有更多。 我强烈build议通过它们阅读,因为委托和协议在CocoaTouch中被广泛使用。

@Losiowaty的答案描述了大多数开发人员select的解决scheme。 但是(在我看来)有更好的方法来实现它。 我更喜欢面向对象的解决scheme。 它可能看起来像更多的代码,但它更好的可维护的方式与更多的可重用的代码。

一个真正面向对象的解决scheme可能看起来像这样:

 // reusable protocol set protocol OOString: class { var value: String { get set } } // reusable functional objects final class RuntimeString: OOString { init(initialValue: String = "") { self.value = initialValue } var value: String } final class ViewUpdatingString: OOString { init(_ decorated: OOString, view: UIView) { self.decorated = decorated self.view = view } var value: String { get { return decorated.value } set(newValue) { decorated.value = newValue view.setNeedsLayout() } } private let decorated: OOString private let view: UIView } // reusable ui objects final class MyLabel : UILabel { init(frame: CGRect, imageXCenter: OOString) { self.imageXCenter = imageXCenter super.init(frame: frame) } required init?(coder aDecoder: NSCoder) { fatalError("Not supported") } override func layoutSubviews() { super.layoutSubviews() text = imageXCenter.value } private let imageXCenter: OOString } final class MyControl : UIControl { init(frame: CGRect, imageXCenter: OOString) { self.imageXCenter = imageXCenter super.init(frame: frame) } required init?(coder aDecoder: NSCoder) { fatalError("Not supported") } private let imageXCenter: OOString private let leftControl = UIImageView(image: UIImage(named: "left-control")) // call this at change private func updateValue() { imageXCenter.value = "\(leftControl.center.x)" } } // non reusable business logic final class MyViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let dependency = RuntimeString(initialValue: "unset") let leftLabel = MyLabel( frame: CGRect(x: 40, y: 300, width: 150, height: 30), imageXCenter: dependency ) let control = MyControl( frame: CGRect(x: 40, y: 400, width: 400, height: 400), imageXCenter: ViewUpdatingString(dependency, view: leftLabel) ) view.addSubview(leftLabel) view.addSubview(control) } } 

主要思想是将两个对象的依赖关系提取到另一个对象中,然后使用装饰器自动更新每个设置值的UI。

注意:

  • 这种方法遵循面向对象编码的规则(干净的编码,优雅的对象,装饰者模式,…)
  • 可重复使用的类是非常简单的构build和完成一个任务
  • 类通过协议彼此进行通信
  • 尽可能dependency injectiondependency injection
  • 内部对象function是私有的(松耦合)
  • 一切(除了业务逻辑)是为重复使用而devise的 – >如果你的代码是这样的,可重复使用的代码组合随着代码的增长而增长
  • 你的应用程序的业务逻辑更集中在一个地方(在我真正的编码,甚至在UIViewController之外)
  • unit testing可重复使用的对象非常简单,当使用协议的虚假实现(甚至在大多数情况下不需要嘲笑)
  • 保留周期较less的问题,在大多数情况下,您不再需要弱性质
  • 避免零,零和选项(他们污染你的代码)