【问题标题】:Programmatically creating Views in IOS (how does it work)?以编程方式在 IOS 中创建视图(它是如何工作的)?
【发布时间】:2011-06-16 17:54:47
【问题描述】:

一点背景知识:我正在浏览 CS193P iTune 视频,并且我被困在作业 3 上的时间最长。基本上,作业要求您以编程方式创建自定义视图以在屏幕上显示形状。顺便说一句,我没有使用任何视图控制器。

直到我最终在 Interface Builder 中拖动一个 View 对象并将对象名称更改为我的自定义视图类之前,我无法显示我的视图。所以我的问题是当人们说以编程方式创建视图时,他们只是说手动创建类但是当你需要显示它时使用 IB?我不禁觉得我误会了什么?

编辑:让我更清楚。我的自定义视图已使用 0、0、200、150 的帧进行初始化,并且 drawRect 被覆盖以在其中绘制一个正方形。如果尝试将其添加到控制器中的主窗口,我的视图甚至不会显示:

    UIWindow* window = [UIApplication sharedApplication].keyWindow;
[window addSubview:polygonView];

但是,如果在 IB 中使用拖动视图并将类更改为我的视图类,它会显示得很好。

编辑:添加了一些代码。这是我的控制器的 awakeFromNib 方法,应该在其中绘制视图。

    - (void)awakeFromNib {
    shape = [[PolygonShape alloc] initWithNumberOfSides:numberOfSidesLable.text.integerValue minimumNumberOfSides:3 maximumNumberOfSides:12];
    polygonView = [[PolygonView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    polygonView.backgroundColor = [UIColor blackColor];
    [window addSubview:polygonView];
    [self updateInterface];  
}

我的控制器的 updateInterface 方法的一部分:

- (void)updateInterface {
    [polygonView setPolygon:shape];
    [polygonView setNeedsDisplay];
...
}

PolygonView.h

#import <UIKit/UIKit.h>
#import "PolygonShape.h"

@interface PolygonView : UIView {
    IBOutlet PolygonShape *polygon; 
}

@property (readwrite, assign) PolygonShape *polygon;

- (void)drawRect:(CGRect)rect;
@end

PolygonView.m

#import "PolygonView.h"

@implementation PolygonView
@synthesize polygon;

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        nslog(@"initialized");
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
       CGRect bounds = [self bounds];

    [[UIColor grayColor] set];
    UIRectFill(bounds);

    CGRect square = CGRectMake(10, 10, 10, 100);
    [[UIColor blackColor] set];
    UIRectFill(square);

    [[UIColor redColor] set];
    UIRectFill(square);
    NSLog(@"drawRect called");
}
@end

polygonView 正在初始化,但 drawRect 没有被调用。

【问题讨论】:

  • keyWindow 是在哪里创建的?如果您没有加载 nib 文件(从您的问题中不清楚您是否加载),那么您必须先创建窗口,然后再添加子视图。
  • 它是在 AppDelegate 类中创建的。这是否意味着我必须在那里 #import 我的 polygonView 类并在那里创建它?
  • 有趣的是,如果我将初始化并将视图添加到我的 updateInterface 方法中的窗口,它会起作用,但只有在我单击调用该方法的按钮之后。代码似乎不是 awakeFromNib 中的进程。有什么想法吗?
  • 学过课程的人可以分享他们的控制器代码吗?此作业不适用于实际课程;我只是想自己学习 Obj-C。在这一点上,我了解了大部分情况,但显然我在这里遗漏了一些东西。
  • 共识表明我在代码中的内容是正确的,尽管似乎没有人能够告诉我为什么从我的控制器的 awakeFromNib 方法调用时没有绘制视图。我会考虑解决这个问题,因为无论如何我都会学习视图控制器。

标签: iphone objective-c ios views


【解决方案1】:

为了更具体地解决您的问题,语法为

UIWindow* window = [UIApplication sharedApplication].keyWindow;

UIView *polygonView = [[UIView alloc] initWithFrame: CGRectMake ( 0, 0, 200, 150)];
//add code to customize, e.g. polygonView.backgroundColor = [UIColor blackColor];

[window addSubview:polygonView];
[polygonView release];

这是一种模式,您不仅将用于此,而且随后将用于子视图。此外,另一个注意事项是许多模板,viewController 已经设置了它自己的视图。当你想创建一个自定义视图时,你可以像上面一样创建它,但不是上面的方法,而是将 viewControllers 视图设置为新创建的视图,如下所示:

viewController.view = polygonView;

祝你好运!

【讨论】:

  • 那我一定是做错了什么。我有你写的完全一样的,我的视图没有显示。
  • 嗯……如果你注释掉 drawRect 或者在 initWithFrame 中用 [self drawRect] 专门调用它会发生什么?
  • 如果我不覆盖drawRect,没有什么不同。如果我从 initWithFrame 方法调用 drawRect,我会收到一个异常错误:“原因:'-[PolygonView drawRect]: unrecognized selector sent to instance 0x4b58c70'”
【解决方案2】:

这是一个老问题,但我不确定他是否得到了他所期望的答案 - 听起来他遇到了与我在创建 UIViewController 子类时遇到的相同问题,在界面中敲击了 UIViewController builder nib,但后来不知道如何让两者相互协作。

如果你单独制作了 nib(所以它不是在你的班级旁边为你制作的),那么你必须记住单击放置在界面构建器中的 UIViewController,然后从属性面板中单击第三个选项卡按钮 ( '自定义类')。 Class 将是默认基类 UIViewController 等 - 只需打开此下拉列表,您将看到所有自定义子类的列表,选择它并打开 - 您已将自定义元素链接到界面。

希望这可以节省我花时间弄清楚的时间,我找到了一些愚蠢的奇妙方法来解决它,直到我意识到简单的解决方案。

【讨论】:

    【解决方案3】:

    您需要有一个视图(或窗口)才能添加子视图。正常的语法是这样的:

    UIView *newView = [[UIView alloc] initWithFrame:mainView.bounds];
    [mainView addSubview:newView];
    [newView release];
    

    当然,如果你有一个继承自 UIView 的自定义对象,你会使用它而不是 UIView。当您开始一个新项目时,创建一个“基于视图的应用程序”,它将从一个具有关联视图的视图控制器开始(可以使用“CustomViewController.view”访问,它将替换代码 sn 中的“mainView” -p 以上)。

    如果您想在应用启动时以编程方式创建视图,请将代码放在视图控制器的“- (void)viewDidLoad”方法中。

    【讨论】:

    • 我知道视图控制器是可行的方法,但在这个特定的任务中,只有一个模型类、一个控制器类和自定义视图类。你是说我必须将我的视图对象添加到主窗口吗?我将如何以及在哪里这样做?
    【解决方案4】:

    您好,只需添加此代码,

    [window bringSubviewToFront:polygonView];
    
    right after,
     [window addSubview:polygonView];
    

    【讨论】:

      【解决方案5】:

      在您的活动控制器类中的某处,您可以将自定义视图添加到当前顶级视图。

      [ myCurrentTopView addSubview: myNewCustomView ];
      

      这有助于首先分配和初始化这个自定义视图。

      然后,您可以通过执行以下操作在此自定义视图的 drawRect 中触发一些绘图:

      [ myNewCustomView setNeedsDisplay ];
      

      【讨论】:

      • 我当前的顶视图是主窗口。主窗口不是我的控制器类中的对象,那么我如何将我的视图设置为子视图([window addSubView:...] 不起作用)。
      【解决方案6】:

      您是否将视图的背景颜色设置为可区分的颜色?

      您确定您的视图没有显示,还是只是您看不到它?将 NSLog 放入视图的 drawRect: 方法中(如果您使用自定义视图类)。

      【讨论】:

      • 是的,我尝试将初始背景颜色设置为黑色,以查看是否可以看到白色或灰色视图显示,但没有。我还在 drawRect 和 iniWithFrame 中放置了一条 NSLog 消息,该消息也没有显示在控制台中。我认为我的视图没有被初始化,即使我有 polygonView = [polygonView initWithFrame:CGRectMake(0, 10, 320, 480)];在我的控制器的 awakeFromNib 方法中。
      • 我收回关于视图未初始化的观点。它是并且 iniWithFrame 中的 NSLog 消息正在显示。只是 drawRect 中的 NSLog 消息没有显示出来。我可以看到我的模型中的数据正在正确地传递给我的视图。我只是想不通为什么窗口不会显示我的视图。
      • 也许再多写一点代码可以帮助我们分析当时的情况。
      【解决方案7】:

      我最近遇到了一个非常相似的问题,这对我有用: 似乎从 Xcode 4.3.2 中的“空应用程序”开始时,您必须使用 setRootViewController 方法而不是 addSubview 将视图设置为主窗口的根视图。所以:

      // Initialize myView and then
      [window setRootViewController:myView];
      // instead of [window addSubview:myView];
      // the rest as normal...
      [window makeKeyAndVisible];
      

      之后,您可以使用 addSubview 方法添加其他视图。

      【讨论】:

        【解决方案8】:

        打电话

        [super drawRect];
        

        在 drawRect:body 中的自定义代码之前。

        【讨论】:

          猜你喜欢
          • 2013-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多