UIView和UIViewController继承练习

发布于 2024-07-29 06:19:29 字数 1616 浏览 4 评论 0原文

我只是想知道这种方法对于具有大量自定义视图的应用程序、对于可能会根据用户交互而变化的嵌套 PNG 图形和动画来说是否是一个很好的做法。 我创建了一个扩展 UIView 的 BaseView 类

@interface BaseView : UIView {
    @protected
    BaseViewController *controller;
}

@property (retain) BaseViewController *controller;

@end

和一个相应的控制器类,这是我放置代码来操作视图的主要位置,

@interface BaseViewController : UIViewController {
    @protected
    CGRect drawArea;
}

- (void) drawArea:(CGRect) _drawArea;
- (CGRect) drawArea;
- (void) linkSubviewController: (BaseViewController *) _subviewController;

@end

其中“drawArea”是用于作为框架传递到视图的 CGRect。

“linkSubviewController”允许您嵌套控制器和视图,如下所示:

- (void) linkSubviewController: (BaseViewController *) _subviewController {
    [self.view addSubview:[_subviewController view]];
}

此外,我还分层了另一个名为“ImageView”和“ImageViewController”的自定义对,它们扩展了 BaseView,但还存储了 UIImage 和 x,y,w,h

在“drawRect”中“ 在视图上绘制方法 我可以检查 self.controller 变量中的任何变量是否已更改,或者分配图像,例如:

UIImage *image = [(ImageViewController *)self.controller image];
CGContextDrawImage( ... ) etc

我编写了大多数 loadView 方法,如下所示

- (void)loadView {  
    ImageView *v = [[ImageView new] initWithFrame:drawArea];
    v.controller = self;
    self.view = v;
} 

基本“initWithFrame”例程包含

    self.backgroundColor = [UIColor clearColor];
    self.opaque = NO;

所以我可以加载具有透明背景的各种图像,而不必每次都进行分配。

我已经能够在我的应用程序中使用此代码,并且它似乎可以轻松编写组装自定义项目布局的顶级类。 对于动画,我将它们放入控制器中并操作 self.view.layer。

基本上我正在寻找反馈,我是 Objective-C 和 iPhone SDK 的新手

I was just wondering if this approach looks like a good practice for apps with a lot of custom views, for nested PNG graphics and animations that may change based on user interaction. I created a BaseView class that extends UIView

@interface BaseView : UIView {
    @protected
    BaseViewController *controller;
}

@property (retain) BaseViewController *controller;

@end

and a corresponding controller class which is the primary location which I am putting code to manipulate the view

@interface BaseViewController : UIViewController {
    @protected
    CGRect drawArea;
}

- (void) drawArea:(CGRect) _drawArea;
- (CGRect) drawArea;
- (void) linkSubviewController: (BaseViewController *) _subviewController;

@end

where "drawArea" is the CGRect used to pass to the view as a frame.

"linkSubviewController" allows you to nest a controller and view as follows :

- (void) linkSubviewController: (BaseViewController *) _subviewController {
    [self.view addSubview:[_subviewController view]];
}

In addition I layered another custom pair called "ImageView" and "ImageViewController" which extend BaseView but also store a UIImage and an x,y,w,h

In the "drawRect" drawing methods on views I can check to see if any vars in the self.controller vars have been changed, or assign images, for example :

UIImage *image = [(ImageViewController *)self.controller image];
CGContextDrawImage( ... ) etc

I write most of the loadView methods something like this

- (void)loadView {  
    ImageView *v = [[ImageView new] initWithFrame:drawArea];
    v.controller = self;
    self.view = v;
} 

The base "initWithFrame" routine contains

    self.backgroundColor = [UIColor clearColor];
    self.opaque = NO;

So I can load a variety of images with transparent backgrounds without having to assign that each time.

I've been able to use this code throughout my app and it seems to make it easy to write a top level class which assembles the layout of custom items. For animations I've been putting them in the controllers and manipulating self.view.layer.

Basically I am looking for feedback, I am new with Objective-C and the IPhone SDK

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清君侧 2024-08-05 06:19:29

这里有几个问题:

  1. 使用 [[Classname new] init...]new 的错误用法。 使用 new[[Classname alloc] init] 的缩写,因此您实际上调用了 init 两次。
  2. 视图实际上并不需要知道谁在控制它们。
  3. 您的视图正在保留控制器,并且由于 UIViewController 保留其视图,因此您有一个保留周期,并且两者都不会完全释放

如果您想要这种类型的行为(视图可以将其绘图委托给父级),请尝试创建一个 DrawDelegate 协议,让您的控制器实现该协议,并在您的视图子类中拥有一个非保留的drawDelegate 属性:

@protocol DrawDelegate
- (void) drawArea:(CGRect)rect;
@end

@interface BaseView : UIView {
    id<DrawDelegate> drawDelegate;
}
@property (assign) id<DrawDelegate> drawDelegate;
@end

There are several issues here:

  1. Using [[Classname new] init...] is incorrect usage of new. Using new is short for [[Classname alloc] init] so you are effectively calling init twice.
  2. Views shouldn't really need to know who is controlling them.
  3. Your view is retaining the controller, and since UIViewController retains its view, you have a retain cycle and neither will ever be fully released.

If you want this type of behavior (whereby a view can delegate its drawing to a parent), try creating a DrawDelegate protocol, have your controllers implement that protocol, and in your view subclass have a non-retaining drawDelegate property:

@protocol DrawDelegate
- (void) drawArea:(CGRect)rect;
@end

@interface BaseView : UIView {
    id<DrawDelegate> drawDelegate;
}
@property (assign) id<DrawDelegate> drawDelegate;
@end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文