iOS: 如何让一个视图触发另一个视图的更新?

iOS: how can I make one view trigger an update in another?

我的顶层 UIView 包含一些标签和绘图 canvas。绘图 canvas 本身就是一个 UIView,它覆盖了它的 drawRect() 方法 ,当然还有各种 触摸方法 。当用户完成绘制后,我想更新 canvas 之外的一个或多个标签(即所有组件都是顶层 UIView)。

最好的方法是什么?
我目前有顶层 UIViewController 从顶层 viewDidLoad() 将各种标签传递到我的 CanvasView方法 并且我将它们存储在本地。每当我需要更新标签时,我都会从我拥有的这些兄弟视图的本地副本中进行更新——但我对此并不满意,因为它感觉很笨拙。

为了进一步解释,这就是我在顶层所做的 UIViewController:

@IBOutlet weak var myLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    for v in self.view.subviews {
        if v .isKindOfClass(CanvasView) {
            let canvasView = v as CanvasView
            canvasView.setMyLabel(myLabel)
        }
    }
}

然后在我的 CanvasView.swift 文件中,我有:

private var myLabel: UILabel!

...

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    // do stuff ...
    setNeedsDisplay()
    myLabel.text = "etc.etc."
}

有没有更好的方法?

谢谢。
Ave

我会实施 delegate pattern。创建 canvas 时传递父级 viewcontroller,您可以在其中实现各种回调方法。

Here 您可以找到有关实现委托的各种方法的更详细说明。对于这个单一而简单的用例,其中一些可能有些矫枉过正。

示例:你有一个游戏实例(称为游戏),它定义了一个委托协议。该协议包含针对不同事件的几种方法。 (例如 -(void)gameDidFinish 等)

现在游戏实现了一个方法addDelegate,每个实例都会调用该方法,希望收到游戏某些事件的通知。所有这些将自己注册为代表的实例都实现了游戏协议中定义的全部或部分方法

如果触发了其中一个游戏事件,则游戏会检查其所有已注册委托是否已实现相应的方法并调用它。

重要提示:如前所述,协议可能有点矫枉过正,因为您只有一名代表。

如果您的 canvas 是一个单独的 viewController,您可以使用委托协议从 canvas 视图控制器访问您的基础视图控制器。 假设您有一个 BaseViewController 调用 canvasViewController.

在您的 canvasViewController.h 中添加以下内容:

@protocol CanvasDelegate <NSObject>
@required
//examples . add your methods to upgate labels here
    - (void) updateLabels: (NSString*) labelText1 and:(NSString*)labelText2;
@end

@interface canvasViewController : UIViewController
{
    id<CanvasDelegate> delegate;
}

@property (retain) id delegate;

@end

现在,只要您想更新标签(或要求 baseViewController 做某事),就可以从您的 canvasViewController.m 文件中执行此代码:

[[self delegate] updateLabels:string1 and:string2];

现在,要使您的基本视图控制器接受来自 canvas 的消息,BaseVC 必须 "adopt" CanvasDelegate 协议并实现所需的方法。 在 baseViewController.h 中添加以下内容:

@interface baseViewController : UIViewController <CanvasDelegate>

baseViewController.m中为pushing创建canvasViewController的对象时,添加以下命令:

canvasVC.delegate = self;

并且不要忘记像这样在 baseViewController.m 中实现所需的方法:

- (void) updateLabels: (NSString*) labelText1 and:(NSString*)labelText2
{
    //update your labels here
}